[CONNECT C++] Copy context resizes the elements x10

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);
}

Parents
  • Does your variable modelP point to the active DGN model or to the DWG attachment?

    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...

    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. 

    You're doing unnecessary work by reallocating the ElementCopyContext on each pass through your for loop...

    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);

  • exportDwg(modelP); // the copy is done here

    Are you converting DWGDGN or DGNDWG?

    modelP is from the DWG attachment

    Then I would expect method exportDwg() to be named importDwg().

     
    Regards, Jon Summers
    LA Solutions

Reply Children
  • It's a DWGDGN 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. 

  • 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

  • It's a DWGDGN 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.

    Architectural or Engineering Units

    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.

    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.

     
    Regards, Jon Summers
    LA Solutions