几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量

几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量 (http://www.dimcax.com/hust/index.php)
-   DirectDWG (http://www.dimcax.com/hust/forumdisplay.php?f=89)
-   -   【转帖】getting modelspace object pointer for write 9programming te (http://www.dimcax.com/hust/showthread.php?t=16413)

yang686526 2009-05-05 11:30 AM

【转帖】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.