高级会员
注册日期: 06-11
帖子: 14579
精华: 1
现金: 224494 标准币
资产: 234494 标准币
|
【转帖】coping entities
coping entities
coping entities
hi,
i would like to copy all entities from on database into another. i wrote this code, bu it doesn't seem to work.
can someone tell me what is wrong?
thanks in advance,
vinicius
[code]
void copyentities(oddbdatabase* psource, oddbdatabase* ptarget)
{
oddbblocktablerecordptr pmssource = psource->getmodelspaceid().safeopenobject(oddb::kforrea d);
oddbblocktablerecordptr pmstarget = ptarget->getmodelspaceid().safeopenobject(oddb::kforwri te);
// get an iterator for the table
oddbsymboltableiteratorptr piter = pmssource->newiterator();
// for each block in the table
for (piter->start(); ! piter->done(); piter->step())
{
// open the block
oddbblocktablerecordptr pblock = piter->getrecordid().safeopenobject();
// get an entity iterator
oddbobjectiteratorptr pentiter = pblock->newiterator();
// for each entity in the table
for (; !pentiter->done(); pentiter->step())
{
// open the entity
oddbobjectid id = pentiter->objectid();
oddbentityptr pent = id.safeopenobject();
pmstarget->appendoddbentity(pent);
}
}
}
</pre><hr></blockquote>
your code is trying to append entities residing in one database to a block in other database.
only non-database resident entities can be appended to block.
other problem is that entities in source database are referencing layers, linetypes etc. from the source database so they can't be added to target database even after removing them from the source one.
these problem is solved in core code. you can simply call one of oddbdatabase::insert() functions. if you need to copy model space of one database to model space of another one use
oddbdatabase::insert(odgematrix3d&, oddbdatabase*, bool);
sergey slezkin
ok, i can use insert the get the whole entities, but what really want to do is to extract the entities of one layer from a database into another database.
the code i put here is just a small approach of the whole program. before running this code, i get the layer and linetypes loaded into the new database.
any other sugestion?
vinicius
layer and linetypes are not the only references between database objects. what to do with a polyline and associative hatch referencing each other? or leader and annotation associated with it? entity's extension dictionary?
while copying entities to another database all references between entities, references to table records and objects should be translated. and referenced elements should be cloned to destination database too.
oddbdatabase::insert() and wblock() functions take care about it.
the easiest solution is to erase all entities from the source database except ones you want to copy and use insert() function.
if it does not work for you, copy required entities to a temporary database using wblock() and call insert() to add them into the destination database.
one problem: wblock() was not implemented in 1.07, it will be available only in next release :-(
sergey slezkin
the layer i want to copy is supposed to keep only simple entities i mean arc, circle and line. if for same reason another entity than these 3 were found, i could skip it.
any way, i'll check the insert().
thanks,
vinicius
i tryed the code below to erase the entities i don磘 want and than save the database into a new file. the problem is that the erase is not working. if i comment the line with pent->erase(), it works and the file is saved, but if i erase the entities, no file is created. can you tell me what's missing?
thanks,
vinicius
[code]
// create a database and load the drawing into it.
oddbdatabaseptr pdb;
pdb = svcs.readfile( szsource, false, false, oda::ksharedenyno );
beginwaitcursor();
if (!pdb.isnull())
{
oddbblocktablerecordptr pblktable = pdb->getmodelspaceid().safeopenobject(oddb::kforwri te);
// get an entity iterator
oddbobjectiteratorptr pentiter = pblktable->newiterator();
odstring entlayer;
odstring curlayer = szlayer;
curlayer.makeupper();
// for each entity
for (; !pentiter->done(); pentiter->step())
{
// open the entity
oddbobjectid id = pentiter->objectid();
oddbentityptr pent = id.safeopenobject(oddb::kforwrite);
if (!pent.isnull())
{
entlayer = pent->layer();
entlayer.makeupper();
if ( entlayer.compare(curlayer) != 0 ) {
pent->erase();
}
}
}
odwrfilebuf fb(sztarget);
pdb->writefile(&fb, oddb::kdxf, oddb::vac14);
}
endwaitcursor();
</pre><hr></blockquote>
does it happen with any file or with some special one? can you reproduce the problem in odamfcapp? entities can be erased selecting them in tree control and pressing "delete" button.
if the problem occurs with some special file could you send me a sample?
sergey slezkin
does it happen with any file or with some special one?
it happens with any file.
can you reproduce the problem in odamfcapp?
no i can't. in odamfcapp the entities can be erased.
i'll send you the file i am working on.
thanks,
vinicius
by the way, what is your e-mail address?
vinicius
probably your application does not have undo filer.
object iterator can't perform step if current entity is erased and undo filer is absent.
we'll change iterator implementation to avoid this problem. for now you can call piter->step() before pent->erase():
while (!pentiter->done())
{// open the entity
oddbobjectid id = pentiter->objectid();
pentiter->step();
oddbentityptr pent = id.safeopenobject(oddb::kforwrite);
if (!pent.isnull())
{
...
if ( entlayer.compare(curlayer) != 0 )
{
pent->erase();
}
}
sergey slezkin
thanks a lot. now it's working fine.
vinicius
in my opinion,this problem should do as follows:
1.create a empty database pdbtmp
2.use source dadabase's "wblock" member filer out all objects that you want to copy to pdbtmp
3.use target database's "insert" member insert pdbtmp into target database.
this method is more simple for block,so in my program many entity set is block!
the way you suggested is the correct one for sure. the same thing is recommended to handle such situations in objectarx help. the only problem is that in dd 1.07 wblock() is not implemented. it will be available only in next release :-(
sergey slezkin
|