Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Typical Deep Clone Operations

Deep Clone from a Single Owner
Deep Clone from Multiple Owners
Wblock Clone
Insert

Deep Clone from a Single Owner

void _EXDC_DEEPCLONE_func(OdEdCommandContext* pCmdCtx)
{
  OdDbCommandContextPtr pDbCmdCtx(pCmdCtx);
  OdDbDatabasePtr pDb = pDbCmdCtx->database();
  OdDbUserIO* pIO = pDbCmdCtx->dbUserIO();

  // Select entities to clone
  OdDbObjectIdArray entIds = selectEntities(pIO);
  if (!entIds.size())
    return;

  // Select owner record for cloned entities
  OdString recName = pIO->getString(OD_T("Enter name of Block to clone entities <\"*ModelSpace\">:"), OdEd::kGstNoEmpty, OD_T("*ModelSpace"));
  OdDbObjectId destRecId = OdDbBlockTablePtr(pDb->getBlockTableId().safeOpenObject())->getAt(recName);
  if (destRecId.isErased())
  {
    destRecId = pDb->getModelSpaceId();
  }

  // Clone
  OdDbIdMappingPtr pMapping = OdDbIdMapping::createObject();
  pMapping->setDestDb(pDb);
  pDb->deepCloneObjects(entIds, destRecId, *pMapping);
}

Deep Clone from Multiple Owners

void _EXDC_DEEPCLONE_MULTIOWNERS_func(OdEdCommandContext* pCmdCtx)
{
  OdDbCommandContextPtr pDbCmdCtx(pCmdCtx);
  OdDbDatabasePtr pDb = pDbCmdCtx->database();
  OdDbUserIO* pIO = pDbCmdCtx->dbUserIO();

  // Select entities to clone and assign appropriate destination blocks
  std::map clonedEnts;
  OdDbSelectionSetIteratorPtr it = pIO->select(L"Select entities",OdEd::kSelAllowInactSpaces)->newIterator();
  while (!it->done())
  {
    OdDbEntityPtr pEnt = OdDbEntity::cast(it->objectId().openObject());
    if (pEnt.get())
    {
      if (OdDbBlockTableRecord::cast(pEnt->ownerId().openObject()).get())
      {
        clonedEnts[pEnt->ownerId()].push_back(pEnt->objectId());
      }
      else
      {
        pIO->putString(L"1 selected entity is not owned by block - skipped");
      }
    }
    else
    {
      pIO->putString(L"1 selected object is not an entity - skipped");
    }
    it->next();
  }

  size_t mapSize = clonedEnts.size();
  if (!mapSize)
  {
    pIO->putString(L"Nothing selected");
    return;
  }

  // Clone
  OdDbIdMappingPtr pMapping = OdDbIdMapping::createObject();
  pMapping->setDestDb(pDb);
  std::map::iterator mapIt = clonedEnts.begin();
  for ( ; mapIt != clonedEnts.end(); ++mapIt )
  {
    pDb->deepCloneObjects(mapIt->second, mapIt->first, *pMapping, (--mapSize != 0));
  }
}

Wblock Clone

void _EXDC_WBLOCK_func(OdEdCommandContext* pCmdCtx)
{
  OdDbCommandContextPtr pDbCmdCtx(pCmdCtx);
  OdDbDatabasePtr pDb = pDbCmdCtx->database();
  OdDbUserIO* pIO = pDbCmdCtx->dbUserIO();

  OdUInt32 nKeyword = pIO->getKeyword(
      OD_T("Enter WBLOCK type [Database/Block/Entities] :")
    , OD_T("Database Block Entities")
    , 0
    );
  OdDbDatabasePtr pDestDb;
  switch (nKeyword)
  {
  case 0: //Database
    {
      pDestDb = pDb->wblock();
    }
    break;
  case 1: //Block
    {
      OdDbSelectionSetIteratorPtr it = pIO->select(L"Select a block",OdEd::kSelAllowInactSpaces|OdEd::kSelAllowObjects)->newIterator();
      if (!it->done())
      {
        if (!OdDbBlockTableRecord::cast(it->objectId().openObject()).isNull())
        {
          pDestDb = pDb->wblock(it->objectId());
        }
      }
    }
    break;
  case 2: //Entities
    {
      OdDbObjectIdArray entIds = selectEntities(pIO);
      if (entIds.size())
      {
        OdGePoint3d pt = OdGePoint3d::kOrigin;
        pIO->getPoint(OD_T("Enter base point :"), 0, &pt);
        pDestDb = pDb->wblock(entIds, pt);
      }
    }
    break;
  }

  // Write database
  saveClonedDatabase(pIO, pDestDb);
}

Insert

void _EXDC_INSERT_func(OdEdCommandContext* pCmdCtx)
{
  OdDbCommandContextPtr pDbCmdCtx(pCmdCtx);
  OdDbDatabasePtr pDb = pDbCmdCtx->database();
  OdDbUserIO* pIO = pDbCmdCtx->dbUserIO();

  OdString fname = pIO->getFilePath(OD_T("Enter file name to insert:")
    , OdEd::kGfpForOpen
    , OD_T("Select drawing to insert")
    , OD_T("dwg")
    , OdString::kEmpty
    , OD_T("TD drawing (*.dwg)|*.dwg||")
    );
  OdDbDatabasePtr pSrcDb = pDb->appServices()->readFile(fname);
  if (pSrcDb.get())
  {
    bool bPreserveSrcDb = (0 == pIO->getKeyword(OD_T("Preserve source database [Yes/No] :"), OD_T("Yes No"), 0 ));
    OdString dstRecName = pIO->getString(OD_T("Enter name of destination block <\"\">:"));
    if (!dstRecName.isEmpty())
    {
      OdString srcRecName = pIO->getString(OD_T("Enter name of source block <\"\">:"));
      if (!srcRecName.isEmpty())
      {
        pDb->insert(srcRecName, dstRecName, pSrcDb, bPreserveSrcDb);
      }
      else
      {
        pDb->insert(dstRecName, pSrcDb, bPreserveSrcDb);
      }
    }
    else
    {
      double scaleX = pIO->getReal(L"Specify X scale factor<1.0>", OdEd::kInpDefault, 1.0);
      double scaleY = pIO->getReal(L"Specify Y scale factor<1.0>", OdEd::kInpDefault, 1.0);
      double scaleZ = pIO->getReal(L"Specify Z scale factor<1.0>", OdEd::kInpDefault, 1.0);
      pDb->insert(OdGeScale3d(scaleX, scaleY, scaleZ), pSrcDb, bPreserveSrcDb);
      //pDb->insert(OdGeMatrix3d::kIdentity, pSrcDb, bPreserveSrcDb);
    }
  }
}

See Also

Deep Clone Basics

Advanced Deep Clone Topics

Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.