/////////////////////////////////////////////////////////////////////////////// // 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 "DbEntity.h" #include "DbPlaneSurface.h" #include "OdDbAssocAsmBasedPersSubentIdPE.h" #include "ModelerGeometry.h" #include "DbAssocEdgePersSubentId.h" #include "ShHistory/DbAssocPersSubentManager.h" #include "DbImpCenterLineActionBody.h" #include "DbImpCenterMarkActionBody.h" #include "Br/BrBrep.h" #include "Br/BrBrepFaceTraverser.h" #include "Br/BrBrepEdgeTraverser.h" #include "Br/BrBrepVertexTraverser.h" ODRX_NO_CONS_DEFINE_MEMBERS(OdDbAssocAsmBasedPersSubentIdPE, OdDbAssocPersSubentIdPE); inline bool isBrepEntity(const OdDbEntity* pEntity) { if (OdDb3dSolid* pSolid = OdDb3dSolid::cast(pEntity)) return true; if (OdDbRegion* pReg = OdDbRegion::cast(pEntity)) return true; if (OdDbBody* pBody = OdDbBody::cast(pEntity)) return true; if (OdDbSurface* pSrf = OdDbSurface::cast(pEntity)) return true; return false; } inline bool getBrep(const OdDbEntity* pEntity, OdBrBrep& br) { if (OdDb3dSolid* pSolid = OdDb3dSolid::cast(pEntity)) { pSolid->brep(br); return true; } if (OdDbRegion* pReg = OdDbRegion::cast(pEntity)) { pReg->brep(br); return true; } if (OdDbBody* pBody = OdDbBody::cast(pEntity)) { pBody->brep(br); return true; } if (OdDbSurface* pSrf = OdDbSurface::cast(pEntity)) { pSrf->brep(br); return true; } return false; } OdResult OdDbAssocAsmBasedPersSubentIdPE::getTransientSubentIds(const OdDbEntity* pEntity, const OdDbAssocPersSubentId* pPerSubentId, OdArray& subents) const { if (!::isBrepEntity(pEntity)) return eWrongObjectType; const OdDbAssocAsmBasedEntityPersSubentIdPtr pAsmPersSubentId = OdDbAssocAsmBasedEntityPersSubentId::cast(pPerSubentId); if (pAsmPersSubentId.isNull()) return eNotThatKindOfClass; OdDbDatabase* pDb = pEntity->database(); OdDbObjectId objId = OdDbAssocPersSubentManager::getInstanceFromDatabase(pDb); OdDbAssocPersSubentManagerPtr pAssocPSManager = objId.openObject(/*OdDb::kForWrite*/); if (pAssocPSManager.isNull()) return eNoInterface; return pAssocPSManager->getTransientSubentIds(pEntity, pAsmPersSubentId->subentId(pEntity), subents); } OdResult OdDbAssocAsmBasedPersSubentIdPE::getVertexSubentityGeometry(const OdDbEntity* pEntity, const OdDbSubentId& vertexSubentId, OdGePoint3d& vertex) { OdBrBrep brep; if (!::getBrep(pEntity, brep)) return eNoInterface; OdDbFullSubentPath subentPath(pEntity->objectId(), vertexSubentId); OdBrVertex brVertex; if (brVertex.setSubentPath(brep, subentPath) == odbrOK && !brVertex.isNull()) { vertex = brVertex.getPoint(); OdGeMatrix3d x; if (brep.getTransformation(x)) vertex.transformBy(x); return eOk; } return eDegenerateGeometry; } OdResult OdDbAssocAsmBasedPersSubentIdPE::getEdgeSubentityGeometry(const OdDbEntity* pEntity, const OdDbSubentId& edgeSubentId, OdGeCurve3d*& pEdgeCurve) { OdBrBrep brep; if (!::getBrep(pEntity, brep)) return eNoInterface; OdDbFullSubentPath subentPath(pEntity->objectId(), edgeSubentId); OdBrEdge brEdge; if (brEdge.setSubentPath(brep, subentPath) == odbrOK && !brEdge.isNull()) { pEdgeCurve = brEdge.getCurve(); if (pEdgeCurve) { OdGeMatrix3d x; if (brep.getTransformation(x)) pEdgeCurve->transformBy(x); } return eOk; } return eDegenerateGeometry; } OdResult OdDbAssocAsmBasedPersSubentIdPE::getFaceSubentityGeometry(const OdDbEntity* pEntity, const OdDbSubentId& faceSubentId, OdGeSurface*& pFaceSurface) { OdBrBrep brep; if (!::getBrep(pEntity, brep)) return eNoInterface; OdDbFullSubentPath subentPath(pEntity->objectId(), faceSubentId); OdBrFace brFace; if (brFace.setSubentPath(brep, subentPath) == odbrOK && !brFace.isNull()) { pFaceSurface = brFace.getSurface(); OdGeMatrix3d x; if (brep.getTransformation(x)) pFaceSurface->transformBy(x); return eOk; } return eDegenerateGeometry; } OdResult OdDbAssocAsmBasedPersSubentIdPE::getAllSubentities(const OdDbEntity* pEntity, OdDb::SubentType subentType, OdArray& allSubentIds) { OdBrBrep brep; if (!::getBrep(pEntity, brep)) return eNoInterface; int num = 0; if (subentType == OdDb::kFaceSubentType) { OdBrBrepFaceTraverser traverser; traverser.setBrep(brep); for (; !traverser.done(); traverser.next(), ++num) {} } else if (subentType == OdDb::kEdgeSubentType) { OdBrBrepEdgeTraverser traverser; traverser.setBrep(brep); for (; !traverser.done(); traverser.next(), ++num) {} } else if (subentType == OdDb::kVertexSubentType) { OdBrBrepVertexTraverser traverser; traverser.setBrep(brep); for (; !traverser.done(); traverser.next(), ++num) {} } else { return eWrongObjectType; } allSubentIds.reserve(num); for (int i = 1; i <= num; ++i) { allSubentIds.push_back(OdDbSubentId(subentType, OdGsMarker(i))); } return eOk; } OdDbAssocPersSubentIdPtr OdDbAssocAsmBasedPersSubentIdPE::createNewPersSubent(OdDbEntity* pEntity, const OdDbCompoundObjectId&, const OdDbSubentId& subentId) { OdDbDatabase* pDb = pEntity->database(); if (!pDb) return OdDbAssocPersSubentIdPtr(); OdDbObjectId objId = OdDbAssocPersSubentManager::getInstanceFromDatabase(pDb, true); OdDbAssocPersSubentManagerPtr pAssocPSManager = objId.openObject(OdDb::kForWrite); if (pAssocPSManager.isNull()) return OdDbAssocPersSubentIdPtr(); pAssocPSManager->insureBodyHasMandatoryPersSubentNamingData(pEntity); OdUInt32 persSubentId = pAssocPSManager->createNewPersSubent(pEntity, subentId); if (!persSubentId) return OdDbAssocPersSubentIdPtr(); OdDbAssocAsmBasedEntityPersSubentIdPtr res = OdDbAssocAsmBasedEntityPersSubentId::createObject(); res->init(OdDbSubentId(subentId.type(), persSubentId)); return res; } OdResult OdDbAssocAsmBasedPersSubentIdPE::getEdgeVertexSubentities(const OdDbEntity* pEntity, const OdDbSubentId& edgeSubentId, OdDbSubentId& startVertexSubentId, OdDbSubentId& endVertexSubentId, OdArray&/* otherVertexSubentIds*/) { OdBrBrep brep; if (!::getBrep(pEntity, brep)) return eNoInterface; OdDbFullSubentPath edgeSubentPath(pEntity->objectId(), edgeSubentId); OdBrEdge brEdge; if (brEdge.setSubentPath(brep, edgeSubentPath) != odbrOK || brEdge.isNull()) return eDegenerateGeometry; OdBrVertex v1, v2; brEdge.getVertex1(v1); brEdge.getVertex2(v2); OdDbSubentId id1, id2; if (v1.isNull() && v2.isNull()) return eDegenerateGeometry; OdDbBaseFullSubentPath startSubPath; if (!v1.isNull() && v1.getSubentPath(startSubPath) == odbrOK) startVertexSubentId = startSubPath.subentId(); OdDbBaseFullSubentPath endSubPath; if (!v2.isNull() && v2.getSubentPath(endSubPath) == odbrOK) endVertexSubentId = endSubPath.subentId(); return eOk; }