/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// /************************************************************************/ /* ExDcCloneCommands.cpp: Defines example of deep cloning commands */ /************************************************************************/ #include "OdaCommon.h" #include "Ed/EdUserIO.h" #include "Ed/EdCommandStack.h" #include "DbCommandContext.h" #include "DbSSet.h" #include "DbDatabase.h" #include "ExDcCmdDefs.h" #include "DbBlockTable.h" #include "DbBlockTableRecord.h" #include "DbEntity.h" #include "DbDictionary.h" #include "DbIdMapping.h" #include "StaticRxObject.h" #include "Reactors/DbgEventReactor.h" #include "Reactors/DbgDatabaseReactor.h" #include "Reactors/DbgObjectReactor.h" #include "Reactors/DbgReactorOut.h" #include "ExDeepCloningAux.h" #define STL_USING_MAP #include "OdaSTL.h" void saveClonedDatabase(OdDbUserIO* pIO, OdDbDatabase* pDestDb) { if (!pDestDb) return; OdStreamBufPtr pFile = ::odSystemServices()->createFile( pIO->getFilePath( OD_T("Enter file name:"), OdEd::kGfpForSave, OD_T("Save cloned database as"), OD_T("dwg")), Oda::kFileWrite, Oda::kShareDenyReadWrite, Oda::kCreateAlways); pDestDb->writeFile(pFile, OdDb::kDwg, OdDb::kDHL_CURRENT); } /************************************************************************/ /* Deep cloning commands. */ /************************************************************************/ 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 <\"*Model_Space\">:"), OdEd::kGstNoEmpty, OD_T("*Model_Space")); 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); } 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)); } } void _EXDC_DEEPCLONE_REACTORS_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(); } // Set RxEvent reactor OdStaticRxObject > editorReactor; editorReactor.init(pIO); odedEditor()->addReactor(&editorReactor); // Set database reactor OdStaticRxObject > dbReactor; dbReactor.init(pIO); pDb->addReactor(&dbReactor); // Set transient reactor OdStaticRxObject > objReactor; objReactor.init(pIO); unsigned i = 0; for (; i < entIds.size(); ++i) { entIds[i].safeOpenObject()->addReactor(&objReactor); } // Clone OdDbIdMappingPtr pMapping = OdDbIdMapping::createObject(); pMapping->setDestDb(pDb); pDb->deepCloneObjects(entIds, destRecId, *pMapping); //try //{ // _EXDC_DEEPCLONE_func(pCmdCtx); //} //catch (...) //{ // odedEditor()->removeReactor(&editorReactor); // throw; //} // Remove reactors odedEditor()->removeReactor(&editorReactor); pDb->removeReactor(&dbReactor); for (i = 0; i < entIds.size(); ++i) { entIds[i].safeOpenObject()->removeReactor(&objReactor); } } void _EXDC_WBLOCKCLONE_func(OdEdCommandContext* pCmdCtx) { OdDbCommandContextPtr pDbCmdCtx(pCmdCtx); OdDbUserIO* pIO = pDbCmdCtx->dbUserIO(); OdDbDatabasePtr pDestDb = wblockCloneFunc(pCmdCtx); if (pDestDb.isNull()) { return; } saveClonedDatabase(pIO, pDestDb); } void _EXDC_WBLOCKCLONE_BLOCKS_func(OdEdCommandContext* pCmdCtx) { OdDbCommandContextPtr pDbCmdCtx(pCmdCtx); OdDbUserIO* pIO = pDbCmdCtx->dbUserIO(); OdDbDatabasePtr pDestDb = wblockBlocksFunc(pCmdCtx); if (pDestDb.isNull()) { return; } saveClonedDatabase(pIO, pDestDb); } void _EXDC_WBLOCK_func(OdEdCommandContext* pCmdCtx) { OdDbCommandContextPtr pDbCmdCtx(pCmdCtx); OdDbUserIO* pIO = pDbCmdCtx->dbUserIO(); saveClonedDatabase(pIO, wblockFunc(pCmdCtx)); } void _EXDC_INSERT_func(OdEdCommandContext* pCmdCtx) { insertFunc(pCmdCtx); }