/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2018, 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 Teigha(R) software pursuant to a license // agreement with Open Design Alliance. // Teigha(R) Copyright (C) 2002-2018 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #ifndef DbAssocNetworkDeepCloneAux_INCLUDED_ #define DbAssocNetworkDeepCloneAux_INCLUDED_ /*!DOM*/ #include "TD_PackPush.h" #define STL_USING_MAP #define STL_USING_SET #include "OdaSTL.h" #include "DbIdMapping.h" #include "DbObjectId.h" #include "OdLinkedArray.h" #include "DbObjectIterator.h" #include "DbObjectReactor.h" #include "OdHashSet.h" #include "OdHashMap.h" #include "OdPlatformSettings.h" #include "DbBlockTableRecord.h" class OdDbAssocAction; class OdDbAssocNetwork; class OdDbAssocDependency; class OdDbAssocVariable; typedef OdLinkedArray OdDbObjectIdLinkedArray; typedef std::map OdString2IdMap; typedef std::map OdString2OdStringMap; //DOM-IGNORE-BEGIN template struct OdHashSet_PtrHasher : OdUnorderedSet_DefaultHasher { // dna: todo: move to OdHashSet.h enum { bucket_size = 4, min_buckets = 8 }; size_t operator()(const T* key) const { return OdUnorderedSet_DefaultHasher::operator()((OdIntPtr)key); } }; class OdDbAssocVarCloneCtx { public: struct DataEntry { OdString m_srcName; OdString m_dstName; bool m_isCloned; }; OdDbAssocVarCloneCtx() {} void addDestVariables(OdDbAssocNetwork* network); void addSourceVariables(OdDbAssocVariable* variable); bool addSourceVariable(const OdString& name); bool addDestVariable(const OdString& name); void recordVariableClone(const OdString& srcName, const OdString& dstName); const DataEntry* getEntryBySourceName(const OdString& srcName) const; const DataEntry* getEntryByDestName(const OdString& dstName) const; int destVariableCount() const; int clonedVariableCount() const; private: typedef OdArray Data; typedef std::map OdString2IdxMap; Data m_data; OdString2IdxMap m_forwardIndex; OdString2IdxMap m_invertedIndex; }; //DOM-IGNORE-END typedef OdHashSet > OdDbStubPtrHashSet; /** \details This class implements the context object for assoc networks deep clone operations. Library: Source code provided. */ class OdDbAssocNetCloneCtx : public OdDbObjectReactor { protected: typedef OdHashMap > NetworkVariableIndex; OdDbIdMappingPtr idMap; OdDbStubPtrHashSet dependentOnObjectsCloned; OdDbStubPtrHashSet actionsToClone; OdDbStubPtrHashSet actionsToAppend; OdDbObjectIdLinkedArray actionsCloned; NetworkVariableIndex variableIndices; OdDbObjectId explodingBlockReferenceId; mutable OdGeMatrix3d actionXform; mutable bool bApplyTransform; OdDbAssocNetCloneCtx() { bApplyTransform = false; } public: ODRX_DECLARE_MEMBERS(OdDbAssocNetCloneCtx); /** \details Registries the deep clone reactor. */ static void createAssocNetworkCloneReactors(); /** \details Unregisters the deep clone reactor. */ static void deleteAssocNetworkCloneReactors(); /** \details Attaches new context data associating it with given OdDbDatabase */ static void attach(OdDbIdMapping& idMap); /** \details Gets internal data associated with given database */ static OdSmartPtr fromDatabase(OdDbDatabase* destDb); /** \details Detaches this context data associated with given database */ static bool detach(OdDbDatabase* destDb); /** \details Gets IdMapping associated with current clone operation */ OdDbIdMapping& idMapping(); OdDbObjectIdLinkedArray& clonedActions(); OdDbAssocVarCloneCtx& varCloneContext(OdDbAssocNetwork* destNetwork); void onBlockCloned(const OdDbBlockTableRecord& originalBlock); void onDependentObjectCloned(const OdDbObject& originalObject); /** \details Remembers an action from source database that was cloned. */ void onActionCloned(const OdDbAssocAction* action); virtual void setActionTransform(const OdGeMatrix3d& transform); bool doApplyTransform() const { return bApplyTransform; } const OdGeMatrix3d& actionTransform() const; /** Description Calls addMoreObjectToDeepClone() for actions whose dependent-on objects were cloned . */ void addMoreObjectsToDeepClone(); /** Description Relinks dependency lists on cloned DB-objects that is be broken by deep clone operation when not all actions depended on a object were cloned. */ void relinkDependenciesOnObjects(); /** Description Appends cloned actions to its owners. */ void appendActionsToOwners(); /** Description Calls one of OdDbObject's methods on 'original', either deepClone() or wblockClone() depending on destination dabase value. if it's equal to original then deepClone() is callen and if it's not then calls wblockClone(). */ static bool cloneObject(OdDbIdMapping& idMap, const OdDbObject* original, OdDbObject* destOwner, OdDbObjectPtr* pClone = 0); static void lookupDestinationBlock(OdDbIdMapping& idMap, OdDbAssocAction* action, OdDbBlockTableRecordPtr& destBlock); static OdDbObjectPtr lookupActionCloneOwner(OdDbIdMapping& idMap, OdDbEntity* destActionEntity); static OdDbObjectPtr lookupActionCloneOwner(OdDbIdMapping& idMap, OdDbBlockTableRecord* destBlock); static OdDbObjectPtr lookupActionCloneOwner(OdDbIdMapping& idMap, OdDbAssocAction* action); }; typedef OdSmartPtr OdDbAssocNetCloneCtxPtr; inline OdDbIdMapping& OdDbAssocNetCloneCtx::idMapping() { return *idMap; } inline OdDbObjectIdLinkedArray& OdDbAssocNetCloneCtx::clonedActions() { return actionsCloned; } inline OdDbAssocNetCloneCtxPtr OdDbAssocNetCloneCtx::fromDatabase(OdDbDatabase* destDb) { const OdDbObjectReactorArray reactors = destDb->getTransientReactors(); OdDbObjectReactorArray::const_iterator it = reactors.begin(), end = reactors.end(); OdRxClass* ctxRxClass = ::odrxGetClassDesc("OdDbAssocNetCloneCtx"); for ( ; it < end; ++it) { if ((*it)->isKindOf(ctxRxClass)) { return (OdDbAssocNetCloneCtx*)it->get(); } } return (OdDbAssocNetCloneCtx*)0; } inline const OdGeMatrix3d& OdDbAssocNetCloneCtx::actionTransform() const { return actionXform; } inline void OdDbAssocNetCloneCtx::setActionTransform(const OdGeMatrix3d& xform) { actionXform = xform; bApplyTransform = !xform.isEqualTo(OdGeMatrix3d::kIdentity, OdGeTol(OdGeContext::gZeroTol)); } inline OdDbObjectId oddbTranslate(OdDbObjectId id, OdDbIdMapping &idMap) { OdDbIdPair idPair(id); if(idMap.compute(idPair)) return idPair.value(); return OdDbObjectId::kNull; } inline OdDbObjectId oddbTranslateCloned(OdDbObjectId id, OdDbIdMapping &idMap) { OdDbIdPair idPair(id); if (idMap.compute(idPair) && idPair.isCloned()) return idPair.value(); return OdDbObjectId::kNull; } #include "TD_PackPop.h" #endif