![]() |
【转帖】getting modelspace object pointer for write 9programming te
getting modelspace object pointer for write (programming tec
getting modelspace object pointer for write (programming technique) question... i am looping a database to add new objects into it... is it better to constantly get the modelspace id, open for write, add entity or is it better to open modelspace id for write just once and pass that around. so, lots of get modelspace/open for write or just the one? any performance issues against these methods? andrew yes, closing the model space once is definitely better than closing it many times. but also beware to start a transactiom while adding the entities. pdb->starttransaction(); // add the entities here pdb->endtransaction(); transactions help to minimize the number of undo writes in the memory. however, if you have disabled undo/redo, then there is no need to call the transaction mechanism. regards chudomir i have never played with this in dwgdirect. is the undo feature on by default? i don't need undo on since all i am doing is creating a drawing file. how do i switch this undo off then...? andrew code: // this pointer must be cleared after each drawing is craeted oddbdatabaseptr pdb; // loop selected files inumfiles = m_lbseqfiles.getcount(); for( ifile = 0; ifile < inumfiles; ifile++ ) { m_lbseqfiles.gettext( ifile, strfile ); fileseq.open( strfile, cfile::moderead|cfile::typetext ); // clear old drawing first (if any) if( !pdb.isnull() ) pdb.release(); createdrawing( pdb ); // get modelspace id idmodelspace = pdb->getmodelspaceid(); // get model space block (from it's id) oddbblocktablerecordptr pmodelspaceblock; // open block for adding objects pmodelspaceblock = idmodelspace.safeopenobject( oddb::kforwrite ); while( fileseq.readstring( strtext ) ) { // trim leading whitespace strtext.trimleft(); // break off first word strword = strtext.spanexcluding( _t(" ") ); // are we starting a new entity? if we are, we // must add the existing entity into the autocad // file before we start getting data for this new entity. if( strword == _t("symbol") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_symbol ); } else if( strword == _t("line") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_line ); } else if( strword == _t("region") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_region ); } // now parse the text entity.parsesequentialtext( strtext ); } // we must create the last entity object after loop terminates entity.createautocaddata( pmodelspaceblock ); pmodelspaceblock.release(); fileseq.close(); // we must pass in the right file name to save the drawing as.. setdrawingtoextents( pdb ); savedrawing( pdb ); } } i have changed the code to do the block in the loop and pass it in. i beleive i must manually release the modelspace block. if i don't do that, i get an empty drawing... i think you should call disableundorecording() of the oddbdatabase object. then you'll need no transactions. as to you code - the model space and the database are smart pointers, so just declare them in the local scope and they will be automatically cleared and deleted. and aslo make the createdrawing() function not to have an output argument, but to return a database pointer. here is a shorter version - beware that the model space smart pointer should be defined after the definition of the database pointer. so that the database pointer will have its destructor called after the model space one... code: // loop selected files inumfiles = m_lbseqfiles.getcount(); for( ifile = 0; ifile < inumfiles; ifile++ ) { m_lbseqfiles.gettext( ifile, strfile ); fileseq.open( strfile, cfile::moderead|cfile::typetext ); oddbdatabaseptr pdb = createdrawing(); pdb->disableundorecording(); oddbblocktablerecordptr pmodelspaceblock = pdb->getmodelspaceid()->safeopenobject( oddb::kforwrite ); while( fileseq.readstring( strtext ) ) { // trim leading whitespace strtext.trimleft(); // break off first word strword = strtext.spanexcluding( _t(" ") ); // are we starting a new entity? if we are, we // must add the existing entity into the autocad // file before we start getting data for this new entity. if( strword == _t("symbol") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_symbol ); } else if( strword == _t("line") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_line ); } else if( strword == _t("region") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_region ); } // now parse the text entity.parsesequentialtext( strtext ); } // we must create the last entity object after loop terminates entity.createautocaddata( pmodelspaceblock ); fileseq.close(); // we must pass in the right file name to save the drawing as.. setdrawingtoextents( pdb ); savedrawing( pdb ); } } best regards chudomir quote: originally posted by chudo and aslo make the createdrawing() function not to have an output argument, but to return a database pointer. here is the createdrawing method: void cseq2dwgdlg::createdrawing(oddbdatabaseptr &rpdb) { assert( rpdb.isnull() ); if( rpdb.isnull() ) { rpdb = theapp.createdatabase( true, oddb::kmetric ); rpdb->newregapp( registered_app ); } } please alter for me. i need to ensure i do it and learn correctly. i appreciate your help with this. andrew no probs. oddbdatabaseptr cseq2dwgdlg::createdrawing() { oddbdatabaseptr pdb = theapp.createdatabase(true, oddb::kmetric); pdb->newregapp(registered_app); // also you can add additional initializations here... return pdb; } } hope this helps. please let me know if you have any problems. regards chudomir best regards chudomir quote: originally posted by chudo no probs. oddbdatabaseptr cseq2dwgdlg::createdrawing() { oddbdatabaseptr pdb = theapp.createdatabase(true, oddb::kmetric); pdb->newregapp(registered_app); // also you can add additional initializations here... return pdb; } } hope this helps. please let me know if you have any problems. regards chudomir thanks. i had to change: oddbblocktablerecordptr pmodelspaceblock = pdb->getmodelspaceid()->safeopenobject( oddb::kforwrite ); to oddbblocktablerecordptr pmodelspaceblock = pdb->getmodelspaceid().safeopenobject( oddb::kforwrite ); for it to compile. yes, sorry, that was my fault. regards chudomir best regards chudomir when i run it, i get a 18kb drawing instead of a 2 mb.. i have a gut feeling that pointer objects inside for loops are created once for the for loop cycle, not each iteration.. if i do this at the bottom of the for loop (inside it): code: pmodelspaceblock.release(); // we must pass in the right file name to save the drawing as.. setdrawingtoextents( pdb ); savedrawing( pdb ); pdb.release(); it creates a 2mb drawing... i see - so can you try this: code: // loop selected files inumfiles = m_lbseqfiles.getcount(); for( ifile = 0; ifile < inumfiles; ifile++ ) { m_lbseqfiles.gettext( ifile, strfile ); fileseq.open( strfile, cfile::moderead|cfile::typetext ); oddbdatabaseptr pdb = createdrawing(); pdb->disableundorecording(); { oddbblocktablerecordptr pmodelspaceblock = pdb->getmodelspaceid()->safeopenobject( oddb::kforwrite ); while( fileseq.readstring( strtext ) ) { // trim leading whitespace strtext.trimleft(); // break off first word strword = strtext.spanexcluding( _t(" ") ); // are we starting a new entity? if we are, we // must add the existing entity into the autocad // file before we start getting data for this new entity. if( strword == _t("symbol") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_symbol ); } else if( strword == _t("line") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_line ); } else if( strword == _t("region") ) { // starting a symbol entity entity.createautocaddata( pmodelspaceblock ); entity.setentitytype( seq_type_region ); } // now parse the text entity.parsesequentialtext( strtext ); } // we must create the last entity object after loop terminates entity.createautocaddata( pmodelspaceblock ); fileseq.close(); // we must pass in the right file name to save the drawing as.. } setdrawingtoextents( pdb ); savedrawing( pdb ); } } note the {} block which defines a local scope for the model space only; however, your solution is good and working. but at least try with this scope. regards chudomir best regards chudomir should not the brace be just before the database pointer allocation? instead of after? we have two pointers here, db and modelspace no - you should have only the model space pointer embraced. pdb scope; { model space scope; } the closing bracket } will force the model space smart pointer to close the model space block and to store the entities into the database. regards chudomir best regards chudomir |
所有的时间均为北京时间。 现在的时间是 06:47 AM. |