Hello,
I'm trying to use the ElementCopyContext class in order to copy each element from an attached DWG file. Later I'd like to import only some of the elements.
The problem is the final result, it is ten time bigger than the attached file. I tried to use SetTransformToDestination(true) in order to fix this, but it's not better.
Any idea? Thanks by advance!
for (PersistentElementRefP const& elemRef : modelP->GetElementsCollection()) { DgnPlatform::EditElementHandle* elmhandle = new DgnPlatform::EditElementHandle(elemRef->GetElementId(), modelP); DgnPlatform::ElementCopyContext copyContext(ACTIVEMODEL); copyContext.SetSourceModelRef(elmhandle->GetModelRef()); copyContext.SetTransformToDestination(true); copyContext.SetWriteElements(true); copyContext.DoCopy(*elmhandle); }
Does your variable modelP point to the active DGN model or to the DWG attachment?
modelP
Topaz said:DgnPlatform::EditElementHandle* elmhandle = new DgnPlatform::EditElementHandle(elemRef->GetElementId(), modelP);
DgnPlatform::EditElementHandle* elmhandle = new DgnPlatform::EditElementHandle(elemRef->GetElementId(), modelP);
You've created a memory leak with new EditElementHandle. Just declare and construct an EditElementHandle on the stack...
new EditElementHandle
EditElementHandle
DgnPlatform::EditElementHandle elmhandle (elemRef->GetElementId(), modelP);
An ElementHandle (and its sub-class EditElementHandle) is a smart pointer to an element descriptor. It's destructor handles memory deallocation for you.
ElementHandle
You're doing unnecessary work by reallocating the ElementCopyContext on each pass through your for loop...
ElementCopyContext
for
DgnPlatform::ElementCopyContext copyContext(ACTIVEMODEL); copyContext.SetSourceModelRef(modelP); copyContext.SetTransformToDestination(true); copyContext.SetWriteElements(true); for (PersistentElementRefP const& elemRef : modelP->GetElementsCollection()) { DgnPlatform::EditElementHandle elmhandle (elemRef->GetElementId(), modelP); copyContext.DoCopy (elmhandle); }
Regards, Jon Summers LA Solutions
Hello Jon, thank you for your answer.Thank you for your advices, indeed my code was full of memory leak and useless reallocations. I reduced the problem to the smallest code possible and forgot to post a clean code. However I didn't know eeh was a smart pointer.
Here is how I get the modelP, it is from the DWG attachment:
DgnAttachmentArrayP pAttachArray = ISessionMgr::GetActiveDgnModelP()->GetDgnAttachmentsP(); for (DgnAttachmentP pAttach : *pAttachArray) { auto modelsCollection = pAttach->GetDgnFileP()->GetLoadedModelsCollection(); for (auto modelIt = modelsCollection.begin(); modelIt != modelsCollection.end(); ++modelIt) { if ((*modelIt)->IsDefault() == true) { Bentley::DgnModelP modelP = *modelIt; exportDwg(modelP); // the copy is done here } } } Cmd_ZoomVariable(L"#GLOBALEVO"); closeDwgsInReferences(_fileNames);
Topaz said:exportDwg(modelP); // the copy is done here
exportDwg(modelP); // the copy is done here
Are you converting DWG→DGN or DGN→DWG?
Topaz said:modelP is from the DWG attachment
Then I would expect method exportDwg() to be named importDwg().
exportDwg()
importDwg()
It's a DWG→DGN conversion. My goal is to import some of the DWG elements and copy them into a DGN file, that's why I'm using the ElementCopyContext class, but maybe there is other (and better?) ways.
Topaz said:but maybe there is other (and better?) ways.
No, to use CopyContext is the only right way how to manipulate with elements across "model borders".
Regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Topaz said:It's a DWG→DGN conversion
I'm no expert on DWG import, but you could search for that topic on the MicroStation Forum. Here is a comment from MicroStation Help about importing DWG.
Defines the linear units for MicroStation to use when opening DWG files with Architectural and Engineering Units (LUNITS=3 or 4). For DWG files with these units, the linear units are inches and are displayed as feet and inches. You should keep this option set to (MicroStation) inches unless you know that the AutoCAD unit conventions were ignored when the file was created.
MicroStation's system for controlling units is very flexible, but it depends on knowing the true geometry size. In AutoCAD, the true size of geometry in a DWG file is more ambiguous. You must set the Units options correctly to remove this ambiguity and enable MicroStation to correctly determine the true size of the DWG geometry. To set the units properly, you must understand the DWG file content and the standards used to create it.
Generally, when you set units to an explicit unit value (for example, to Inches or Meters), these units become the master units when the DWG file is opened. The next smallest units on the units list become the sub units. For example, if Feet are the master units, Inches are the sub units.
However, if the units you select are either the master or sub units of the DGN seed file, both the master and sub units from the seed file are retained. If you want to use the sub units of the seed file as the master units for the file that you are opening, you must change the units in the seed file.
Topaz said:I'm using the ElementCopyContext class, but maybe there is other (and better?) ways
You have chosen the best way! I think the problem lies with the indetermine units used in AutoCAD and MicroStation Units. You need to work out how to scale your conversion.