/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// #include "OdaCommon.h" #include "SmartCenterObserve.h" void attachSmartCenterReactor() { ::odedRegCmds()->addReactor(OdSmartCenterEditorReactor::getSmartCenterEditorReactor()); } void detachSmartCenterReactor() { OdSmartCenterEditorReactor* pReactor = OdSmartCenterEditorReactor::getSmartCenterEditorReactor(); if (!pReactor) return; ::odedRegCmds()->removeReactor(pReactor); pReactor->clearObservers(); } bool OdSmartCenterObserver::hasCommand(const OdString& commandName) const { for (auto comName : m_comNames) { if (comName.find(commandName) != -1) return true; } return false; } bool OdSmartCenterObserver::hasSmartCenterId(OdDbObjectId id) const { return m_smartCenterIds.contains(id); } void OdSmartCenterObserver::objectModified(const OdDbDatabase* pDb, const OdDbObject* pObject) { if (!pDb || !pObject || !pObject->isKindOf(OdDbEntity::desc())) return; categorizeObject(OdDbEntity::cast(pObject)); } void OdSmartCenterObserver::categorizeObject(const OdDbEntity* pEnt) { if (!m_actClass) return; OdDbBlockReference* pBlockRef = OdDbBlockReference::cast(pEnt); if (pBlockRef) { getOrInsertNewSmartCenter(pEnt->objectId()); } else { insertSmartCenterEdge(pEnt); } } SmartMapIt OdSmartCenterObserver::getOrInsertNewSmartCenter(OdDbObjectId smartCenterId) { OdDbBlockReferencePtr pBlRef = OdDbBlockReference::cast(smartCenterId.safeOpenObject()); if (pBlRef.isNull() || !m_actClass) return m_smartMap.end(); OdDbObjectId actBodyId = OdDbSmartCenterActionBody::getSmartCenterActionBody(pBlRef); if (actBodyId.isNull()) return m_smartMap.end(); auto mapIt = m_smartMap.find(smartCenterId); if (mapIt != m_smartMap.end()) return mapIt; OdDbSmartCenterActionBodyPtr pActBody = OdDbSmartCenterActionBody::cast(actBodyId.safeOpenObject()); if (pActBody.isNull() || !pActBody->isKindOf(m_actClass)) return m_smartMap.end(); auto it = m_smartMap.emplace(smartCenterId, OdDbObjectIdArray()); OdDbObjectIdArray dependencyIds; pActBody->getDependencies(true, true, dependencyIds); OdDbAssocDependencyPtr pDepArrayEntity; for (auto depId : dependencyIds) { OdDbAssocDependencyPtr pDep = OdDbAssocDependency::cast(depId.openObject()); if (pDep.isNull()) continue; OdDbObjectId depObjectId = pDep->dependentOnObject(); if (!depObjectId.isNull() && depObjectId != smartCenterId && !it.first->second.contains(depObjectId)) it.first->second.append(depObjectId); } return it.first; } void OdSmartCenterObserver::insertSmartCenterEdge(const OdDbEntity* pEnt) { OdDbObjectIdArray actionIds; OdDbAssocAction::getActionsDependentOnObject(pEnt, true, false, actionIds); for (auto actionId : actionIds) { OdDbAssocActionPtr pAction = actionId.safeOpenObject(); if (pAction.isNull()) continue; OdDbObjectId bodyId = pAction->actionBody(); if (bodyId.isNull()) continue; OdDbSmartCenterActionBodyPtr pActionBody = OdDbSmartCenterActionBody::cast(bodyId.safeOpenObject()); if (pActionBody.isNull() || !pActionBody->isKindOf(m_actClass)) continue; OdDbObjectId smartCenterId = pActionBody->centerObjectId(); if (smartCenterId.isNull()) continue; OdDbBlockReferencePtr bRef = OdDbBlockReference::cast(smartCenterId.safeOpenObject()); if (bRef.isNull()) continue; auto it = getOrInsertNewSmartCenter(smartCenterId); if (it == m_smartMap.end()) continue; it->second.remove(pEnt->objectId()); if (it->second.isEmpty()) m_smartCenterIds.append(smartCenterId); } } void OdSmartCenterObserver::clearData() { m_smartMap.clear(); m_smartCenterIds.clear(); } OdSmartCenterEditorReactor* OdSmartCenterEditorReactor::getSmartCenterEditorReactor() { static OdStaticRxObject g_smartCenterReactor; return &g_smartCenterReactor; } OdSmartCenterEditorReactor::OdSmartCenterEditorReactor() { m_observers.append( OdRxObjectImpl::createObject( OdArray{ OD_T("ROTATE") }, OdDbCenterLineActionBody::desc() ) ); } bool OdSmartCenterEditorReactor::observerHasSmartCenter(OdDbObjectId smartCenterId, OdRxClass* pClass) const { const OdSmartCenterObserver* pObs = findObserver(pClass); if (!pObs) return false; return pObs->hasSmartCenterId(smartCenterId); } const OdSmartCenterObserver* OdSmartCenterEditorReactor::findObserver(OdRxClass* pClass) const { if (!pClass) return nullptr; for (unsigned n = 0; n < m_observers.size(); n++) { if (m_observers[n]->getActClass() == pClass) return m_observers[n].get(); } return nullptr; } void OdSmartCenterEditorReactor::commandWillStart(OdEdCommand* pCommand, OdEdCommandContext* pCmdCtx) { OdDbDatabasePtr pDb = OdDbDatabase::cast(pCmdCtx->baseDatabase()); if (pDb.isNull()) return; OdString strGlobalName = pCommand->globalName(); strGlobalName.makeUpper(); for (unsigned n = 0; n < m_observers.size(); n++) { if (m_observers[n]->hasCommand(strGlobalName)) { pDb->removeReactor(m_observers[n].get()); pDb->addReactor(m_observers[n].get()); } } } void OdSmartCenterEditorReactor::commandEnded(OdEdCommand*, OdEdCommandContext* pCmdCtx) { removeObservers(OdDbDatabase::cast(pCmdCtx->baseDatabase())); } void OdSmartCenterEditorReactor::commandCancelled(OdEdCommand*, OdEdCommandContext* pCmdCtx) { removeObservers(OdDbDatabase::cast(pCmdCtx->baseDatabase())); } void OdSmartCenterEditorReactor::commandFailed(OdEdCommand*, OdEdCommandContext* pCmdCtx) { removeObservers(OdDbDatabase::cast(pCmdCtx->baseDatabase())); } void OdSmartCenterEditorReactor::removeObservers(OdDbDatabasePtr pDb) { if (pDb.isNull()) return; for (unsigned n = 0; n < m_observers.size(); n++) { pDb->removeReactor(m_observers[n].get()); m_observers[n]->clearData(); } } void OdSmartCenterEditorReactor::clearObservers() { m_observers.clear(); m_observers.setPhysicalLength(0); }