/////////////////////////////////////////////////////////////////////////////// // 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 "ExIfcModelFiller.h" #include "IfcEntity.h" using namespace OdIfc; OdIfc::OdIfcInstancePtr ExIfcModelFiller::getRelContainedInSpatialStructure(OdIfc::OdIfcInstancePtr pRelating) { std::map::iterator it = m_relContainedInSpatialStructure.find(pRelating); if (it == m_relContainedInSpatialStructure.end()) return OdIfcInstancePtr(); return it->second; } OdIfc::OdIfcInstancePtr ExIfcModelFiller::addRelNests(OdIfc::OdIfcInstancePtr pRelating, const OdDAIObjectIds &related) { if (pRelating.isNull()) { ODA_ASSERT("Relating object is NULL."); return OdIfc::OdIfcInstancePtr(); } if (related.isEmpty()) { ODA_ASSERT("Related objects is missing."); return OdIfc::OdIfcInstancePtr(); } if (pRelating->isKindOf(kIfcObjectDefinition) == false) { ODA_ASSERT("Relating isn't a kind of IfcObjectDefinition."); return OdIfc::OdIfcInstancePtr(); } OdIfc::OdIfcInstancePtr pNests = m_model->createEntityInstance("ifcrelnests"); OdIfc::Utils::assignGlobalId(pNests); pNests->putAttr("relatingobject", OdDAIObjectId(pRelating->id())); pNests->putAttr("relatedobjects", related); m_model->appendEntityInstance(pNests); return pNests; } OdIfc::OdIfcInstancePtr ExIfcModelFiller::addRelNests(OdIfc::OdIfcInstancePtr pRelating, OdIfc::OdIfcInstancePtr pRelated) { if (pRelating.isNull()) { ODA_ASSERT("Relating object is NULL."); return OdIfc::OdIfcInstancePtr(); } if (pRelated.isNull()) { ODA_ASSERT("Related objects is missing."); return OdIfc::OdIfcInstancePtr(); } if (pRelating->isKindOf(kIfcObjectDefinition) == false) { ODA_ASSERT("Relating isn't a kind of IfcObjectDefinition."); return OdIfc::OdIfcInstancePtr(); } OdIfc::OdIfcInstancePtr pRelNests = m_model->createEntityInstance("ifcrelnests"); OdIfc::Utils::assignGlobalId(pRelNests); pRelNests->putAttr("relatingobject", OdDAIObjectId(pRelating->id())); m_model->appendEntityInstance(pRelNests); if (pRelated->id() == OdDAIObjectId::kNull) m_model->appendEntityInstance(pRelated); OdDAIObjectIds relatedObjects; relatedObjects.push_back(pRelated->id()); pRelNests->putAttr("relatedobjects", relatedObjects); m_relNests[pRelating] = pRelNests; return pRelNests; } OdIfc::OdIfcInstancePtr ExIfcModelFiller::appendRelNests(OdIfc::OdIfcInstancePtr pRelating, OdIfc::OdIfcInstancePtr pRelated) { if (pRelating.isNull()) { ODA_ASSERT("Relating object is NULL."); return OdIfc::OdIfcInstancePtr(); } if (pRelated.isNull()) { ODA_ASSERT("Related object is NULL."); return OdIfc::OdIfcInstancePtr(); } if (pRelated->isKindOf(kIfcObjectDefinition) == false) { ODA_ASSERT("EntityInstance isn't a kind of IfcObjectDefinition."); return OdIfc::OdIfcInstancePtr(); } OdIfcInstancePtr pRelNests = getRelNests(pRelating); if (pRelNests.isNull()) return addRelNests(pRelating, pRelated); if (pRelated->id() == OdDAIObjectId::kNull) m_model->appendEntityInstance(pRelated); OdDAI::Aggr *idsRelated; if (pRelNests->getAttr(kRelatedObjects) >> idsRelated) { if (idsRelated->type() == OdRxValueType::Desc::value()) { if (idsRelated->aggrType() == OdDAI::aggrTypeList) { if (idsRelated->isNil()) idsRelated->createEmpty(); OdDAI::ListOfOdDAIObjectId *list = reinterpret_cast(idsRelated); list->addByIndex(list->getMemberCount(), OdDAIObjectId(pRelated->id())); } else { ODA_ASSERT_ONCE(0 && "Unsupported aggr type."); } } } return pRelNests; } OdIfc::OdIfcInstancePtr ExIfcModelFiller::getRelNests(OdIfcInstancePtr pRelating) { auto it = m_relNests.find(pRelating); if (it == m_relNests.end()) return OdIfcInstancePtr(); return it->second; } OdIfc::OdIfcInstancePtr ExIfcModelFiller::appendRelContainedInSpatialStructure(OdIfcInstancePtr pRelating, OdIfcInstancePtr pRelated) { if (pRelating.isNull()) { ODA_ASSERT("Related object is NULL."); return OdIfcInstancePtr(); } if (pRelated.isNull()) { ODA_ASSERT("Related object is NULL."); return OdIfcInstancePtr(); } if (pRelating->isKindOf(kIfcSpatialElement) == false) { ODA_ASSERT("Relating isn't a kind of kIfcSpatialElement."); return OdIfcInstancePtr(); } if (pRelated->isKindOf(kIfcProduct) == false) { ODA_ASSERT("Related isn't a kind of IfcProduct."); return OdIfcInstancePtr(); } OdIfcInstancePtr pRelContainedInSpatialStructure = getRelContainedInSpatialStructure(pRelating);// getRelAggregates(pRelating); if (pRelContainedInSpatialStructure.isNull()) return addRelContainedInSpatialStructure(pRelating, pRelated); if (!pRelated->id()) m_model->appendEntityInstance(pRelated); OdDAIObjectIds idsRelated; if (pRelContainedInSpatialStructure->getAttr(kRelatedElements) >> idsRelated) { idsRelated.append(OdDAIObjectId(pRelated->id())); pRelContainedInSpatialStructure->putAttr(kRelatedElements, idsRelated); } return pRelContainedInSpatialStructure; } OdDAI::ApplicationInstancePtr ExIfcModelFiller::createRooted(const char *typeName, const char *name, bool append) { OdDAI::EntityPtr entity = m_model->underlyingSchema()->find(typeName); if (entity.isNull()) { ODA_ASSERT_ONCE("Can not find a type."); return{}; } if (!entity->instantiable()) { ODA_ASSERT_ONCE("Non-instantiable type."); return{}; } if (!Entity.IfcRoot->isSupertypeOf(entity)) { ODA_ASSERT_ONCE("Not a rooted type."); return{}; } OdDAI::ApplicationInstancePtr rooted = m_model->createEntityInstance(typeName); if (rooted.isNull()) return rooted; if (append) m_model->appendEntityInstance(rooted); OdIfc::Utils::assignGlobalId(OdIfc::OdIfcInstance::cast(rooted)); if (!m_ownerHistory.isNull()) rooted->putAttr("ownerhistory", OdDAIObjectId(m_ownerHistory->id())); if (name) rooted->putAttr("name", name); return rooted; } IfcRepresentationBuilderPtr ExIfcModelFiller::createRepresentationBuilder(OdIfc::OdIfcInstancePtr pInst) { if (pInst.isNull()) { return{}; } if (!pInst->isKindOf(Entity.IfcProduct)) { return{}; } IfcRepresentationBuilderPtr res = IfcRepresentationBuilder::createObject(this, pInst); return res; } IfcBridgeBuilderPtr ExIfcModelFiller::appendBridge(const OdAnsiString &name, IfcBridgeBuilder::Type type) { if (Entity.IfcBridge == nullptr) { ODA_ASSERT("IfcBridge isn't supported by model schema."); return{}; } if (m_project.isNull() || m_site.isNull()) { ODA_ASSERT("Not enough topology to create Bridge builder."); return{}; } IfcBridgeBuilderPtr res = IfcBridgeBuilder::createObject(this, name, type); res->appendIfcBridge(); return res; } IfcAlignmentBuilderPtr ExIfcModelFiller::appendAlignment(const OdAnsiString &name) { if (Entity.IfcAlignment == nullptr) { ODA_ASSERT("IfcAlignment isn't supported by model schema."); return{}; } if (m_project.isNull() || m_site.isNull()) { ODA_ASSERT("Not enough topology to create Bridge builder."); return{}; } IfcAlignmentBuilderPtr res = IfcAlignmentBuilder::createObject(this, name); res->appendIfcAlignment(); return res; } IfcRailwayBuilderPtr ExIfcModelFiller::appendRailway(const OdAnsiString &name) { if (Entity.IfcRailway == nullptr) { ODA_ASSERT("IfcRailway isn't supported by model schema."); return{}; } if (m_project.isNull() || m_site.isNull()) { ODA_ASSERT("Not enough topology to create Bridge builder."); return{}; } IfcRailwayBuilderPtr res = IfcRailwayBuilder::createObject(this, name); res->appendIfcRailway(); return res; } OdIfc::OdIfcInstancePtr ExIfcModelFiller::createShapeRepresentation(const OdAnsiString &contextType, const OdAnsiString &identifier, const OdAnsiString &type) { OdIfc::OdIfcInstancePtr grc = getGeometricRepresentationContext(contextType); if (grc.isNull()) { ODA_ASSERT("Not convenient graphic representation context found."); return{}; } OdIfc::OdIfcInstancePtr pSR = m_model->createEntityInstance("ifcshaperepresentation"); pSR->putAttr(OdIfc::kContextOfItems, OdDAIObjectId(grc->id())); pSR->putAttr(OdIfc::kRepresentationIdentifier, identifier); pSR->putAttr(OdIfc::kRepresentationType, type); return pSR; } OdIfc::OdIfcInstancePtr ExIfcModelFiller::createAlignmentSegment(OdDAIObjectId nestedSegmentId) { if (nestedSegmentId.isNull()) { ODA_ASSERT("Nested segment id is missing."); return{}; } OdIfcInstancePtr pSeg = m_model->createEntityInstance("ifcalignmentsegment"); OdIfc::Utils::assignGlobalId(pSeg); pSeg->putAttr("ownerhistory", OdDAIObjectId(ownerHistory()->id())); pSeg->putAttr("designparameters", nestedSegmentId); m_model->appendEntityInstance(pSeg); return pSeg; }