diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h index d1e7da6..6e219bb 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h @@ -1,553 +1,564 @@ template int ifc_Tree::BuildTreeFromRoot(Type_Elmt_Of_Source *&pElem/*, STRUCT_IFCENTITY *&st_IfcTree*/, Type_Source * const& ifcXmlFile) { //lecture des Id et type de "IfcProject" Map_String_String m_messages; int iRes = ifcXmlFile->ReadIdAndTypeOfAnEntity(pElem, m_messages); //Recup du positionnement relatif Type_Elmt_Of_Source *lpObjectPlac = nullptr; ifcXmlFile->FindIfcGeometricRepresentationContext(pElem, lpObjectPlac); //Recup de la matrice de position double db_LocalMat[3][4]; ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); //Création et Remplissage de la structure de "IfcProject" _st_IfcTree = new STRUCT_IFCENTITY(); FillAttributeOf_STRUCT_IFCENTITY(_st_IfcTree, m_messages, db_LocalMat); //Recupération chainée des entités successives de "IfcProject" iRes = BuildTreeFrom(pElem, ifcXmlFile, _st_IfcTree); return iRes; } template int ifc_Tree::BuildTreeFromRelAggregates(list &lpRelatedObjects, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { //Boucle sur les RelatedObjects de IfcRelAggregates en cours int res = 0; list ::iterator it_Elem; for (it_Elem = lpRelatedObjects.begin(); it_Elem != lpRelatedObjects.end(); it_Elem++) { //lecture du contenu des child d'un IfcEntity liés à "IfcProject" Map_String_String map_messages; res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_Elem, map_messages); //Recup du positionnement relatif Type_Elmt_Of_Source *lpObjectPlac = nullptr; ifcXmlFile->FindIfcLocalPlacement(*it_Elem, lpObjectPlac); //Recup de la matrice de position double db_LocalMat[3][4]; ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); //Création et Remplissage de la structure de "IfcEntity" STRUCT_IFCENTITY * st_IfcContain = new STRUCT_IFCENTITY; FillAttributeOf_STRUCT_IFCENTITY(st_IfcContain, map_messages, db_LocalMat, &(*st_IfcBelongTo)); //Appel Récursif BuildTreeFrom(*it_Elem, ifcXmlFile, st_IfcContain); }// for (it_Elem = lpRelatedObjects.begin(); it_Elem != lpRelatedObjects.end(); it_Elem++) return res; } template int ifc_Tree::BuildTreeFromShapeOfSpace(list &lpShape, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { //Boucle sur les IfcProductDefinitionShape de IfcSpace en cours int res = 0; list ::iterator it_ElemShape; for (it_ElemShape = lpShape.begin(); it_ElemShape != lpShape.end(); it_ElemShape++) { //lecture du contenu des child d'un IfcEntity liés à "IfcProject" Map_String_String map_messages; res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_ElemShape, map_messages); // !!!! IfcProductDefinitionShape n'a pas de LocalPlacement !!!! //Création et Remplissage de la structure de "IfcEntity" STRUCT_IFCENTITY * st_IfcContainRep = new STRUCT_IFCENTITY; FillAttributeOf_STRUCT_IFCENTITY(st_IfcContainRep, map_messages, nullptr, &(*st_IfcBelongTo)); //Appel Récursif //1/2) A REVOIR Voir à récuperer les data (les n faces) des ifcSpaces...=> cf STRUCT_GEOMDATA_POINTS //IfcConnectionSurfaceGeometry int ifc_Tree::BuildTreeFromRelSpaceBoundary(list &lpRelatedBuildingElement, list &lpConnectionSurfaceGeometry, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { //Boucle à la fois sur les éléments de construction et sur les ConnectionSurfaceGeometry (correspondance unaire 1 <-> 1) int res = 0; list ::iterator it_ElemBE; list ::iterator it_ElemCSG; for (it_ElemBE = lpRelatedBuildingElement.begin(), it_ElemCSG = lpConnectionSurfaceGeometry.begin(); it_ElemBE != lpRelatedBuildingElement.end() && it_ElemCSG != lpConnectionSurfaceGeometry.end(); it_ElemBE++, it_ElemCSG++) { //lecture du contenu des Buildingelements de "IfcSpace" Map_String_String map_messages; res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_ElemBE, map_messages); //Création (ou recuperation) et Remplissage de la structure du Building Element "IfcWall..." STRUCT_IFCENTITY * st_IfcContainBE = nullptr; if (_map_ID_IfcEnt[map_messages["Id"]]) { st_IfcContainBE = _map_ID_IfcEnt[map_messages["Id"]]; FillAttributeOfExisting_STRUCT_IFCENTITY(st_IfcContainBE, map_messages, nullptr, &(*st_IfcBelongTo)); }// if (_map_ID_IfcEnt[map_messages["Id"]) else { st_IfcContainBE = new STRUCT_IFCENTITY; _map_ID_IfcEnt[map_messages["Id"]] = st_IfcContainBE; FillAttributeOf_STRUCT_IFCENTITY(st_IfcContainBE, map_messages, nullptr, &(*st_IfcBelongTo)); //lecture du Quantities des Buildingelements de "IfcSpace" map_messages.clear(); res = ifcXmlFile->ReadKeyWordsAndValuesOfIfcElementQuantity(*it_ElemBE, map_messages); FillQuantitiesAttributeOf_STRUCT_IFCENTITY(st_IfcContainBE, map_messages); //Fillattribute.... A FAIRE }// else if (_map_ID_IfcEnt[map_messages["Id"]) //lecture du contenu des ConnectionSurfaceGeometry (sous-Faces) de "IfcSpace" map_messages.clear(); res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_ElemCSG, map_messages); //Création et Remplissage de la structure de "IfcConnectionSurfaceGeometry" STRUCT_IFCENTITY * st_IfcContainCSG = new STRUCT_IFCENTITY; FillAttributeOf_STRUCT_IFCENTITY(st_IfcContainCSG, map_messages, nullptr, &(*st_IfcBelongTo), &(*st_IfcContainBE)); //Appel Récursif //2/2) A REVOIR Voir à récuperer les data (les n ss-faces) des ifcSpaces...=> cf STRUCT_GEOMDATA_POINTS //IfcConnectionSurfaceGeometry int ifc_Tree::BuildExplicitDataTreeFromIfcConnectionSurfaceGeometry(Type_Elmt_Of_Source* pElem, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { //Pour IfcConnectionSurfaceGeometry => 1 Sous-Face // // // // // // // => a mettre dans identifiant sous-face // // // // // // // // // ////// 1)/2) => 1=Plan de ref [2=Sous-Surf dans le plan de ref (=> chgmt ref)] // // // // // // // // // // // // // // // // // // // // // // 0.9999824492 // 0.005924630765 // 0. // // // ////// 2)/2) => 2=Sous-Surf dans le plan de ref (=> chgmt ref) [1=Plan de ref] // // // // // // false // // // // continuous // false // // // // // // // // // // // // // // // // // // 0. // 6.511503496 // 0. // // // //Recup de repere local P/R reprere global Type_Elmt_Of_Source *lpObjectPlac = nullptr; ifcXmlFile->FindIfcCurveBoundedPlanePlacemcent(pElem, lpObjectPlac); double db_LocalMat[3][4]; int Res = ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); FillRelativePlacementOf_STRUCT_IFCENTITY(st_IfcBelongTo, db_LocalMat); //Recup des points P/R reprere local list lst_Path_For_SubFace; lst_Path_For_SubFace.push_back("SurfaceOnRelatingElement");// [1..1] 1 Face => gérer un 1er niveau de listes lst_Path_For_SubFace.push_back("OuterBoundary");//[1..n] M contours => gerer un 2ème niveau de listes => 1er contour externe ensuite internes ("InnerBoundaries"? => utilité en BEM?? => ignorées pour le moment) lst_Path_For_SubFace.push_back("Segments"); //[1..n] 1 seul contour (externe) mais contenant plusieurs segments => dans même liste?? lst_Path_For_SubFace.push_back("ParentCurve"); list ::iterator it_ElemForPath_SubFace; it_ElemForPath_SubFace = lst_Path_For_SubFace.begin(); // // "lll" est une liste qui dissocie les IfcPolyline par entités de type (IfcCurveBoundedPlane,...) sous SurfaceOnRelatingElement // "ll" est une liste qui dissocie les IfcPolyline par entités de type (IfcCompositeCurve,...) sous OuterBoundary // "l" est une liste d'entités (IfcPolyline,...) sous Segments>ParentCurve (cette liste rassemble la multiplicité de ces Segments>ParentCurve) list lpObjectSubFace; list >> lllBoundaryOfSurface_SubFace; Res = ifcXmlFile->FindObjectFromRefAndPathBy3(pElem, it_ElemForPath_SubFace, lst_Path_For_SubFace.end(), lllBoundaryOfSurface_SubFace, lpObjectSubFace); //Recupération des points définissant chaque face + création des faces et assoc avec les "BelongTo" //Si il y a plus d'une Rep => problème if (lllBoundaryOfSurface_SubFace.size() > 1) return 1; if (lllBoundaryOfSurface_SubFace.size() != lpObjectSubFace.size()) return 2; // //Recup de la Rep list >> ::iterator it_BoundaryOfSurface = lllBoundaryOfSurface_SubFace.begin(); // //Boucle sur les faces de la Rep pour récupérer leurs contours list ::iterator it_SubFace; list > ::iterator it_SegmentsOfBoundary; for (it_SegmentsOfBoundary = (*it_BoundaryOfSurface).begin(), it_SubFace = lpObjectSubFace.begin(); it_SegmentsOfBoundary != (*it_BoundaryOfSurface).end(); it_SegmentsOfBoundary++, it_SubFace++) { //lecture du contenu des child d'un IfcEntity liés à "IfcProject" Map_String_String map_messages; Res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_SubFace, map_messages); list> SubFacePtsCoord;//la list définit un des contours de la face, list> définit les contours de la face Res = ifcXmlFile->ReadPtsDefiningPolyloopOrPolyline((*it_SegmentsOfBoundary), SubFacePtsCoord); //Création et Remplissage de la structure "Sous-Face" STRUCT_IFCENTITY * st_IfcSubFacGeomRep = new STRUCT_IFCENTITY; FillGeomAttributeOf_STRUCT_IFCENTITY(st_IfcSubFacGeomRep, SubFacePtsCoord, st_IfcBelongTo, map_messages); }// for (it_SegmentsOfBoundary = (*it_BoundaryOfSurface).begin(); it_SegmentsOfBoundary != (*it_BoundaryOfSurface).end(); it_SegmentsOfBoundary++) return Res; } template int ifc_Tree::BuildExplicitDataTreeFromIfcProductDefinitionShape(Type_Elmt_Of_Source* pElem, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { //Pour IfcProductDefinitionShape => n Faces => seul l'IfcShapeRepresentation "Body" est pris en compte! // // // // // // // ////// 1)/2) => 1=Body (=> 6 faces "Polyloops" pour cube) [et 2=FootPrint (Polylines)] // // // // // // Body // Brep // // // // // ////// 1.1)/1.2) // // // Body // Model // // // // model_view // // // // Model // 3 // 1.000000000E-5 // // // // // => !! 2 ex:double-wrapper et non 3 // // // ////// 1.2)/1.2) // // // // // // // // // // => a mettre dans identifiant face // => a mettre dans identifiant face // => a mettre dans identifiant face // => a mettre dans identifiant face // => a mettre dans identifiant face // => a mettre dans identifiant face // // // // // // // // // // // // // // true // // // // // // // // // // // ////// 2)/2) => 2=FootPrint (Polylines) [et 1=Body (=> 6 faces "Polyloops" pour cube)] // // // // // // FootPrint // GeometricCurveSet // // // // // ////// 2.1)/2.2) // // // FootPrint // Model // // // // model_view // // ////// 2.2)/2.2) // // // // // // // int Res = 0; // //Recup de l'IfcShapeRepresentation de type BRep Type_Elmt_Of_Source *lpObjectFound = nullptr; ifcXmlFile->FindIfcShapeRepresentationBrep(pElem, lpObjectFound); if (lpObjectFound) { //Recup de repere local P/R reprere global Type_Elmt_Of_Source *lpObjectPlac = nullptr; ifcXmlFile->FindIfcGeometricRepresentationSubContext(lpObjectFound, lpObjectPlac); double db_LocalMat[3][4]; Res = ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); FillRelativePlacementOf_STRUCT_IFCENTITY(st_IfcBelongTo, db_LocalMat); //Recup des points P/R reprere local list lst_Path_For_BodyFaces; lst_Path_For_BodyFaces.push_back("Items"); //[1..n] => HP: 1 seul Item pertinent pour BEM?? lst_Path_For_BodyFaces.push_back("Outer"); lst_Path_For_BodyFaces.push_back("CfsFaces"); //[1..n] N Faces => gérer un 1er niveau de listes lst_Path_For_BodyFaces.push_back("Bounds"); //[1..n] M contours => gerer un 2ème niveau de listes => 1er contour externe ensuite internes? lst_Path_For_BodyFaces.push_back("Bound"); list ::iterator it_ElemForPath_BodyFaces; it_ElemForPath_BodyFaces = lst_Path_For_BodyFaces.begin(); // // "lll" est une liste qui dissocie les IfcPolyLoop par entités de type (IfcFacetedBrep,...) sous Items // "ll" est une liste qui dissocie les IfcPolyLoop par entités de type (IfcFace,...) sous CfsFaces // "l" est une liste d'entités (IfcPolyLoop,...) sous Bounds>Bound (cette liste rassemble la multiplicité de ces Bounds>Bound) list lpObjectFace; list >> lllCFsFacesOfOneItem_Face; // => liste des BRep (1 seule utile pour BEM??) Res = ifcXmlFile->FindObjectFromRefAndPathBy3(lpObjectFound, it_ElemForPath_BodyFaces, lst_Path_For_BodyFaces.end(), lllCFsFacesOfOneItem_Face, lpObjectFace); //Recupération des points définissant chaque face + création des faces et assoc avec les "BelongTo" //Si il y a plus d'une Rep => problème if (lllCFsFacesOfOneItem_Face.size() > 1) return 1; if ( (*(lllCFsFacesOfOneItem_Face.begin())).size() != lpObjectFace.size()) return 2; // //Recup de la Rep list >> ::iterator it_CFsFacesOfOneItem = lllCFsFacesOfOneItem_Face.begin(); // //Boucle sur les faces de la Rep pour récupérer leurs contours list ::iterator it_Face; list > ::iterator it_BoundsOfOneCFsFace; for (it_BoundsOfOneCFsFace = (*it_CFsFacesOfOneItem).begin(), it_Face = lpObjectFace.begin(); it_BoundsOfOneCFsFace != (*it_CFsFacesOfOneItem).end(); it_BoundsOfOneCFsFace++, it_Face++) { //lecture du contenu des child d'un IfcEntity liés à "IfcProject" Map_String_String map_messages; Res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_Face, map_messages); list> FacePtsCoord;//la list définit un des contours de la face, list> définit les contours de la face Res = ifcXmlFile->ReadPtsDefiningPolyloopOrPolyline(*it_BoundsOfOneCFsFace, FacePtsCoord); //Création et Remplissage de la structure "Face" STRUCT_IFCENTITY * st_IfcFacGeomRep = new STRUCT_IFCENTITY; FillGeomAttributeOf_STRUCT_IFCENTITY(st_IfcFacGeomRep, FacePtsCoord, st_IfcBelongTo, map_messages); }// for (it_BoundsOfOneCFsFace = (*it_CFsFacesOfOneItem).begin(); it_BoundsOfOneCFsFace != (*it_CFsFacesOfOneItem).end(); it_BoundsOfOneCFsFace++) }// if(lpObjectFound) return Res; } // /////////////////////////////////////////////////////////////////////////////////// // Routines intermédiaires "d'aiguillage" mais ne créant pas de structure/entité // /////////////////////////////////////////////////////////////////////////////////// // template int ifc_Tree::BuildTreeFrom(Type_Elmt_Of_Source* pElem, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { // // IfcRelAggregates // //Recuperation des IfcEntity liés à pElem ("IfcProject",ifcSite...) par le lien binaire IfcRelAggregates list lpRelatedObjects; int res = ifcXmlFile->FindRelatedObjectsInRelAggregatesFromRelatingObject(pElem, &lpRelatedObjects); // Si lpRelatedObjects est vide il n'y a pas d'autre RelAggreg => à priori à partir des ifcspaces // ???Si lpRelatedObjects est vide il n'y a pas d'autre RelAggreg => essayer alors RelProperties...??? if (lpRelatedObjects.size() != 0) { BuildTreeFromRelAggregates(lpRelatedObjects, ifcXmlFile, &(*st_IfcBelongTo)); }// if (lpRelatedObjects.size!=0) else { - // - //lecture du Quantities des "IfcSpace" - Map_String_String map_messages; - res = ifcXmlFile->ReadKeyWordsAndValuesOfIfcElementQuantity(pElem, map_messages); - FillQuantitiesAttributeOf_STRUCT_IFCENTITY(st_IfcBelongTo, map_messages); - - // - // IfcProductDefinitionShape - // - //récupérer le lien IfcSpace <-> Faces (pas le data geom!) => IfcProductDefinitionShape - //Recuperation de l'IfcEntity (IfcProductDefinitionShape) de "IfcSpace" consigné dans sa definition - list lpShape; - res = ifcXmlFile->FindRepresentationInSpace(pElem, &lpShape); - - BuildTreeFromShapeOfSpace(lpShape, ifcXmlFile, &(*st_IfcBelongTo)); - - // - // IfcRelSpaceBoundary - // - //Recuperation des IfcEntity liés à "IfcSpace" par le lien ternaire IfcRelSpaceBoundary - list lpRelatedBuildingElement; - list lpConnectionSurfaceGeometry; - res = ifcXmlFile->FindRelatedBuildingElementAndConnectionGeometryInRelSpaceBoundaryFromRelatingSpace(pElem, &lpRelatedBuildingElement, &lpConnectionSurfaceGeometry); - - if (lpRelatedBuildingElement.size() != 0 && lpRelatedBuildingElement.size() == lpConnectionSurfaceGeometry.size()) + //Test car il peut exister par exemple des IfcBuildingStorey sans espace => ne pas continuer cette branche + // Par sécurité, test étendu aux entités "pères": IfcProject, IfcSite, IfcBuilding, IfcBuildingStorey + if (string(pElem->Value()) != string("IfcProject") + && string(pElem->Value()) != string("IfcSite") + && string(pElem->Value()) != string("IfcBuilding") + && string(pElem->Value()) != string("IfcBuildingStorey") + ) { - BuildTreeFromRelSpaceBoundary(lpRelatedBuildingElement, lpConnectionSurfaceGeometry, ifcXmlFile, &(*st_IfcBelongTo)); - }// if (lpRelatedBuildingElement.size() != 0 && lpRelatedBuildingElement.size() == lpConnectionSurfaceGeometry.size()) - + // + //lecture du Quantities des "IfcSpace" + Map_String_String map_messages; + res = ifcXmlFile->ReadKeyWordsAndValuesOfIfcElementQuantity(pElem, map_messages); + FillQuantitiesAttributeOf_STRUCT_IFCENTITY(st_IfcBelongTo, map_messages); + + // + // IfcProductDefinitionShape + // + //récupérer le lien IfcSpace <-> Faces (pas le data geom!) => IfcProductDefinitionShape + //Recuperation de l'IfcEntity (IfcProductDefinitionShape) de "IfcSpace" consigné dans sa definition + list lpShape; + res = ifcXmlFile->FindRepresentationInSpace(pElem, &lpShape); + + BuildTreeFromShapeOfSpace(lpShape, ifcXmlFile, &(*st_IfcBelongTo)); + + // + // IfcRelSpaceBoundary + // + //Recuperation des IfcEntity liés à "IfcSpace" par le lien ternaire IfcRelSpaceBoundary + list lpRelatedBuildingElement; + list lpConnectionSurfaceGeometry; + res = ifcXmlFile->FindRelatedBuildingElementAndConnectionGeometryInRelSpaceBoundaryFromRelatingSpace(pElem, &lpRelatedBuildingElement, &lpConnectionSurfaceGeometry); + + if (lpRelatedBuildingElement.size() != 0 && lpRelatedBuildingElement.size() == lpConnectionSurfaceGeometry.size()) + { + BuildTreeFromRelSpaceBoundary(lpRelatedBuildingElement, lpConnectionSurfaceGeometry, ifcXmlFile, &(*st_IfcBelongTo)); + }// if (lpRelatedBuildingElement.size() != 0 && lpRelatedBuildingElement.size() == lpConnectionSurfaceGeometry.size()) + }// if (string(pElem->Value()) != string("IfcProject") + // && string(pElem->Value()) != string("IfcSite") + // && string(pElem->Value()) != string("IfcBuilding") + // && string(pElem->Value()) != string("IfcBuildingStorey") }// else if (lpRelatedObjects.size!=0) return res; } template int ifc_Tree::BuildExplicitDataTreeFrom(Type_Elmt_Of_Source* pElem, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { int Res = 0; //Pour IfcConnectionSurfaceGeometry => 1 Sous-Face if (string(pElem->Value()) == string("IfcConnectionSurfaceGeometry")) { Res = BuildExplicitDataTreeFromIfcConnectionSurfaceGeometry(pElem, ifcXmlFile, st_IfcBelongTo); }// if (string(pElem->Value()) == string("IfcConnectionSurfaceGeometry")) //Pour IfcProductDefinitionShape => n Faces // // IMPORTANT (A CONFIRMER): // HP: 1 Space <=> 1 Shape <=> 1 BRep (utile pour BEM) => N Faces et 1 Face => N contours (1 externe et N-1 internes)???? // => du coup on élimine shape et BRep pour associer 1 Space à N Faces // Attention: question => 1 Face peut contenir un contour externe et des contours internes??? // => gérer liste de listes de points // => si en général 1 seul contour externe et n internes alors 1ère liste=contour externe et les autres listes=internes // if (string(pElem->Value()) == string("IfcProductDefinitionShape")) { Res=BuildExplicitDataTreeFromIfcProductDefinitionShape(pElem, ifcXmlFile, st_IfcBelongTo); }// if (string(pElem->Value()) == string("IfcProductDefinitionShape")) return 0; }