![]() |
【转帖】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 |
所有的时间均为北京时间。 现在的时间是 08:01 AM. |