高级会员
注册日期: 06-11
帖子: 14579
精华: 1
现金: 224494 标准币
资产: 234494 标准币
|
【转帖】import blocks
import blocks
import blocks
hi!
i'm trying to import blocks from one dwg draw to another one, after many and many gp faults i arrive at this code:
try
// try
{
if (!m_pdb.isnull())
{
myservices has;
cstring bf;
odgepoint3d orig;
//oddbblocktablerecordptr lc_pblock = oddbblocktablerecord::createobject();
oddbblocktablerecordptr lc_pblock;
oddbblocktableptr lc_pblocks = m_pdb->getblocktableid().safeopenobject(oddb::kforwrite) ;
oddbdatabaseptr bk_pdb = has.readfile(inpath);
if (!bk_pdb.isnull())
{
int count=0;
// open the blocks table
oddbblocktableptr pblocks = bk_pdb->getblocktableid().safeopenobject();
// get an iterator for the block table that skips deleted records
oddbsymboltableiteratorptr pblkiter = pblocks->newiterator();
// for each block in the block table
for (pblkiter->start(); ! pblkiter->done(); pblkiter->step(),count++)
{
// open the block
oddbblocktablerecordptr pblock = pblkiter->getrecordid().safeopenobject();
orig=pblock->origin();
//check if block is an xref
if (pblock->isdependent())
{
oddbobjectiteratorptr pentiter = pblock->newiterator();
for (; !pentiter->done(); pentiter->step())
{
// get the entity in a pointer
oddbentityptr pent = pentiter->objectid().safeopenobject();
//check if entity is a block reference
if (pent->iskindof(oddbblockreference::desc()))
{
//it is a block reference, so get a pointer to it
oddbblockreferenceptr pblockref = pentiter->entity();
//as well as a pointer to its parent
oddbblocktablerecordptr pparentblock = pblockref->blocktablerecord().safeopenobject();
if (pparentblock->pathname())
{
trace(_t("%s\t%s\norigine x=%f\ty=%f\tz=%f\n"),pblock->getname(), pparentblock->pathname(),orig.x,orig.y,orig.z);
*lc_pblock=*pparentblock;
lc_pblocks->add(lc_pblock);
}
}
}
}
else
{
oddbobjectid brefid = addblock(pblock->getname());
oddbblocktablerecordptr lc_pblock = brefid.safeopenobject(oddb::kforwrite);
trace(_t("blocco normale %s\norigine x=%f\ty=%f\tz=%f\n"),pblock->getname(),orig.x,orig.y,orig.z);
*lc_pblock=*pblock;
bf.format(_t("blocco%d"),count);
orig=lc_pblock->origin();
trace(_t("blocco nuovo %s\norigine x=%f\ty=%f\tz=%f\n"),lc_pblock->getname(),orig.x,orig.y,orig.z);
lc_pblock->setname(odstring((lpcstr)bf));
trace(_t("nuovo nome %s\n"),lc_pblock->getname());
}
}
bk_pdb.release(); // delete the database before odunitialize() is called.
lc_pblock.release();
lc_pblocks.release();
pblocks.release();
#ifdef _debug
dumpblocks();
#endif
//if (rd==true)
m_pdevice->update();
}
}
}
catch (oderror& err)
// catch(cexception,e)
{
trace(_t("error number [%d]-[%x]\n"), err.code());
}
// end_catch
catch (...)
{
trace(_t("generic error %d\n"), eok);
}
well it seems working well but unfotunately i'm not able to see the blocks on the draw! as you can see i dump the blocks after the work and into the db it seems that the blocks are in, but the draw seems unmodified...... i tryed many systems but nothing happens someone can help me please?
regards mrspock
see wblockcloneobjects and deepcloneobjects梩hey allow you to clone objects from 1 db to another (i think). i believe these may provide the functionality you are seeking.
thanks! i'll try
blocks cloning!!!!!!
well it may be i'm not a great programmer but i cannot understand() what i have to do! look the following code:
try
{
if (!m_pdb.isnull())
{
myservices has;
oddbidmappingptr pid = oddbidmapping::createobject();
oddbblocktablerecordptr lc_pblock;
oddbblocktableptr lc_pblocks = m_pdb->getblocktableid ().safeopenobject(oddb::kforwrite);
oddbdatabaseptr bk_pdb = has.readfile(inpath);
if (!bk_pdb.isnull())
{
// open the blocks table
oddbblocktableptr pblocks = bk_pdb->getblocktableid ().safeopenobject();
oddbobjectidarray listablk; //lista id
// get an iterator for the block table that skips deleted records
oddbsymboltableiteratorptr pblkiter = pblocks->newiterator();
// filling the idarray
for (pblkiter->start(); ! pblkiter->done(); pblkiter->step())
{
// append the block
listablk.append(pblkiter->getrecordid());
}
m_pdb->wblockcloneobjects(listablk,
m_pdb->getblocktableid(),
*pid,
oddb::kdrcmanglename);
bk_pdb.release();
lc_pblock.release();
lc_pblocks.release();
pblocks.release();
#ifdef _debug
dumpblocks();
#endif
//if (rd==true)
m_pdevice->update();
}
}
}
catch (oderror& err)
{
trace(_t("errore [%d]-[%x]\n"), err.code());
}
catch (...)
{
trace(_t("errore nella creazione del device di rendering %d\n"), eok);
}
i made the modifications for use the wblockcloneobjects but in first i have some problems for the paramiters :
[b]objectids [b] (i) object id's of the objects to be cloned. how i can obtain this, i can immagine that since there aren't any function that returns this idarray i have to build it..... (look the code)
[b] owner [b] (i/o) object id of owner object which will be given ownership of the clones. here, because i'm cloning the blocks, for me the owner is the id of the blocklist! isn't it?
[b] idmap [b] (o) id map that associates the object id's from the original objects with the object id's of the newly created clones. here i followed the slezkin's suggestions about the message posted by wolfgang hirner and i passed to the function the pointer after the asterisk (my compiler doesn't want directly the smart pointer!)
[b] drc [b] (i) action for duplicate records. here i putted one value because i haven't find in the "rich" documentation the meaning of any value.........
so after this the compiler was happy to compile my code, usually i prefer understand what i'm doing in the code... and why but thats it!
the only result is gp fault, and now i dont have any system to understand why!
why the try-catch doesn't traps the gp fault, and why or may be what parameter is wrong!!!!!!!
my boss want kill me because i'm loosing time without any kind of result!
where i can buy a documentation ? (manuals and so on?) if i need to use something that is not in the examples .........
help help help
i also spent many hours on this, but found an easy solution. maybe this sample code will help you:
void myclass::importblocksfromfile(odstring externalfilename)
{
// imports blocks from an external database into this database
// our block table in this database
oddbblocktableptr pbt = getblocktableid().safeopenobject();
oddbobjectid blockid;
// create a custom hostappservices object.
odrxobjectimpl<ccadhostappservices> svcs;
// load external database
oddbdatabaseptr pextdb;
pextdb = svcs.readfile(externalfilename, false, false);
trace1("external database: %08x\n", pextdb );
trace1("this database: %08x\n", database() );
// *** check ext db ok here ***
oddbblocktableptr pextbt = pextdb->getblocktableid().safeopenobject();
oddbsymboltableiteratorptr pextbti = pextbt->newiterator(true, true);
while( !pextbti->done() )
{
oddbblocktablerecordptr pextblock = pextbti->getrecord();
// add this external block to our block table if
// it isn't a layout block, an anonymous block, or an xref block
if( !pextblock->islayout() && !pextblock->isanonymous() && !pextblock->isfromexternalreference() )
{
odstring blockname = pextblock->getname();
if( pbt->has( blockname ) )
{
trace1("block %s already exists in the current database!\n", blockname);
}
else
{
trace1("adding block %s !!!\n", blockname );
// src_blk, dest_blk, src_db, preserve_existing
database()->insert(blockname, blockname, pextdb, true);
// note: database() gives a ptr to our current database
}
}
pextbti->step();
}
}
regards,
james
thanks!
hi!
many thanks for your contribute, it seems working well, this afternoon i tested the deepcloneobjects it works like your cod but unfortunately, i don't know why when i close the app it leaves a memory leak! it may be i made somthung strange. infact now i have the blocks in my database but i don't see them, i made a routine that write some lines and a polyline on a new block and after imports the blocks, at the end of the operations i see only the lines and the polyline but not the imported blocks! did you have the same problem in the past?
in any case thanks for your help
bye
gildo (mrspock)
i also have a memory leak. i'll have to look into it (tomorrow .
detected memory leaks!
dumping objects ->
{45} normal block at 0x003e2700, 33 bytes long.
data: < c > 00 43 00 cd cd cd cd cd cd cd cd cd cd cd cd cd
{44} normal block at 0x003e2698, 40 bytes long.
data: < |l > 14 7c 4c 10 16 00 00 00 00 00 00 00 00 00 00 00
object dump complete.
- james
deepcloneobjects() supports cloning only within single database.
the correct method to use for your task is
database()->insert(blockname, blockname, pextdb, true);
autocad objectarx help can be used to learn more about clone and wblock functionality. the concepts are the same.
2 memory leaks dumped (33 and 40 bytes long) have the following reason: the memory is freed in static objects' destructors which are called after dumping is invoked. don't worry, they are not from your code and not actually a leaks but a result of incorrect diagnostics.
sergey slezkin
|