/////////////////////////////////////////////////////////////////////////////// // 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 "OdAssocPowerTowerPersSubentIdPE.h" #include "COdPowerTowerEntity.h" #include "ShHistory/OdDbAssocPersSubentManagerPE.h" #include ODRX_NO_CONS_DEFINE_MEMBERS_ALTNAME(OdAssocPowerTowerPersSubentIdPE, OdDbAssocPersSubentIdPE, L"OdAssocPowerTowerPersSubentIdPE"); #define GEOM_OFFSET 1000 OdAssocPowerTowerPersSubentIdPE::OdAssocPowerTowerPersSubentIdPE() { } OdAssocPowerTowerPersSubentIdPE::~OdAssocPowerTowerPersSubentIdPE() { } OdDbAssocPersSubentIdPtr OdAssocPowerTowerPersSubentIdPE::createNewPersSubent(OdDbEntity* pEntity, const OdDbCompoundObjectId& compId, const OdDbSubentId& subentId) { const OdDb3dSolid* pSolid(nullptr); OdDbSubentId actualSubEntId; unsigned int nGeom(0); OdResult res = getActualSubEntIdAndGeom(pEntity, subentId, pSolid, actualSubEntId, nGeom); if (res != eOk) return OdDbAssocPersSubentIdPtr(); OdSmartPtr pPE = pSolid->isA()->getX(OdDbAssocPersSubentIdPE::desc()); if (pPE.isNull()) return OdDbAssocPersSubentIdPtr(); //Getting PersSubentId for solid OdDbAssocPersSubentIdPtr persSubId = pPE->createNewPersSubent(const_cast(pSolid), compId, actualSubEntId); OdDbAssocAsmBasedEntityPersSubentId* pAsmPersSubId = OdDbAssocAsmBasedEntityPersSubentId::cast(persSubId); if (!pAsmPersSubId) return OdDbAssocPersSubentIdPtr(); //We add a negative value so that it does not overlap with the PersSubentId array, //which is stored in the PersSubentManager pAsmPersSubId->m_SubentId.setIndex(-1 * (pAsmPersSubId->m_SubentId.index() + nGeom * GEOM_OFFSET)); return persSubId; } OdResult OdAssocPowerTowerPersSubentIdPE::getTransientSubentIds(const OdDbEntity* pEntity, const OdDbAssocPersSubentId* pPerSubentId, OdArray& subents) const { OdDbAssocAsmBasedEntityPersSubentId* pAsmPersSubId = OdDbAssocAsmBasedEntityPersSubentId::cast(pPerSubentId); if (!pAsmPersSubId) return eInvalidInput; OdDbSubentId subentId = pAsmPersSubId->m_SubentId; const OdDb3dSolid* pSolid(nullptr); OdDbSubentId actualSubEntId; unsigned int nGeom(0); OdResult res = getActualSubEntIdAndGeom(pEntity, subentId, pSolid, actualSubEntId, nGeom); if (res != eOk) return res; pAsmPersSubId->m_SubentId = actualSubEntId; res = pAsmPersSubId->getTransientSubentIds(pSolid, subents); pAsmPersSubId->m_SubentId = subentId; if (res != eOk) return res; for (auto& subEnt : subents) subEnt.setIndex(subEnt.index() + nGeom * GEOM_OFFSET); return eOk; } OdResult OdAssocPowerTowerPersSubentIdPE::getAllSubentities(const OdDbEntity* pEntity, OdDb::SubentType subentType, OdArray& allSubentIds) { const COdPowerTowerEntity* pTower = COdPowerTowerEntity::cast(pEntity); if (!pTower) return eWrongObjectType; int nGeomMult = 0; for (auto geom : pTower->getGeom()) { OdSmartPtr pPE = geom->isA()->getX(OdDbAssocPersSubentIdPE::desc()); if (pPE.isNull()) continue; unsigned int nStart = allSubentIds.size(); OdArray curAllSubentIds; pPE->getAllSubentities(geom, subentType, allSubentIds); //We need to add GEOM_OFFSET to OdDbSubentId for separating solids for (unsigned int n = nStart; n < allSubentIds.size(); n++) allSubentIds[n].setIndex(allSubentIds[n].index() + nGeomMult * GEOM_OFFSET); nGeomMult++; } return eOk; } OdResult OdAssocPowerTowerPersSubentIdPE::getEdgeVertexSubentities(const OdDbEntity* pEntity, const OdDbSubentId& edgeSubentId, OdDbSubentId& startVertexSubentId, OdDbSubentId& endVertexSubentId, OdArray& otherVertexSubentIds) { const OdDb3dSolid* pSolid(nullptr); OdDbSubentId actualSubEntId; unsigned int nGeom(0); OdResult res = getActualSubEntIdAndGeom(pEntity, edgeSubentId, pSolid, actualSubEntId, nGeom); if (res != eOk) return res; OdSmartPtr pPE = pSolid->isA()->getX(OdDbAssocPersSubentIdPE::desc()); if (pPE.isNull()) return eBadProtocolExtension; pPE->getEdgeVertexSubentities(pSolid, actualSubEntId, startVertexSubentId, endVertexSubentId, otherVertexSubentIds); startVertexSubentId.setIndex(startVertexSubentId.index() + nGeom * GEOM_OFFSET); endVertexSubentId.setIndex(startVertexSubentId.index() + nGeom * GEOM_OFFSET); for (auto& subEnt : otherVertexSubentIds) subEnt.setIndex(subEnt.index() + nGeom * GEOM_OFFSET); return eOk; } OdResult OdAssocPowerTowerPersSubentIdPE::getVertexSubentityGeometry(const OdDbEntity* pEntity, const OdDbSubentId& subentId, OdGePoint3d& vertex) { const OdDb3dSolid* pSolid(nullptr); OdDbSubentId actualSubEntId; unsigned int nGeom(0); OdResult res = getActualSubEntIdAndGeom(pEntity, subentId, pSolid, actualSubEntId, nGeom); if (res != eOk) return res; OdSmartPtr pPE = pSolid->isA()->getX(OdDbAssocPersSubentIdPE::desc()); if (pPE.isNull()) return eBadProtocolExtension; pPE->getVertexSubentityGeometry(pSolid, actualSubEntId, vertex); const COdPowerTowerEntity* pTower = COdPowerTowerEntity::cast(pEntity); OdGeMatrix3d matr = OdGeMatrix3d::translation(pTower->getBasePnt() - OdGePoint3d::kOrigin); vertex.transformBy(matr); return eOk; } OdResult clonePersSubentNamingData(OdDbObject* pObj, OdDbAssocPersSubentManagerCloner* apsmc) { if (!pObj || !apsmc) return eInvalidInput; OdDbAssocPersSubentManagerPEPtr pPE = OdDbAssocPersSubentManagerPE::cast( pObj->queryX(OdDbAssocPersSubentManagerPE::desc()) ); if (pPE.isNull()) return eBadProtocolExtension; return pPE->clonePersSubentNamingData(pObj, apsmc); } void OdAssocPowerTowerPersSubentIdPE::clonePersSubentId( OdDbAssocGeomDependency* pGeomDep, OdDbObject* pTowerObj, OdDbAssocPersSubentManagerCloner* apsmc) { if (!pGeomDep || !pTowerObj) return; COdPowerTowerEntity* pTower = COdPowerTowerEntity::cast(pTowerObj); if (!pTower) return; OdDbAssocAsmBasedEntityPersSubentId* pAsmId = OdDbAssocAsmBasedEntityPersSubentId::cast(pGeomDep->persistentSubentId()); if (!pAsmId) return; OdDbSubentId subEntId = pAsmId->m_SubentId; unsigned int nGeom = static_cast(std::abs(subEntId.index())) / GEOM_OFFSET; if (pTower->geomCount() <= nGeom) return; OdDb3dSolid* pSolid = pTower->getSolid(nGeom); if (clonePersSubentNamingData(pSolid, apsmc) != eOk) return; pAsmId->m_SubentId = OdDbSubentId(subEntId.type(), std::abs(subEntId.index()) % GEOM_OFFSET); clonePersSubentNamingData(pGeomDep, apsmc); pAsmId->m_SubentId.setIndex(-1 * (pAsmId->m_SubentId.index() + nGeom * GEOM_OFFSET)); } OdResult OdAssocPowerTowerPersSubentIdPE::getActualSubEntIdAndGeom( const OdDbEntity* pEntity, const OdDbSubentId& subentId, const OdDb3dSolid*& pSolid, OdDbSubentId& actualSubentId, unsigned int& nGeom) const { const COdPowerTowerEntity* pTower = COdPowerTowerEntity::cast(pEntity); if (!pTower) return eWrongObjectType; nGeom = static_cast(std::abs(subentId.index())) / GEOM_OFFSET; if (pTower->geomCount() <= nGeom) return eInvalidInput; actualSubentId = OdDbSubentId(subentId.type(), std::abs(subentId.index()) % GEOM_OFFSET); pSolid = pTower->getGeom().at(nGeom); return eOk; }