diff --git a/IfcC++/.vs/ifc_BIMxBEMEPFLEngine/v14/.suo b/IfcC++/.vs/ifc_BIMxBEMEPFLEngine/v14/.suo index fc6d3ea..93f8a9a 100644 Binary files a/IfcC++/.vs/ifc_BIMxBEMEPFLEngine/v14/.suo and b/IfcC++/.vs/ifc_BIMxBEMEPFLEngine/v14/.suo differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine.VC.db b/IfcC++/ifc_BIMxBEMEPFLEngine.VC.db index 1613032..65e4344 100644 Binary files a/IfcC++/ifc_BIMxBEMEPFLEngine.VC.db and b/IfcC++/ifc_BIMxBEMEPFLEngine.VC.db differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.cpp index 59cf82e..8bc9258 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.cpp +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.cpp @@ -1,892 +1,959 @@ #include "LoadDataAtBEMFormat.h" #include -LoadDataAtBEMFormat::LoadDataAtBEMFormat() +LoadDataAtBEMFormat::LoadDataAtBEMFormat(double dbl_Minisurf) { + _dbl_MinimalSurface = dbl_Minisurf; } LoadDataAtBEMFormat::~LoadDataAtBEMFormat() { } //Convertit les structures attendues par Lesosai en chaine de caractères int LoadDataAtBEMFormat::GetLesosaiEntitiesDefinition(string *&str_EntDef) { int res = 0; str_EntDef = _str_EntitiesDefinitions; return res; } +int LoadDataAtBEMFormat::GetLesosaiLogFile(string *&str_LogFile) +{ + int res = 0; + str_LogFile = _str_LogFile; + return res; +} + int LoadDataAtBEMFormat::GetLesosaiEntitiesNumber() { int res = 0; return res; } int LoadDataAtBEMFormat::GetLesosaiEntitiesAttributesSize() { int res = 0; return res; } //Transforme la structure générique ifc_Tree en des structures attendues par Lesosai int LoadDataAtBEMFormat::LoadLesosaiFormat(ifc_Tree* CurrentIfcTree) { int res = 0; + // Allocation de la chaine de caractere (log pour consigner certaines infos: retrait des surfaces quasi-nulles par exple) + _str_LogFile = new string(); + //Pour Post-traiter le tree => mettre l'arbre en rateau (sans duplication des entités) ifc_TreePostTreatment *cl_PostTreatmt = new ifc_TreePostTreatment(CurrentIfcTree); //Mise à plat de l'arbre (en rateau) Map_Basified_Tree *map_BasifTree=nullptr; if(cl_PostTreatmt) cl_PostTreatmt->BasifyTree(map_BasifTree); //Certains contours sont définis avec en dernier point le 1er points (loop) //Pour la suite des traitements, cela nous gêne (calcul du centre de gravité=CentroidsComputation, détection des points les plus proche=RelimitSideBySideSurfaces) //Retrait dans les contours (st_PointsDesContours) du derniers point lorsqu'il est égal au 1er (+ consigne bool bo_IsItLoop=true) if (cl_PostTreatmt) - cl_PostTreatmt->RemoveLastPointOfLoopContours(); + cl_PostTreatmt->RemoveLastPointOfLoopContours(_str_LogFile); //Calcul des surfaces IfcConnectionSurfaceGeometry // => à faire avant changement de coord car algo fonctionne en 2D => si la 3ème coord est la même pour toute! if (cl_PostTreatmt) cl_PostTreatmt->ComputeIfcConnectionSurfaceGeometrySurface(); + if (cl_PostTreatmt) + cl_PostTreatmt->RemoveQuasiNullIfcConnectionSurfaceGeometrySurface(_dbl_MinimalSurface, _str_LogFile); + //Relance pour nettoyer map_BasifTree + if (cl_PostTreatmt) + cl_PostTreatmt->BasifyTree(map_BasifTree); + //Changement repere => repere projet if (cl_PostTreatmt) cl_PostTreatmt->TransformEntitiesToWorlCoordFrame(); //Calcul des centres de gravité de chaque IfcConnectionSurfaceGeometry if (cl_PostTreatmt) cl_PostTreatmt->CentroidsComputation(); //Repérage des IfcConnectionSurfaceGeometry en vis-à-vis et côte-à-côte if (cl_PostTreatmt) cl_PostTreatmt->FindFaceToFaceAndSideBySideSurfaces(); //Raccord des IfcConnectionSurfaceGeometry en côte-à-côte if (cl_PostTreatmt) - cl_PostTreatmt->RelimitSideBySideSurfaces(); + cl_PostTreatmt->RelimitSideBySideSurfaces(_str_LogFile); //Raccord des IfcConnectionSurfaceGeometry en côte-à-côte if (cl_PostTreatmt) cl_PostTreatmt->CreateTIFCSurfaces(); //Ajout des TIFCSurfaces à ifc_TreePostTreatment::_map_BasifTree if (cl_PostTreatmt) cl_PostTreatmt->CompleteBasifiedTreeFromByTIFCSurfaces(); // Allocation de la chaine de caractere (fourniture des données du Tree via cette chaine de caractere) _str_EntitiesDefinitions = new string(); //Conversion des entités dans la chaine de caractere _str_EntitiesDefinitions (membre de la classe) ConvertBasifiedTree(map_BasifTree); return res; } //int LoadDataAtBEMFormat::BasifyTreeFrom(STRUCT_IFCENTITY *&st_IfcTree, Map_Basified_Tree &map_BasifTree) //{ // int res = 0; // //Memo adresse pointeur (si existe pas ajouté) et son type "Ifc" // // => la map permet de ne pas référencer de multiple fois une même entité // // dans l'arbre, des entités sont référencés plusieurs fois car elles appartiennent à plusieurs objets // map_BasifTree[st_IfcTree] = st_IfcTree->ch_Type; // // list ::iterator it_Elem; // for (it_Elem = (st_IfcTree->st_Contains).begin(); it_Elem != (st_IfcTree->st_Contains).end(); it_Elem++) // { // BasifyTreeFrom((*it_Elem), map_BasifTree); // }// for (it_Elem = (st_IfcTree->st_Contains).begin(); it_Elem != (st_IfcTree->st_Contains).end(); it_Elem++) // // return res; //} // int LoadDataAtBEMFormat::ConvertBasifiedTree(Map_Basified_Tree *&map_BasifTree) { int res = 0; OpenSets(); std::map::iterator it_Elem; for (it_Elem = map_BasifTree->begin(); it_Elem != map_BasifTree->end(); it_Elem++) { if (it_Elem->second == "IfcConnectionSurfaceGeometry") { ConvertIfcConnectionSurfaceGeometry(it_Elem->first); //Pour Lesosai ConvertTIFCGeo2D(it_Elem->first); }// if (it_Elem->second == "IfcConnectionSurfaceGeometry") else if (it_Elem->second == "TIFCSurface") ConvertTIFCSurface(it_Elem->first); else if (it_Elem->second == "IfcFace") ConvertIfcFace(it_Elem->first); else if (it_Elem->second == "IfcCurveBoundedPlane") ConvertIfcSubFace(it_Elem->first); //else if (it_Elem->second == "IfcProductDefinitionShape") // ConvertIfcProductDefinitionShape(it_Elem->first); else if (it_Elem->second == "IfcSpace") ConvertIfcSpace(it_Elem->first); else if (it_Elem->second == "IfcBuildingStorey") ConvertIfcBuildingStorey(it_Elem->first); else if (it_Elem->second == "IfcBuilding") ConvertIfcBuilding(it_Elem->first); else if (it_Elem->second == "IfcSite") ConvertIfcSite(it_Elem->first); else if (it_Elem->second == "IfcProject") ConvertIfcProject(it_Elem->first); }// for (it_Elem = map_BasifTree.begin(); it_Elem != map_BasifTree.end(); it_Elem++) CloseSets(); //Merge des 2 Set_Of_TIFCPolygons: _str_FacesDefinitions + _str_SubFacesDefinitions string str_Deb = ""; string str_Fin = ""; int int_Level = 10; string str_ValKW = ""; string str_KW = _str_LESOSAI_PolygonsSet; LineForLevel(int_Level, str_Deb, str_KW, str_ValKW); int_Level = 11; LineForLevel(int_Level, str_Fin, str_KW, str_ValKW); //string str_Deb = DEB_KW0_L + _str_LESOSAI_PolygonsSet + KW_R; //string str_Fin = FIN_KW0_L + _str_LESOSAI_PolygonsSet + KW_R; //Retrait fin du paragraphe _str_FacesDefinitions = _str_FacesDefinitions.substr(0, _str_FacesDefinitions.length() - str_Fin.length()); //Retrait début du paragraphe _str_SubFacesDefinitions = _str_SubFacesDefinitions.substr(str_Deb.length(), _str_SubFacesDefinitions.length() - str_Deb.length()); int_Level = 0; str_ValKW = ""; str_KW = _str_LESOSAI_SetsRoot; LineForLevel(int_Level, *_str_EntitiesDefinitions, str_KW, str_ValKW); *_str_EntitiesDefinitions += /*DEB_KW0_L + _str_LESOSAI_SetsRoot + KW_Rn +*/_str_ProjectsDefinitions + _str_SitesDefinitions + _str_BuildingsDefinitions + _str_BuildingStoreysDefinitions + _str_SpacesDefinitions //+ _str_ProductDefinitionShapesDefinitions + _str_TIFCSurfacesDefinitions + _str_TIFCGeo2DDefinitions + _str_FacesDefinitions + _str_SubFacesDefinitions //+_str_ConnectionSurfaceGeometriesDefinitions /*+ FIN_KW0_L + _str_LESOSAI_SetsRoot + KW_R*/ ; int_Level = 1; str_ValKW = ""; str_KW = _str_LESOSAI_SetsRoot; LineForLevel(int_Level, *_str_EntitiesDefinitions, str_KW, str_ValKW); return res; } void LoadDataAtBEMFormat::OpenSets() { int int_Level = 10; string str_ValKW = ""; string str_KW = _str_LESOSAI_ProjetsSet; LineForLevel(int_Level, _str_ProjectsDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_SitesSet; LineForLevel(int_Level, _str_SitesDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_BuildingsSet; LineForLevel(int_Level, _str_BuildingsDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_StoreysSet; LineForLevel(int_Level, _str_BuildingStoreysDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_SpacesSet; LineForLevel(int_Level, _str_SpacesDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_SurfacesSet; LineForLevel(int_Level, _str_TIFCSurfacesDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_PolygonsSet; LineForLevel(int_Level, _str_FacesDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_Geo2DSet; LineForLevel(int_Level, _str_TIFCGeo2DDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_PolygonsSet; LineForLevel(int_Level, _str_SubFacesDefinitions, str_KW, str_ValKW); str_KW = "ProductDefinitionShapes"; LineForLevel(int_Level, _str_ProductDefinitionShapesDefinitions, str_KW, str_ValKW); str_KW = "ConnectionSurfaceGeometries"; LineForLevel(int_Level, _str_ConnectionSurfaceGeometriesDefinitions, str_KW, str_ValKW); //_str_ProjectsDefinitions += DEB_KW0_L + _str_LESOSAI_ProjetsSet + KW_R; //_str_SitesDefinitions += DEB_KW0_L + _str_LESOSAI_SitesSet + KW_R; //_str_BuildingsDefinitions += DEB_KW0_L + _str_LESOSAI_BuildingsSet + KW_R; //_str_BuildingStoreysDefinitions += DEB_KW0_L + _str_LESOSAI_StoreysSet + KW_R; //_str_SpacesDefinitions += DEB_KW0_L + _str_LESOSAI_SpacesSet + KW_R; //_str_TIFCSurfacesDefinitions += DEB_KW0_L + _str_LESOSAI_SurfacesSet + KW_R; //_str_FacesDefinitions += DEB_KW0_L + _str_LESOSAI_PolygonsSet + KW_R; //_str_TIFCGeo2DDefinitions += DEB_KW0_L + _str_LESOSAI_Geo2DSet + KW_R; //_str_SubFacesDefinitions += DEB_KW0_L + _str_LESOSAI_PolygonsSet + KW_R;//"SubFaces" //_str_ProductDefinitionShapesDefinitions += DEB_KW0_L + "ProductDefinitionShapes" + KW_R; //_str_ConnectionSurfaceGeometriesDefinitions += DEB_KW0_L + "ConnectionSurfaceGeometries" + KW_R; } void LoadDataAtBEMFormat::CloseSets() { int int_Level = 11; string str_ValKW = ""; string str_KW = _str_LESOSAI_ProjetsSet; LineForLevel(int_Level, _str_ProjectsDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_SitesSet; LineForLevel(int_Level, _str_SitesDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_BuildingsSet; LineForLevel(int_Level, _str_BuildingsDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_StoreysSet; LineForLevel(int_Level, _str_BuildingStoreysDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_SpacesSet; LineForLevel(int_Level, _str_SpacesDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_SurfacesSet; LineForLevel(int_Level, _str_TIFCSurfacesDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_PolygonsSet; LineForLevel(int_Level, _str_FacesDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_Geo2DSet; LineForLevel(int_Level, _str_TIFCGeo2DDefinitions, str_KW, str_ValKW); str_KW = _str_LESOSAI_PolygonsSet; LineForLevel(int_Level, _str_SubFacesDefinitions, str_KW, str_ValKW); str_KW = "ProductDefinitionShapes"; LineForLevel(int_Level, _str_ProductDefinitionShapesDefinitions, str_KW, str_ValKW); str_KW = "ConnectionSurfaceGeometries"; LineForLevel(int_Level, _str_ConnectionSurfaceGeometriesDefinitions, str_KW, str_ValKW); //_str_ProjectsDefinitions += FIN_KW0_L + _str_LESOSAI_ProjetsSet + KW_R; //_str_SitesDefinitions += FIN_KW0_L + _str_LESOSAI_SitesSet + KW_R; //_str_BuildingsDefinitions += FIN_KW0_L + _str_LESOSAI_BuildingsSet + KW_R; //_str_BuildingStoreysDefinitions += FIN_KW0_L + _str_LESOSAI_StoreysSet + KW_R; //_str_SpacesDefinitions += FIN_KW0_L + _str_LESOSAI_SpacesSet + KW_R; //_str_TIFCSurfacesDefinitions += FIN_KW0_L + _str_LESOSAI_SurfacesSet + KW_R; //_str_FacesDefinitions += FIN_KW0_L + _str_LESOSAI_PolygonsSet + KW_R; //_str_TIFCGeo2DDefinitions += FIN_KW0_L + _str_LESOSAI_Geo2DSet + KW_R; //_str_SubFacesDefinitions += FIN_KW0_L + _str_LESOSAI_PolygonsSet + KW_R;//"SubFaces" //_str_ProductDefinitionShapesDefinitions += FIN_KW0_L + "ProductDefinitionShapes" + KW_R; //_str_ConnectionSurfaceGeometriesDefinitions += FIN_KW0_L + "ConnectionSurfaceGeometries" + KW_R; } int LoadDataAtBEMFormat::LineForLevel(int &int_Level, string &str_EntsDefinitions, string &str_KW, string &str_ValKW) { switch (int_Level) { case 0: str_EntsDefinitions = str_EntsDefinitions + DEB_KW0_L + str_KW + KW_Rn; break; case 1: str_EntsDefinitions = str_EntsDefinitions + FIN_KW0_L + str_KW + KW_Rn; break; case 10: str_EntsDefinitions = str_EntsDefinitions + DEB_KW1_L + str_KW + KW_Rn; break; case 11: str_EntsDefinitions = str_EntsDefinitions + FIN_KW1_L + str_KW + KW_Rn; break; case 20: str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_KW + KW_Rn; break; case 21: str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_KW + KW_Rn; break; case 30: str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + str_KW + KW_R + str_ValKW + FIN_KW0_L + str_KW + KW_Rn; break; case 32: str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + str_KW + KW_Rn; break; case 33: str_EntsDefinitions = str_EntsDefinitions + FIN_KW3_L + str_KW + KW_Rn; break; case 40: str_EntsDefinitions = str_EntsDefinitions + DEB_KW4_L + str_KW + KW_R + str_ValKW + FIN_KW0_L + str_KW + KW_Rn; break; case 42: str_EntsDefinitions = str_EntsDefinitions + DEB_KW4_L + str_ValKW + KW1_Rn; break; default: return 1; }// switch (int_Level) return 0; } int LoadDataAtBEMFormat::ConvertIfcEnt(STRUCT_IFCENTITY *&st_IfcEnt, string &str_Balise, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) { int res = 0; // Entête Début int int_Level = 20; string str_KW = str_Balise; string str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW1_L + str_Balise + KW_R; // Id, Name, Contains GenericConversion(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); // Entête Fin int_Level = 21; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW1_L + str_Balise + KW_R; return res; } int LoadDataAtBEMFormat::GenericConversion(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) { int res = 0; // Id int int_Level = 30; string str_KW = "Id"; string str_ValKW = st_IfcEnt->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_KW + KW_R + st_IfcEnt->ch_Id + FIN_KW0_L + str_KW + KW_R; // GlobalId str_KW= "GlobalId"; str_ValKW = st_IfcEnt->ch_GlobalId; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_KW + KW_R + st_IfcEnt->ch_GlobalId + FIN_KW0_L + str_KW + KW_R; // Name str_KW= "Name"; str_ValKW = st_IfcEnt->ch_Name; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_KW + KW_R + st_IfcEnt->ch_Name + FIN_KW0_L + str_KW + KW_R; // Contains if (string(st_IfcEnt->ch_Type) == string("IfcFace")) { res = SpecificConversionOfContainsForFaceAndSubFace(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); }// if (string(st_IfcEnt->ch_Type) == string("IfcFace")) else if (string(st_IfcEnt->ch_Type) == string("IfcCurveBoundedPlane")) { res = SpecificConversionOfContainsForFaceAndSubFace(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); }// else if (string(st_IfcEnt->ch_Type) == string("IfcCurveBoundedPlane")) else if (string(st_IfcEnt->ch_Type) == string("IfcSpace")) { res = SpecificConversionOfContainsForSpace(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); }// else if (string(st_IfcEnt->ch_Type) == string("IfcSpace")) else if (string(st_IfcEnt->ch_Type) == string("IfcConnectionSurfaceGeometry")) { if(str_InsideContainsName == _str_LESOSAI_Polygon) res = SpecificConversionOfContainsForTIFCGeo2D(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); else res = SpecificConversionOfContainsForConnectionSurfaceGeometry(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); }// else if (string(st_IfcEnt->ch_Type) == string("IfcConnectionSurfaceGeometry")) else if (string(st_IfcEnt->ch_Type) == string("TIFCSurface")) { res = SpecificConversionOfContainsForTIFCSurface(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); }// else if (string(st_IfcEnt->ch_Type) == string("TIFCSurface")) else if (string(st_IfcEnt->ch_Type) == string("IfcBuilding")) { res = SpecificConversionOfContainsBuilding(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); }// else if (string(st_IfcEnt->ch_Type) == string("TIFCSurface")) else { + if (string(st_IfcEnt->ch_Type) == string("IfcProject")) + res = SpecificConversionOfNorthProject(st_IfcEnt, str_EntsDefinitions/*, str_ContainsName, str_InsideContainsName*/); + res = SpecificConversionOfContains(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); }// else if (string(st_IfcEnt->ch_Type) == string("IfcFace")) return res; } int LoadDataAtBEMFormat::SpecificConversionOfContainsForTIFCGeo2D(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) { int res = 0; // Contains res = SpecificConversionOfContains(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); - Map_String_String::iterator it_MapVal; - for (it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) + //Map_String_String::iterator it_MapVal; + if (st_IfcEnt->map_DefValues) { - int int_Level = 30; - string str_KW = (*it_MapVal).first; - string str_ValKW = (*it_MapVal).second; - LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); - //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + (*it_MapVal).first + "=" + (*it_MapVal).second + KW_R; - }// for (it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) + for (Map_String_String::iterator it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) + { + int int_Level = 30; + string str_KW = (*it_MapVal).first; + string str_ValKW = (*it_MapVal).second; + LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); + //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + (*it_MapVal).first + "=" + (*it_MapVal).second + KW_R; + }// for (it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) + }// if (st_IfcEnt->map_DefValues) return res; } int LoadDataAtBEMFormat::SpecificConversionOfContainsForConnectionSurfaceGeometry(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName, string str_FaceToFaceName, string str_Centroid, string str_SideBySideName) { int res = 0; // Contains res = SpecificConversionOfContains(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); - Map_String_String::iterator it_MapVal; - for (it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) + //Map_String_String::iterator it_MapVal; + if (st_IfcEnt->map_DefValues) { - int int_Level = 30; - string str_KW = (*it_MapVal).first; - string str_ValKW = (*it_MapVal).second; - LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); - //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + (*it_MapVal).first + "=" + (*it_MapVal).second + KW_R; - }// for (it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) + for (Map_String_String::iterator it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) + { + int int_Level = 30; + string str_KW = (*it_MapVal).first; + string str_ValKW = (*it_MapVal).second; + LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); + //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + (*it_MapVal).first + "=" + (*it_MapVal).second + KW_R; + }// for (it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) + }// if (st_IfcEnt->map_DefValues) // FaceToface int int_Level = 32; string str_KW = str_FaceToFaceName; string str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //string str_Balise = str_FaceToFaceName; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; - list ::iterator it_Elem; - for (it_Elem = (st_IfcEnt->st_FaceToFace).begin(); it_Elem != (st_IfcEnt->st_FaceToFace).end(); it_Elem++) + //list ::iterator it_Elem; + for (list ::iterator it_Elem = (st_IfcEnt->st_FaceToFace).begin(); it_Elem != (st_IfcEnt->st_FaceToFace).end(); it_Elem++) { int_Level = 40; str_KW = ""; str_ValKW = (*it_Elem)->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + (*it_Elem)->ch_Id + KW_R; }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) int_Level = 33; str_KW = str_FaceToFaceName; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; // SideBySide int_Level = 32; str_KW = str_SideBySideName; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_Balise = str_SideBySideName; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; //list ::iterator it_Elem; //for (it_Elem = (st_IfcEnt->st_SideBySide).begin(); it_Elem != (st_IfcEnt->st_SideBySide).end(); it_Elem++) - map ::iterator it_ElemBool; - for (it_ElemBool = (st_IfcEnt->mp_SideBySide).begin(); it_ElemBool != (st_IfcEnt->mp_SideBySide).end(); it_ElemBool++) + //map ::iterator it_ElemBool; + //for (map > ::iterator it_ElemBool = (st_IfcEnt->mp_SideBySide).begin(); it_ElemBool != (st_IfcEnt->mp_SideBySide).end(); it_ElemBool++) + for (set >> ::iterator it_ElemBool = (st_IfcEnt->mp_SideBySide).begin(); it_ElemBool != (st_IfcEnt->mp_SideBySide).end(); it_ElemBool++) { - string bo_val=">ch_Id + bo_val; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + (*it_ElemBool).first->ch_Id + bo_val + KW_R; }// for (it_ElemBool = (st_IfcEnt->mp_SideBySide).begin(); it_ElemBool != (st_IfcEnt->mp_SideBySide).end(); it_ElemBool++) int_Level = 33; str_KW = str_SideBySideName; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; // Centroid int_Level = 32; str_KW = str_Centroid; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_Balise = str_Centroid; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; - list ::iterator it_DbVal; - for (it_DbVal = (st_IfcEnt->db_Centroid).begin(); it_DbVal != (st_IfcEnt->db_Centroid).end(); it_DbVal++) + //list ::iterator it_DbVal; + for (list ::iterator it_DbVal = (st_IfcEnt->db_Centroid).begin(); it_DbVal != (st_IfcEnt->db_Centroid).end(); it_DbVal++) { int_Level = 40; str_KW = ""; str_ValKW = to_string(*(*it_DbVal)); LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + to_string(*(*it_DbVal)) + KW_R; }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) int_Level = 33; str_KW = str_Centroid; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; // TIFCSurface int_Level = 32; str_KW = _str_LESOSAI_Surface; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_Balise = _str_LESOSAI_Surface; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; if (st_IfcEnt->st_TIFCSurface) { int_Level = 40; str_KW = ""; str_ValKW = st_IfcEnt->st_TIFCSurface->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + st_IfcEnt->st_TIFCSurface->ch_Id + KW_R; }// if (st_IfcEnt->st_TIFCSurface) int_Level = 33; str_KW = _str_LESOSAI_Surface; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; return res; } int LoadDataAtBEMFormat::SpecificConversionOfContainsForTIFCSurface(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) { int res = 0; // Contains //string str_Balise = str_ContainsName; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; int i_Ind=1; list ::iterator it_Elem; for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) { // geoInt1 et geoInt2 (geoInt2 est vide si c'est une TIFCsurface en vis-à-vis avec extérieur) int int_Level = 30; string str_KW = "geoInt" + std::to_string(i_Ind); string str_ValKW = (*it_Elem)->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + "geoInt" + std::to_string(i_Ind) + "=" + (*it_Elem)->ch_Id + KW_R; list ::iterator it_Elem2; for (it_Elem2 = ((*it_Elem)->st_BelongsTo).begin(); it_Elem2 != ((*it_Elem)->st_BelongsTo).end(); it_Elem2++) { if (string((*it_Elem2)->ch_Type) == "IfcSpace") { int_Level = 30; str_KW = "room" + std::to_string(i_Ind); str_ValKW = (*it_Elem2)->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + "room" + std::to_string(i_Ind) + "=" + (*it_Elem2)->ch_Id + KW_R; }// if (string((*it_Elem2)->ch_Type) == "IfcSpace") // Type de TIFCSurface : ifcWall, ifcCeiling, ifcFloor else if (i_Ind == 1) { int_Level = 30; str_KW = "surfType"; - str_ValKW = (*it_Elem2)->ch_Type; + if ((*it_Elem2)->ch_PredifinedType != nullptr /*&& (*it_Elem2)->ch_PredifinedType != "notdefined"*/) + str_ValKW = (*it_Elem2)->ch_PredifinedType; + else + str_ValKW = (*it_Elem2)->ch_Type; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + "surfType" + "=" + (*it_Elem2)->ch_Type + KW_R; }// else if (i_Ind == 1) }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) i_Ind ++ ; }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; return res; } int LoadDataAtBEMFormat::SpecificConversionOfContainsBuilding(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) { int res = 0; res = SpecificConversionOfContains(st_IfcEnt, str_EntsDefinitions, str_ContainsName, str_InsideContainsName); // boucle à partir du building sur ses storey, puis les espaces puis les ifconnecturface puis les TIFCSurface // pour recuperer tous les TIFCSurface du building(de maniere unique) = > map ou liste(+unique()) puis lire les id des TIFCSurface list li_TIFCSurfaceByBuilding; list ::iterator it_ElemStorey; for (it_ElemStorey = (st_IfcEnt->st_Contains).begin(); it_ElemStorey != (st_IfcEnt->st_Contains).end(); it_ElemStorey++) { list ::iterator it_ElemSpace; for (it_ElemSpace = ((*it_ElemStorey)->st_Contains).begin(); it_ElemSpace != ((*it_ElemStorey)->st_Contains).end(); it_ElemSpace++) { list ::iterator it_ElemCSAndBE; for (it_ElemCSAndBE = ((*it_ElemSpace)->st_Contains).begin(); it_ElemCSAndBE != ((*it_ElemSpace)->st_Contains).end(); it_ElemCSAndBE++) { if((*it_ElemCSAndBE)->st_TIFCSurface) li_TIFCSurfaceByBuilding.push_back((*it_ElemCSAndBE)->st_TIFCSurface); }// for (it_ElemCSAndBE = ((*it_ElemSpace)->st_Contains).begin(); it_ElemCSAndBE != ((*it_ElemSpace)->st_Contains).end(); it_ElemCSAndBE++) }// for (it_ElemSpace = ((*it_ElemStorey)->st_Contains).begin(); it_ElemSpace != ((*it_ElemStorey)->st_Contains).end(); it_ElemSpace++) }// for (it_ElemStorey = (st_IfcEnt->st_Contains).begin(); it_ElemStorey != (st_IfcEnt->st_Contains).end(); it_ElemStorey++) li_TIFCSurfaceByBuilding.sort(); li_TIFCSurfaceByBuilding.unique(); // surfaces int int_Level = 32; string str_KW = "surfaces" /*+ _str_LESOSAI_Surfaces*/; string str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //string str_Balise = "surfaces : " + _str_LESOSAI_Surfaces; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; list ::iterator it_Elem; for (it_Elem = li_TIFCSurfaceByBuilding.begin(); it_Elem != li_TIFCSurfaceByBuilding.end(); it_Elem++) { int_Level = 40; str_KW = _str_LESOSAI_Surface; str_ValKW = (*it_Elem)->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + _str_LESOSAI_Surface + "=" + (*it_Elem)->ch_Id + KW_R; }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) int_Level = 33; str_KW = "surfaces" /*+ _str_LESOSAI_Surfaces*/; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; return res; } int LoadDataAtBEMFormat::SpecificConversionOfContains(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) { int res = 0; // Contains int int_Level = 32; string str_KW = str_ContainsName; string str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //string str_Balise = str_ContainsName; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; list ::iterator it_Elem; for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) { if (str_InsideContainsName == "") { int_Level = 40; str_KW = ""; str_ValKW = (*it_Elem)->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + (*it_Elem)->ch_Id + KW_R; }// if (str_InsideContainsName == "") else { int_Level = 40; str_KW = str_InsideContainsName; str_ValKW = (*it_Elem)->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + str_InsideContainsName + "=" + (*it_Elem)->ch_Id + KW_R; }// else if (str_InsideContainsName == "") }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) int_Level = 33; str_KW = str_ContainsName; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; return res; } int LoadDataAtBEMFormat::SpecificConversionOfContainsForSpace(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) { int res = 0; // Contains int int_Level = 32; string str_KW = str_ContainsName; string str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //string str_Balise = str_ContainsName; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; list ::iterator it_Elem; for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) { if (string((*it_Elem)->ch_Type) == string("IfcProductDefinitionShape")) { //on saute l'étage "IfcProductDefinitionShape" pour descendre sur les faces list ::iterator it_SsElem; for (it_SsElem = ((*it_Elem)->st_Contains).begin(); it_SsElem != ((*it_Elem)->st_Contains).end(); it_SsElem++) { int int_Level = 40; string str_KW = str_InsideContainsName; string str_ValKW = (*it_SsElem)->ch_Id; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + str_InsideContainsName + "=" + (*it_SsElem)->ch_Id + KW_R; }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) }// for (it_SsElem = ((*it_Elem)->st_Contains).begin(); it_SsElem != ((*it_Elem)->st_Contains).end(); it_SsElem++) }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) int_Level = 33; str_KW = str_ContainsName; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; Map_String_String::iterator it_MapVal; for (it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) { int_Level = 30; str_KW = (*it_MapVal).first; str_ValKW = (*it_MapVal).second; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + (*it_MapVal).first + "=" + (*it_MapVal).second + KW_R; }// for (it_MapVal = (st_IfcEnt->map_DefValues)->begin(); it_MapVal != (st_IfcEnt->map_DefValues)->end(); it_MapVal++) return res; } int LoadDataAtBEMFormat::SpecificConversionOfContainsForFaceAndSubFace(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) { //lire la liste des points et non contains int res = 0; // Contains int int_Level = 32; string str_KW = str_ContainsName; string str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //string str_Balise = str_ContainsName; //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; list > ::iterator it_llPt; for (it_llPt = (st_IfcEnt->st_PointsDesContours).begin(); it_llPt != (st_IfcEnt->st_PointsDesContours).end(); it_llPt++) { list ::iterator it_lPt; for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) { int_Level = 42; str_KW = ""; str_ValKW = "point x=\"" + std::to_string(*(*it_lPt)) + "\""; it_lPt++; str_ValKW += " y=\"" + std::to_string(*(*it_lPt)) + "\""; it_lPt++; str_ValKW += " z=\"" + std::to_string(*(*it_lPt)) + "\""; //str_ValKW = std::to_string(*(*it_lPt)); LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + std::to_string(*(*it_lPt)) + KW_R; }// for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) }// for (it_llPt = (st_IfcEnt->st_PointsDesContours).begin(); it_llPt != (st_IfcEnt->st_PointsDesContours).end(); it_llPt++) int_Level = 33; str_KW = str_ContainsName; str_ValKW = ""; LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; return res; } +int LoadDataAtBEMFormat::SpecificConversionOfNorthProject(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions/*, string &str_ContainsName, string &str_InsideContainsName*/) +{ + //lire la liste des points et non contains + int res = 0; + string str_North = "north"; + // Contains + int int_Level = 32; + string str_KW = str_North; + string str_ValKW = str_North; + LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); + //string str_Balise = str_ContainsName; + //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; + list ::iterator it_lPt; + for (it_lPt = (st_IfcEnt->db_Centroid).begin(); it_lPt != (st_IfcEnt->db_Centroid).end(); it_lPt++) + { + //list ::iterator it_lPt; + //for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) + //{ + int_Level = 42; + str_KW = ""; + str_ValKW = "point x=\"" + std::to_string(*(*it_lPt)) + "\""; it_lPt++; + str_ValKW += " y=\"" + std::to_string(*(*it_lPt)) + "\""; it_lPt++; + str_ValKW += " z=\"" + std::to_string(*(*it_lPt)) + "\""; + //str_ValKW = std::to_string(*(*it_lPt)); + LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); + //str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + std::to_string(*(*it_lPt)) + KW_R; + //}// for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) + }// for (it_llPt = (st_IfcEnt->st_PointsDesContours).begin(); it_llPt != (st_IfcEnt->st_PointsDesContours).end(); it_llPt++) + int_Level = 33; + str_KW = str_North; + str_ValKW = ""; + LineForLevel(int_Level, str_EntsDefinitions, str_KW, str_ValKW); + //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; + + return res; +} + //int LoadDataAtBEMFormat::SpecificConversionOfContainsForSubFace(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName) //{ // //lire la liste des points et non contains // int res = 0; // // string str_Balise = str_ContainsName; // str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; // list > ::iterator it_llPt; // for (it_llPt = (st_IfcEnt->st_PointsDesContours).begin(); it_llPt != (st_IfcEnt->st_PointsDesContours).end(); it_llPt++) // { // list ::iterator it_lPt; // for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) // str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + std::to_string(*(*it_lPt)) + KW_R; // }// for (it_llPt = (st_IfcEnt->st_PointsDesContours).begin(); it_llPt != (st_IfcEnt->st_PointsDesContours).end(); it_llPt++) // str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; // // return res; //} // int LoadDataAtBEMFormat::ConvertIfcProject(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Projet; string str_ContainsName = "sites" /*+ _str_LESOSAI_Sites*/; string str_InsideContainsName = _str_LESOSAI_Site; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_ProjectsDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertIfcSite(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Site; string str_ContainsName = "buildings" /*+ _str_LESOSAI_Buildings*/; string str_InsideContainsName = _str_LESOSAI_Building; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_SitesDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertIfcBuilding(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Building; string str_ContainsName = "storeys" /*+ _str_LESOSAI_Storeys*/; string str_InsideContainsName = _str_LESOSAI_Storey; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_BuildingsDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertIfcBuildingStorey(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Storey; string str_ContainsName = "spaces" /*+ _str_LESOSAI_Spaces*/; string str_InsideContainsName = _str_LESOSAI_Space; //string str_ContainsName = "spaces"; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_BuildingStoreysDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertIfcSpace(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Space; string str_ContainsName = "geo" /*+ _str_LESOSAI_Polygons*/; string str_InsideContainsName = _str_LESOSAI_Polygon; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_SpacesDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertIfcFace(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Polygon; string str_ContainsName = "points" /*+ _str_LESOSAI_Points*/; string str_InsideContainsName = ""; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_FacesDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertTIFCSurface(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Surface; string str_ContainsName = ""; string str_InsideContainsName = ""; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_TIFCSurfacesDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertTIFCGeo2D(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Geo2D /*+ " (IfcConnectionSurfaceGeometry->SubFace)"*/; string str_ContainsName = "poly" /*+ _str_LESOSAI_Polygon*/; string str_InsideContainsName = _str_LESOSAI_Polygon ;//SubFace ConvertIfcEnt(st_IfcEnt, str_Balise, _str_TIFCGeo2DDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertIfcSubFace(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = _str_LESOSAI_Polygon;//"SubFace" string str_ContainsName = "points" /*+ _str_LESOSAI_Points*/;//"points" string str_InsideContainsName = ""; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_SubFacesDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = "IfcConnectionSurfaceGeometry"; string str_ContainsName = "contains"; string str_InsideContainsName = "SubFace"; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_ConnectionSurfaceGeometriesDefinitions, str_ContainsName, str_InsideContainsName); return res; } int LoadDataAtBEMFormat::ConvertIfcProductDefinitionShape(STRUCT_IFCENTITY *st_IfcEnt) { int res = 0; // Id, Name, Contains string str_Balise = "IfcProductDefinitionShape"; string str_ContainsName = "contains"; string str_InsideContainsName = ""; ConvertIfcEnt(st_IfcEnt, str_Balise, _str_ProductDefinitionShapesDefinitions, str_ContainsName, str_InsideContainsName); return res; } diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.h b/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.h index 4239089..c1a5454 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.h +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.h @@ -1,97 +1,102 @@ #pragma once #include "ifc_Tree.h" #include "ifc_TreePostTreatment.h" //typedef std::map Map_Basified_Tree; // class LoadDataAtBEMFormat { public: - LoadDataAtBEMFormat(); + LoadDataAtBEMFormat(double dbl_Minisurf); ~LoadDataAtBEMFormat(); int LoadLesosaiFormat(ifc_Tree* CurrentIfcTree); int GetLesosaiEntitiesNumber(); int GetLesosaiEntitiesAttributesSize(); int GetLesosaiEntitiesDefinition(string *&str_EntDef); + int GetLesosaiLogFile(string *&str_LogFile); int ConvertIfcProject(STRUCT_IFCENTITY *st_IfcEnt); int ConvertIfcSite(STRUCT_IFCENTITY *st_IfcEnt); int ConvertIfcBuilding(STRUCT_IFCENTITY *st_IfcEnt); int ConvertIfcBuildingStorey(STRUCT_IFCENTITY *st_IfcEnt); int ConvertIfcSpace(STRUCT_IFCENTITY *st_IfcEnt); int ConvertIfcProductDefinitionShape(STRUCT_IFCENTITY *st_IfcEnt); int ConvertTIFCSurface(STRUCT_IFCENTITY *st_IfcEnt); int ConvertTIFCGeo2D(STRUCT_IFCENTITY *st_IfcEnt); int ConvertIfcFace(STRUCT_IFCENTITY *st_IfcEnt); int ConvertIfcSubFace(STRUCT_IFCENTITY *st_IfcEnt); int ConvertIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *st_IfcEnt); int ConvertBasifiedTree(Map_Basified_Tree *&map_BasifTree); int SpecificConversionOfContains(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName); int SpecificConversionOfContainsBuilding(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName); int SpecificConversionOfContainsForSpace(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName); int SpecificConversionOfContainsForFaceAndSubFace(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName); //int SpecificConversionOfContainsForSubFace(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName); int SpecificConversionOfContainsForTIFCGeo2D(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName); int SpecificConversionOfContainsForConnectionSurfaceGeometry(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName, string str_FaceToFaceName = "FaceToFace", string str_Centroid = "Centroid", string str_SideBySideName = "SideBySide"); int SpecificConversionOfContainsForTIFCSurface(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName); + int SpecificConversionOfNorthProject(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions/*, string &str_ContainsName, string &str_InsideContainsName*/); int GenericConversion(STRUCT_IFCENTITY *&st_IfcEnt, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName); int ConvertIfcEnt(STRUCT_IFCENTITY *&st_IfcEnt, string &str_Balise, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName); //int BasifyTreeFrom(STRUCT_IFCENTITY *&st_IfcTree, Map_Basified_Tree &map_BasifTree); void OpenSets(); void CloseSets(); private: int LineForLevel(int &int_Level, string &str_EntsDefinitions, string &str_KW, string &str_ValKW); - // Compilation de toutes les entités (variable utilisée pour passer l'info au code appelant) - string *_str_EntitiesDefinitions; - // Compilation de toutes les entités d'un même type string _str_ProjectsDefinitions; string _str_SitesDefinitions; string _str_BuildingsDefinitions; string _str_BuildingStoreysDefinitions; string _str_SpacesDefinitions; string _str_FacesDefinitions; string _str_SubFacesDefinitions; string _str_ProductDefinitionShapesDefinitions; string _str_ConnectionSurfaceGeometriesDefinitions; string _str_TIFCSurfacesDefinitions; string _str_TIFCGeo2DDefinitions; // Initialisation des différents mots-clés lexicaux string _str_LESOSAI_SetsRoot = "bimbem"; //Root_Of_TIFCSets string _str_LESOSAI_ProjetsSet = "Set_Of_TIFCProjects"; string _str_LESOSAI_Projets = "TIFCProjects"; string _str_LESOSAI_Projet = "TIFCProject"; string _str_LESOSAI_SitesSet = "Set_Of_TIFCSites"; string _str_LESOSAI_Sites = "TIFCSites"; string _str_LESOSAI_Site = "TIFCSite"; string _str_LESOSAI_BuildingsSet = "Set_Of_TIFCBuildings"; string _str_LESOSAI_Buildings = "TIFCBuildings";string _str_LESOSAI_Building = "TIFCBuilding"; string _str_LESOSAI_StoreysSet = "Set_Of_TIFCStoreys"; string _str_LESOSAI_Storeys = "TIFCStoreys"; string _str_LESOSAI_Storey = "TIFCStorey"; string _str_LESOSAI_ZonesSet = "Set_Of_TIFCZones"; string _str_LESOSAI_Zones = "TIFCZones"; string _str_LESOSAI_Zone = "TIFCZone"; string _str_LESOSAI_SpacesSet = "Set_Of_TIFCSpaces"; string _str_LESOSAI_Spaces = "TIFCSpaces"; string _str_LESOSAI_Space = "TIFCSpace"; string _str_LESOSAI_SurfacesSet = "Set_Of_TIFCSurfaces"; string _str_LESOSAI_Surfaces = "TIFCSurfaces"; string _str_LESOSAI_Surface = "TIFCSurface"; string _str_LESOSAI_PolygonsSet = "Set_Of_TIFCPolygons"; string _str_LESOSAI_Polygons = "TIFCPolygons"; string _str_LESOSAI_Polygon = "TIFCPolygon"; string _str_LESOSAI_PointsSet = "Set_Of_TIFCPoints"; string _str_LESOSAI_Points = "TIFCPoints"; string _str_LESOSAI_Point = "TIFCPoint"; string _str_LESOSAI_Geo2DSet = "Set_Of_TIFCGeo2Ds"; string _str_LESOSAI_Geo2Ds = "TIFCGeo2Ds"; string _str_LESOSAI_Geo2D = "TIFCGeo2D"; // Initialisation des différents mots-clés grammaticaux string DEB_KW0_L = "<"; string DEB_KW1_L = "\t<"; string DEB_KW2_L = "\t\t<"; string DEB_KW3_L = "\t\t\t<"; string DEB_KW4_L = "\t\t\t\t<"; string KW_R = ">"; string KW_Rn = ">\n"; string KW1_Rn = "/>\n"; string FIN_KW0_L = "FirstChild("ex:uos"); //Chargement de toutes les entités du fichier xml dans un tableau de type "MAP": // _map_ID_Elmt["i1722"] = TiXmlElement *() int res = LoadIfcEntities(_hRoot); if (res != 0) return 1003;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine //Initialisation de la map _map_BE_Quantities // => Chargement de toutes les entités du fichier xml dans un tableau de type "MAP" associant à chaque élément de construction (IfcWallStandardCase, IfcSlab, ...) // leurs propriétés "IfcElementQuantity" (Length, Width, Height, GrossFootprintArea, ...): // _map_BE_Quantities[TiXmlElement * Buildingelemet] = TiXmlElement * IfcElementQuantity res = ScanIfcRelDefinesByPropertiesForQuantities(); if (res != 0) return 1004;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine //Recup de l'élément "IfcProject" pElem = _hRoot.FirstChild("IfcProject").ToElement(); // Constitution de l'arbre structure de données BIMxBEM _cl_ifcTree = new ifc_Tree(); if (_cl_ifcTree) res = _cl_ifcTree->BuildTreeFromRoot(pElem, this); return res; } // // La définition d'une entité se compose de lien direct (les attributs) et de liens indirects vers d'autres entités (les entités liées) // // Cette classe se décompose en 4 parties principales: // 1.0: Routines de base de lecture des attributs // 1.1: Routines spécifiques de lecture des attributs // 2.0: Routines de base de recherche des entités liés // 2.1: Routines de recherche par chemin "UN-aire" des entités liées // 2.2: Routines de recherche par chemin "MULTI-aire" des entités liées // 3.0: Routines de scan // // Pour chercher des entités depuis leur id => utiliser _map_ID_Elmt (si on a l'id) // Pour chercher des entités depuis leur ref => utiliser la routine FindObjectFromRef // Pour chercher des entités depuis leur nom de type ifc => utiliser routines de base du parser (par exemple "TiXmlHandle.Child(pKeyword1,..)") // ////////////////////////////////////////////////////////////////////////////////////// // 1.0) ROUTINES DE BASE DE LECTURE (DES ATTRIBUTS) DE LA DEFINITION D'UNE ENTITE // ////////////////////////////////////////////////////////////////////////////////////// // Lecture de tous les attributs enfants d'une entité // En quelque sorte, lecture des liens directs/constitutifs de la def qui ne soient pas des liens vers d'autres entités ifc (liens indirects) // Ce liens indirects sont associés avec un chemin de mots clés pour obtenir l'entité souhaitée => plutôt dans les routines "Find..." int ifcXML_File::ReadIdAndTypeOfAnEntity(TiXmlElement *pIfcEntity, Map_String_String &map_messages) { int res = 0; // Positionnement sur le 1er child de "IfcEntity" TiXmlHandle hLocalRoot(pIfcEntity); TiXmlElement *pElem = hLocalRoot.FirstChild().ToElement(); map_messages["Id"] = pIfcEntity->Attribute("id"); map_messages["Type"] = pIfcEntity->Value(); //lecture du contenu des children de "IfcEntity" for (pElem; pElem; pElem = pElem->NextSiblingElement()) { const char *pKey = pElem->Value(); const char *pText = pElem->GetText(); if (pKey && pText) { map_messages[pKey] = pText; }// if (pKey && pText) }// for (pElem; pElem; pElem = pElem->NextSiblingElement()) return res; } // Routines semblable à ReadIdAndTypeOfAnEntity (sans lecture de l'ID et du type) et surtout utilise en argument une liste plutôt que map car // le problème est que si les index du tableau "map" sont les mêmes (pour lecture des coordonnées par exemple) cela ecrase alors la précédente valeur int ifcXML_File::ReadAllValuesOfAnEntity(TiXmlElement *pIfcEntity, list &li_messages) { int res = 0; // Positionnement sur le 1er child de "IfcEntity" TiXmlHandle hLocalRoot(pIfcEntity); TiXmlElement *pElem = hLocalRoot.FirstChild().ToElement(); //lecture du contenu des children de "IfcEntity" for (pElem; pElem; pElem = pElem->NextSiblingElement()) { //const char *pKey = pElem->Value(); const char *pText = pElem->GetText(); if (/*pKey &&*/ pText) { li_messages.push_back(pText); }// if (pKey && pText) }// for (pElem; pElem; pElem = pElem->NextSiblingElement()) return res; } // Lecture d'un attribut enfant d'une entité int ifcXML_File::ReadOneSpecificValueOfAnEntity(TiXmlElement *pIfcEntity, string &st_Path, string &st_value) { int res = 0; // Positionnement sur le 1er child de "IfcEntity" TiXmlHandle hLocalRoot(pIfcEntity); TiXmlElement *pElem = hLocalRoot.FirstChild(st_Path.c_str()).ToElement(); //lecture du contenu des children de "IfcEntity" if(pElem) st_value = pElem->GetText(); return res; } ///////////////////////////////////////////////////////////////////////////////////////////// // 1.1) ROUTINES DE SPECIFIQUES DE LECTURE (DES ATTRIBUTS) DE LA DEFINITION D'UNE ENTITE // ///////////////////////////////////////////////////////////////////////////////////////////// +int ifcXML_File::ReadIfcDirectionVector(TiXmlElement *pElement, double Vector[3]) +{ + // + // Model + // 3 + // 1.000000000E-5 + // + // + // + // + // + // + // + + + string st_Path[2] = { "","" }; + int res = 0; + + //Axe North + st_Path[0] = "TrueNorth"; + st_Path[1] = "IfcDirection"; + TiXmlElement *lpObjectFound = nullptr; + res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObjectFound); + + TiXmlHandle hLocalBaseRoot3(lpObjectFound); + TiXmlHandle hLocalBaseRoot4(hLocalBaseRoot3.FirstChild("DirectionRatios")); + + //lecture du contenu des child d'un IfcEntity + list li_messages; + res = ReadAllValuesOfAnEntity(hLocalBaseRoot4.ToElement(), li_messages); + + // Remplissage Matrice + list ::iterator it_li_messages; + it_li_messages = li_messages.begin(); + Vector[0] = std::stod((*it_li_messages)); it_li_messages++; + Vector[1] = std::stod((*it_li_messages)); it_li_messages++; + if (it_li_messages == li_messages.end()) + { + Vector[2] = std::stod("0.0"); + }// if (it_li_messages == li_messages.end()) + else + { + Vector[2] = std::stod((*it_li_messages)); it_li_messages++; + }// else if (it_li_messages == li_messages.end()) + + return 0; +} + int ifcXML_File::ReadIfcAxis2Placement3DMatrix(TiXmlElement *pElement, double Matrix[3][4]) { // // // // // // // // // // // string st_Path[2] = { "","" }; int res = 0; //Origin { st_Path[0] = "Location"; st_Path[1] = "IfcCartesianPoint"; TiXmlElement *lpObjectFound = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObjectFound); TiXmlHandle hLocalBaseRoot3(lpObjectFound); TiXmlHandle hLocalBaseRoot4(hLocalBaseRoot3.FirstChild("Coordinates")); //lecture du contenu des child d'un IfcEntity liés à "IfcProject" list li_messages; res = ReadAllValuesOfAnEntity(hLocalBaseRoot4.ToElement(), li_messages); // Remplissage Matrice list ::iterator it_li_messages; it_li_messages = li_messages.begin(); Matrix[0][3] = std::stod((*it_li_messages)); it_li_messages++; Matrix[1][3] = std::stod((*it_li_messages)); it_li_messages++; Matrix[2][3] = std::stod((*it_li_messages)); it_li_messages++; } //Axe Z { st_Path[0] = "Axis"; st_Path[1] = "IfcDirection"; TiXmlElement *lpObjectFound = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObjectFound); TiXmlHandle hLocalBaseRoot3(lpObjectFound); TiXmlHandle hLocalBaseRoot4(hLocalBaseRoot3.FirstChild("DirectionRatios")); //lecture du contenu des child d'un IfcEntity liés à "IfcProject" list li_messages; res = ReadAllValuesOfAnEntity(hLocalBaseRoot4.ToElement(), li_messages); // Remplissage Matrice list ::iterator it_li_messages; it_li_messages = li_messages.begin(); Matrix[0][2] = std::stod((*it_li_messages)); it_li_messages++; Matrix[1][2] = std::stod((*it_li_messages)); it_li_messages++; Matrix[2][2] = std::stod((*it_li_messages)); it_li_messages++; } //Axe X { st_Path[0] = "RefDirection"; st_Path[1] = "IfcDirection"; TiXmlElement *lpObjectFound = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObjectFound); TiXmlHandle hLocalBaseRoot3(lpObjectFound); TiXmlHandle hLocalBaseRoot4(hLocalBaseRoot3.FirstChild("DirectionRatios")); - //lecture du contenu des child d'un IfcEntity liés à "IfcProject" + //lecture du contenu des child d'un IfcEntity list li_messages; res = ReadAllValuesOfAnEntity(hLocalBaseRoot4.ToElement(), li_messages); // Remplissage Matrice list ::iterator it_li_messages; it_li_messages = li_messages.begin(); Matrix[0][0] = std::stod((*it_li_messages)); it_li_messages++; Matrix[1][0] = std::stod((*it_li_messages)); it_li_messages++; Matrix[2][0] = std::stod((*it_li_messages)); it_li_messages++; } // The axis is the placement Z axis direction and the ref_direction is an approximation to the placement X axis direction. // 1ere colonne = « RefDirection » ; 2ème colonne = « Axis » X « RefDirection » ; 3ème colonne = « Axis » // Definition from IAI: If the attribute values for Axis and RefDirection are not given, // the placement defaults to P[1] (x-axis) as [1.,0.,0.], P[2] (y-axis) as [0.,1.,0.] and P[3] (z-axis) as [0.,0.,1.]. //Axe Y // QUESTION: Produit vectoriel zXx ? ou xXz ? Matrix[0][1] = Matrix[1][2] * Matrix[2][0] - Matrix[2][2] * Matrix[1][0]; Matrix[1][1] = Matrix[2][2] * Matrix[0][0] - Matrix[0][2] * Matrix[2][0]; Matrix[2][1] = Matrix[0][2] * Matrix[1][0] - Matrix[1][2] * Matrix[0][0]; //Normalisation de Axe Y: // Remarque: à priori x et z sont ortho et normalisés => pas nécessaire de normaliser y? double db_Norm = sqrt(Matrix[0][1] * Matrix[0][1] + Matrix[1][1] * Matrix[1][1] + Matrix[2][1] * Matrix[2][1]); Matrix[0][1] /= db_Norm; Matrix[1][1] /= db_Norm; Matrix[2][1] /= db_Norm; // //QUESTION: Faut-il orthogonaliser l'axe X (car "ref_direction is an approximation to the placement X axis direction")? // return 0; } int ifcXML_File::ReadKeyWordsAndValuesOfIfcElementQuantity(TiXmlElement *pIfcEntity, Map_String_String &m_messages) { // // Length // 10.07112391 // // // OU // // // NetFootprintArea // 4.028449566 // // // OU ... // int res = 0; //Recup de la definition geométrique (IfcQuantity) de l'entité en cours TiXmlElement* pIfcEntityQuant = _map_BE_Quantities[pIfcEntity]; //Lecture des attributs de la definition string st_Path = "Quantities"; list llpObject; res = FindAllLinkedObjectsFromFirstLinkPath(pIfcEntityQuant, st_Path, llpObject); //Boucle sur chaque attribut list ::iterator it_Elem; for (it_Elem = llpObject.begin(); it_Elem != llpObject.end(); it_Elem++) { // Positionnement sur le 1er child de "IfcEntity" TiXmlHandle hLocalRoot((*it_Elem)); TiXmlElement *pElem1 = hLocalRoot.FirstChild().ToElement(); if ((*it_Elem)) { TiXmlElement *pElem2 = pElem1->NextSiblingElement(); m_messages[pElem1->GetText()] = pElem2->GetText(); //m_messages[pElem1->Value()] = pElem2->Value(); }// if ((*it_Elem)) }// for (it_Elem = llpObject.begin(); it_Elem != llpObject.end(); it_Elem++) return res; } //////////////////////////////////////////////////////////////////////////////////////////// // 2.0) ROUTINES DE BASE DE RECHERCHE (DES ENTITES LIEES) DE LA DEFINITION D'UNE ENTITE // //////////////////////////////////////////////////////////////////////////////////////////// // Chargement en mémoire de tous les noeuds enfants de la racine => point d'entrée de toutes les entités ifc (de leur définition) // Permet une recherche optimisée des définitions des entités à partir de leur "ref" qui se fait par leur "Id" (en index de la map) => cf. FindObjectFromRef int ifcXML_File::LoadIfcEntities(TiXmlHandle &hroot) { int res = 0; int iInd = 0; TiXmlElement* pIfcEntity = hroot.Child(iInd).ToElement(); while (pIfcEntity) { _map_ID_Elmt[pIfcEntity->Attribute("id")] = pIfcEntity; iInd++; pIfcEntity = hroot.Child(iInd).ToElement(); }// while (pIfcEntity) return res; } // Recherche optimisée de la definition d'une entité référencé dans une autre entité (associé avec la routine LoadIfcEntities) int ifcXML_File::FindObjectFromRef(TiXmlElement *&RelatedElmt, TiXmlElement *&lpObject) { int res = 0; lpObject = _map_ID_Elmt[RelatedElmt->Attribute("ref")]; return res; } //Recherche d'une entité liée de type st_Path[1] sous le "lien" st_Path[0] int ifcXML_File::FindOneSpecificLinkedObjectFromFirstLinkPath(TiXmlElement *pElement, string st_Path[2], TiXmlElement *&lpObject) { // // // => lpObject lien vers sa def // // int res = 0; TiXmlHandle hLocalBaseRoot1(pElement); TiXmlHandle hLocalBaseRoot2(hLocalBaseRoot1.FirstChild(st_Path[0].c_str())); //Lecture du seul Specific object souhaité st_Path[1] TiXmlElement *lpObjectToSearch1 = hLocalBaseRoot2.FirstChild(st_Path[1].c_str()).ToElement(); res = FindObjectFromRef(lpObjectToSearch1, lpObject); return res; } //Recherche de toutes les entités liées de type st_Path[1] sous le "lien" st_Path[0] int ifcXML_File::FindSeveralSpecificLinkedObjectsFromFirstLinkPath(TiXmlElement *pElement, string st_Path[2], list &llpObject) { // // // => lpObject lien vers sa def // => pas recupéré dans lpObject // => lpObject lien vers sa def // // int res = 0; TiXmlHandle hLocalBaseRoot1(pElement); TiXmlHandle hLocalBaseRoot2(hLocalBaseRoot1.FirstChild(st_Path[0].c_str())); //Lecture de tous les Specific Object du type souhaité st_Path[1] int int_Index = 0; TiXmlElement *lpObjectToSearch1 = hLocalBaseRoot2.Child(st_Path[1].c_str(), int_Index).ToElement(); while (lpObjectToSearch1) { TiXmlElement *lpObject = nullptr; res = FindObjectFromRef(lpObjectToSearch1, lpObject); llpObject.push_back(lpObject); int_Index++; lpObjectToSearch1 = hLocalBaseRoot2.Child(st_Path[1].c_str(), int_Index).ToElement(); }// while (lpObjectToSearch1) return res; } //Recherche de toutes les entités liées (quelque soit le type ifc) sous le "lien" st_Path[0] int ifcXML_File::FindAllLinkedObjectsFromFirstLinkPath(TiXmlElement *pElement, string &st_Path, list &llpObject) { // // // => lpObject lien vers sa def // => lpObject lien vers sa def // => lpObject lien vers sa def // // int res = 0; TiXmlHandle hLocalBaseRoot1(pElement); TiXmlHandle hLocalBaseRoot2(hLocalBaseRoot1.FirstChild(st_Path.c_str())); //Lecture de tous les Specific Object [pas de type souhaité st_Path[1]] int int_Index = 0; TiXmlElement *lpObjectToSearch1 = hLocalBaseRoot2.Child(int_Index).ToElement(); while (lpObjectToSearch1) { TiXmlElement *lpObject = nullptr; res = FindObjectFromRef(lpObjectToSearch1, lpObject); llpObject.push_back(lpObject); int_Index++; lpObjectToSearch1 = hLocalBaseRoot2.Child(int_Index).ToElement(); }// while (lpObjectToSearch1) return res; } /////////////////////////////////////////////////////////////////////////////////////////////////// // 2.1) ROUTINES DE RECHERCHE EN LIEN UNAIRE (DES ENTITES LIEES) DE LA DEFINITION D'UNE ENTITE // /////////////////////////////////////////////////////////////////////////////////////////////////// int ifcXML_File::FindIfcCurveBoundedPlanePlacemcent(TiXmlElement *pElement, TiXmlElement *&lpObject) { //Pour IfcConnectionSurfaceGeometry => 1 Sous-Face // // // // // // // // // // // // // // // // // // // // // int res = 0; string st_Path[2] = { "","" }; st_Path[0] = "SurfaceOnRelatingElement"; st_Path[1] = "IfcCurveBoundedPlane"; TiXmlElement *lpObjectFound1 = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObjectFound1); st_Path[0] = "BasisSurface"; st_Path[1] = "IfcPlane"; TiXmlElement *lpObjectFound2 = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(lpObjectFound1, st_Path, lpObjectFound2); st_Path[0] = "Position"; st_Path[1] = "IfcAxis2Placement3D"; res = FindOneSpecificLinkedObjectFromFirstLinkPath(lpObjectFound2, st_Path, lpObject); return res; } int ifcXML_File::FindIfcGeometricRepresentationSubContext(TiXmlElement *pElement, TiXmlElement *&lpObject) { //Pour IfcProductDefinitionShape => n Faces // // // // // Body // Brep // // // // // // // Body // Model // // // // model_view // // // // Model // 3 // 1.000000000E-5 // // // // // => !! 2 ex:double-wrapper et non 3 // // int res = 0; string st_Path[2] = { "","" }; //ATTENTION "ContextOfItems" peut-il avoir plusieurs IfcGeometricRepresentationSubContext? // => multiplicité pas gérée par cette routine st_Path[0] = "ContextOfItems"; st_Path[1] = "IfcGeometricRepresentationSubContext"; TiXmlElement *lpObjectFound1 = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObjectFound1); st_Path[0] = "ParentContext"; st_Path[1] = "IfcGeometricRepresentationContext"; TiXmlElement *lpObjectFound2 = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(lpObjectFound1, st_Path, lpObjectFound2); st_Path[0] = "WorldCoordinateSystem"; st_Path[1] = "IfcAxis2Placement3D"; res = FindOneSpecificLinkedObjectFromFirstLinkPath(lpObjectFound2, st_Path, lpObject); return res; } int ifcXML_File::FindIfcGeometricRepresentationContext(TiXmlElement *pElement, TiXmlElement *&lpObject) { // // // // // - // - // - // - // - // - // - // - // - // int res = 0; string st_Path[2] = { "","" }; //ATTENTION "RepresentationContexts" peut avoir plusieurs IfcGeometricRepresentationContext // => multiplicité pas gérée par cette routine // A voir si nécessaire au niveau de ifcprojet seul usage de cette routine // => quel rôle des IfcGeometricRepresentationContext du ifcproject, est-ce seulement de rassembler les contextes? // => impliquerait ne pas appliquer (et de ne pas sauvegarder) matrice de position de ifcproject!!! // Pour les faces et sous-faces routine FindIfcGeometricRepresentationSubContext pourlaquelle il n'y a toujours qu'un seul contexte! st_Path[0] = "RepresentationContexts"; st_Path[1] = "IfcGeometricRepresentationContext"; - TiXmlElement *lpObjectFound1 = nullptr; - res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObjectFound1); + //TiXmlElement *lpObjectFound1 = nullptr; + res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObject); + + return res; +} + +int ifcXML_File::FindIfcAxis2Placement3D(TiXmlElement *pElement, TiXmlElement *&lpObject) +{ + // + // + // + // + // + // + // + // + + int res = 0; + string st_Path[2] = { "","" }; st_Path[0] = "WorldCoordinateSystem"; st_Path[1] = "IfcAxis2Placement3D"; - res = FindOneSpecificLinkedObjectFromFirstLinkPath(lpObjectFound1, st_Path, lpObject); + res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObject); return res; } int ifcXML_File::FindIfcLocalPlacement(TiXmlElement *pElement, TiXmlElement *&lpObject) { // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // int res = 0; string st_Path[2] = { "","" }; st_Path[0] = "ObjectPlacement"; st_Path[1] = "IfcLocalPlacement"; TiXmlElement *lpObjectFound1 = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElement, st_Path, lpObjectFound1); st_Path[0] = "RelativePlacement"; st_Path[1] = "IfcAxis2Placement3D"; res = FindOneSpecificLinkedObjectFromFirstLinkPath(lpObjectFound1, st_Path, lpObject); return res; } int ifcXML_File::FindIfcShapeRepresentationBrep(TiXmlElement *pElement, TiXmlElement *&lpObject) { //Pour IfcShapeRepresentation => n Faces // // // // // // // // // // // // FootPrint // GeometricCurveSet // // // // // // // // // // Body // Brep // // // // int res = 0; string st_Path = "Representations"; list llpObject; res = FindAllLinkedObjectsFromFirstLinkPath(pElement, st_Path, llpObject); list ::iterator it_l = llpObject.begin(); st_Path = "RepresentationType"; while (*(it_l)) { string st_Value=""; res = ReadOneSpecificValueOfAnEntity(*(it_l), st_Path, st_Value); if (st_Value == string("Brep")) { lpObject = *(it_l); break; }//if (lpObjectFound && string(ch_Reptype) == string("Brep")) it_l++; }// while (*(it_l)) return res; } /////////////////////////////////////////////////////////////////////////////////////////////////////// // 2.2) ROUTINES DE RECHERCHE EN LIEN MULTI-AIRE (DES ENTITES LIEES) DE LA DEFINITION D'UNE ENTITE // /////////////////////////////////////////////////////////////////////////////////////////////////////// int ifcXML_File::FindObjectFromRefAndPathBy3(TiXmlElement *&RelatedElmt, list::iterator &lst_Path, list::iterator &lst_PathEnd, list >> &lllpObject, list &lpObjectFace) { int res = 0; TiXmlHandle hLocalBaseRoot(RelatedElmt); if (lst_Path != lst_PathEnd) { const char* ch_Name = (*lst_Path).c_str(); int int_Ind = 0; TiXmlElement* lpObjectToSearch = hLocalBaseRoot.FirstChild(ch_Name).Child(int_Ind).ToElement(); while (lpObjectToSearch) { TiXmlElement* lpSearchedObject = nullptr; if (lpObjectToSearch) res = FindObjectFromRef(lpObjectToSearch, lpSearchedObject); // Pour IfcConnectionSurfaceGeometry // "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) // // Pour IfcShapeRepresentation // "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) // // Si le mot-clé a une multiplicité [1,m] => création d'une liste // Si c'est le Nième mot-clé multiple [1,m] => création d'une liste à 3-N profondeur "list on ajoute une liste de (3-1=2) niveaux (llxxx) //if (string(ch_Name) == string("CfsFaces")) // liste par CfsFace if (string(ch_Name) == string("Items") || string(ch_Name) == string("SurfaceOnRelatingElement")) // liste par Item, par SurfaceOnRelatingElement { //On descend au niveau N // => au 1er niveau c'est la liste passée en argument (lllpObject) pas d'action //On ajoute la liste de niveau 3-N list > llNewpObject; lllpObject.push_back(llNewpObject); } // Au 2nd mot clé "multiple" (N=2) => on ajoute une liste de (3-2=1) niveau (lxxx) if (string(ch_Name) == string("CfsFaces") || string(ch_Name) == string("OuterBoundary") || string(ch_Name) == string("InnerBoundaries")) // liste par CfsFace, par OuterBoundary/InnerBoundaries { //On descend au niveau N list >> ::iterator it_lll = lllpObject.end(); it_lll--; //On ajoute la liste de niveau 3-N list lNewpObject; (*it_lll).push_back(lNewpObject); } if (string(ch_Name) == string("CfsFaces") || string(ch_Name) == string("SurfaceOnRelatingElement")) // liste des Faces (pour CfsFaces) ou Subface (pour SurfaceOnRelatingElement) { //On ajoute la Face ou Sous-Face qui portera l'identifiant lpObjectFace.push_back(lpSearchedObject); } lst_Path++; res = FindObjectFromRefAndPathBy3(lpSearchedObject, lst_Path, lst_PathEnd, lllpObject, lpObjectFace); lst_Path--; int_Ind++; lpObjectToSearch = hLocalBaseRoot.FirstChild(ch_Name).Child(int_Ind).ToElement(); }// while (lpObjectToSearch) }// if (lst_Path != lst_PathEnd) else { //if (string(ch_Name) == string("Segments") || string(ch_Name) == string("Bounds")) // liste par Bound ou Segment => on rassemble en 1 liste car carac d'1 même face! // Au N=3ème multiple => on ajoute une liste de (3-3=0) niveau (xxx soit l'objet final) //On descend au niveau N list >> ::iterator it_lll = lllpObject.end(); it_lll--; list > ::iterator it_ll = (*it_lll).end(); it_ll--; //On ajoute la liste de niveau 3-N (pour N=3, c'est l'objet final) (*it_ll).push_back(RelatedElmt);// liste de Bounds (IfcFaceOuterBound) ou Segment }// else if (lst_Path != lst_PathEnd) return res; } int ifcXML_File::ReadPtsDefiningPolyloopOrPolyline(list &lPolyloopOfOneBound_Face, list> &FacePtsCoord) { // // // // // // // // // // // // // // // // // // // // // 9.672305351 // 6.511389214 // 2.67 // // int res = 0; // // Boucle sur les contours TiXmlElement* lpSearchedObject = nullptr; list ::iterator it_PolyloopOfOneBound; for (it_PolyloopOfOneBound = lPolyloopOfOneBound_Face.begin(); it_PolyloopOfOneBound != lPolyloopOfOneBound_Face.end(); it_PolyloopOfOneBound++) { list ContoursPtsCoord; TiXmlHandle hLocalBaseRoot((*it_PolyloopOfOneBound)); int int_ind = 0; TiXmlElement* pPointofPolyloop = hLocalBaseRoot.FirstChild().Child(int_ind).ToElement(); while (pPointofPolyloop) { if (pPointofPolyloop) res = FindObjectFromRef(pPointofPolyloop, lpSearchedObject); // TiXmlHandle hLocalBaseRoot1(lpSearchedObject); for (int i = 0; i < 3; i++) { TiXmlElement* pCoordPointofPolyloop = hLocalBaseRoot1.FirstChild().Child(i).ToElement(); //Lire IfcLengthMeasure; double *coord = nullptr; if (pCoordPointofPolyloop) coord = new double(stod(pCoordPointofPolyloop->GetText())); else coord = new double(0.0); ContoursPtsCoord.push_back(coord); }// for (int i = 0; i < 3; i++) // int_ind++; pPointofPolyloop = hLocalBaseRoot.FirstChild().Child(int_ind).ToElement(); }// while (pPointofPolyloop) FacePtsCoord.push_back(ContoursPtsCoord); }// for (it_PolyloopOfOneBound = (*it_BoundsOfOneCFsFace).begin(); it_PolyloopOfOneBound != (*it_BoundsOfOneCFsFace).end(); it_PolyloopOfOneBound++) return res; } int ifcXML_File::FindRepresentationInSpace(TiXmlElement* &pElemSpace, list *lpRelatedObjects) { // // // // // int res = 0; string st_Path[2] = { "","" }; //Retrouver l'IfcProductDefinitionShape st_Path[0] = "Representation"; st_Path[1] = "IfcProductDefinitionShape"; TiXmlElement *lpObjectFound = nullptr; res = FindOneSpecificLinkedObjectFromFirstLinkPath(pElemSpace, st_Path, lpObjectFound); if (lpRelatedObjects) lpRelatedObjects->push_back(lpObjectFound); return res; } int ifcXML_File::FindRelatedObjectsInRelAggregatesFromRelatingObject(TiXmlElement *&lpRelatingObj, list *lpRelatedObjects) { // => ATTENTION La multiplicite sous pKeyword2 n'est pas géré // // // // => ATTENTION: lpRelatingObj est en fait un lien vers def => l'entité est retrouvé si valeur de ref = valeur de id // // // => lpRelatedObjects lien vers sa def // => lpRelatedObjects lien vers sa def // => lpRelatedObjects lien vers sa def // // int res = 0; // Recherche de toutes les ifcentity de type pKeyword1 sur lesquelles se fait le scan const char* pKeyword1 = "IfcRelAggregates"; // Parmi les ifcentity de type pKeyword1 on ne s'interesse qu'à ceux qui ont l'entité lpRelatingObj en attribut pKeyword2 const char* pKeyword2 = "RelatingObject"; // Pour ces ifcentities de type pKeyword1 liées à lpRelatingObj on récupère les entités sous l'attribut pKeyword3 dans lpRelatedObjects const char* pKeyword3 = "RelatedObjects"; res = FindObjectsInRelFromRelatingEnt(lpRelatingObj, lpRelatedObjects, pKeyword1, pKeyword2, pKeyword3); return res; } int ifcXML_File::FindRelatedBuildingElementAndConnectionGeometryInRelSpaceBoundaryFromRelatingSpace(TiXmlElement *&lpRelatingObj, list *lpRelatedObjects, list *lpsecondRelatedObjects) { // => ATTENTION La multiplicite sous pKeyword2 n'est pas géré // // // // => ATTENTION: lpRelatingObj est en fait un lien vers def => l'entité est retrouvé si valeur de ref = valeur de id // // // => lpRelatedObjects lien vers sa def // => lpRelatedObjects lien vers sa def // => lpRelatedObjects lien vers sa def // // // => lpsecondRelatedObjects lien vers sa def // => lpsecondRelatedObjects lien vers sa def // => lpsecondRelatedObjects lien vers sa def // // int res = 0; // Recherche de toutes les ifcentity de type pKeyword1 sur lesquelles se fait le scan const char* pKeyword1 = "IfcRelSpaceBoundary"; // Parmi les ifcentity de type pKeyword1 on ne s'interesse qu'à ceux qui ont l'entité lpRelatingObj en attribut pKeyword2 const char* pKeyword2 = "RelatingSpace"; // Pour ces ifcentities de type pKeyword1 liées à lpRelatingObj on récupère les entités sous l'attribut pKeyword3 dans lpRelatedObjects const char* pKeyword3 = "RelatedBuildingElement"; // Parallèlement, pour ces ifcentities de type pKeyword1 liées à lpRelatingObj on récupère les entités sous l'attribut pKeyword4 dans lpsecondRelatedObjects const char* pKeyword4 = "ConnectionGeometry"; res = FindObjectsInRelFromRelatingEnt(lpRelatingObj, lpRelatedObjects, pKeyword1, pKeyword2, pKeyword3, pKeyword4, lpsecondRelatedObjects); return res; } int ifcXML_File::FindObjectsInRelFromRelatingEnt(TiXmlElement *&lpRelatingObj, list *lpRelatedObjects, const char* pKeyword1, const char* pKeyword2, const char* pKeyword3, const char* pKeyword4, list *lpsecondRelatedObjects) { // => ATTENTION La multiplicite sous pKeyword2 n'est pas géré // // // // => ATTENTION: lpRelatingObj est en fait un lien vers def => l'entité est retrouvé si valeur de ref = valeur de id // // // => lpRelatedObjects lien vers sa def // => lpRelatedObjects lien vers sa def // => lpRelatedObjects lien vers sa def // // // // OU [les arguments pKeyword4 et lpsecondRelatedObjects sont optionnels] // // // // => ATTENTION: lpRelatingObj est en fait un lien vers def => l'entité est retrouvé si valeur de ref = valeur de id // // // => lpRelatedObjects lien vers sa def // => lpRelatedObjects lien vers sa def // => lpRelatedObjects lien vers sa def // // // => lpsecondRelatedObjects lien vers sa def // => lpsecondRelatedObjects lien vers sa def // => lpsecondRelatedObjects lien vers sa def // // int res = 0; TiXmlHandle hLocalBaseRoot(_hRoot); std::string str_SearchedID(lpRelatingObj->Attribute("id")); int int_nbcount = 0; bool boo_IsItTheEnd = false; while (!boo_IsItTheEnd) { // Pour une recherche à partir du nom d'entité, // à priori le plus optimisé est d'utiliser les routines de base du parser: "TiXmlHandle.Child(pKeyword1,..)" TiXmlHandle hLocalVariableRoot1(hLocalBaseRoot.Child(pKeyword1, int_nbcount));//"IfcRelAggregates", "IfcRelSpaceBoundary" TiXmlHandle hLocalVariableRoot2(hLocalVariableRoot1.FirstChild(pKeyword2));//"RelatingObject", "RelatingSpace" TiXmlHandle hLocalVariableRoot3(hLocalVariableRoot2.FirstChild(/*"IfcProject"*/)); if (nullptr != hLocalVariableRoot3.ToElement()) { //DEB: A REVOIR en terme de perfo si judicieux d'utiliser le _map_ID_Elmt plutôt que // comparaison de string std::string str_SearchedID(lpRelatingObj->Attribute("id")) en dehors boucle puis if (str_SearchedID == std::string(ch_ID)) //FIN: //if (_map_ID_Elmt[lpRelatingObj->Attribute("id")]== _map_ID_Elmt[hLocalVariableRoot3.ToElement()->Attribute("ref")]) if (str_SearchedID == std::string(hLocalVariableRoot3.ToElement()->Attribute("ref"))) { if (pKeyword3) { //Recup des entités sous pKeyword3 TiXmlHandle hLocalVariableRoot4(hLocalVariableRoot1.FirstChild(pKeyword3));//"RelatedObjects", "RelatedBuildingElement" int int_Index = 0; TiXmlElement *RelatedElmt = hLocalVariableRoot4.Child(int_Index).ToElement(); while (RelatedElmt) { // Recuperation de la def de l'élément dont la ref est RelatedElmt TiXmlElement *RelatedElmt2 = nullptr; res = FindObjectFromRef(RelatedElmt, RelatedElmt2); if (lpRelatedObjects) lpRelatedObjects->push_back(RelatedElmt2); int_Index++; RelatedElmt = hLocalVariableRoot4.Child(int_Index).ToElement(); }// while (RelatedElmt) }// if(pKeyword3) if (pKeyword4) { //Recup des entités sous pKeyword4 //A REVOIR... Attention à voir comment ca marche s il y a plusieurs "RelatingObject", "RelatingSpace" pour généraliser la routine TiXmlHandle hLocalVariableRoot4(hLocalVariableRoot1.FirstChild(pKeyword4));//"ConnectionGeometry" int int_Index = 0; TiXmlElement *RelatedElmt = hLocalVariableRoot4.Child(int_Index).ToElement(); while (RelatedElmt) { // Recuperation de la def de l'élément dont la ref est RelatedElmt TiXmlElement *RelatedElmt2 = nullptr; res = FindObjectFromRef(RelatedElmt, RelatedElmt2); if (lpsecondRelatedObjects) lpsecondRelatedObjects->push_back(RelatedElmt2); int_Index++; RelatedElmt = hLocalVariableRoot4.Child(int_Index).ToElement(); }// while (RelatedElmt) }// if(pKeyword4) }// if (nullptr != ch_ID && str_SearchedID == std::string(ch_ID)) int_nbcount++; }// if (nullptr != hLocalVariableRoot3.ToElement()) else boo_IsItTheEnd = true; }//while (!boo_IsItFound) return res; } //////////////////////////////////////////////////////////////////////////////////////////// // 3.0) ROUTINES DE BASE POUR UN SCAN GLOBAL (SANS RECHERCHE D'UNE ENTITE SPECIFIQUE) // //////////////////////////////////////////////////////////////////////////////////////////// int ifcXML_File::ScanAssociateRelatedAndRelatingEnt(const char* pKeyword1, const char* pKeyword2, const char* pKeyword3, const char* pKeyword4) { // => ATTENTION La multiplicite sous pKeyword2 est gérée, mais suppose l'unicité sous pKeyword3 // // => IfcRelDefinesByProperties // => RelatedObjects // => ATTENTION: lpRelatingObj est en fait un lien vers def => l'entité est retrouvé si valeur de ref = valeur de id // => ATTENTION: lpRelatingObj est en fait un lien vers def => l'entité est retrouvé si valeur de ref = valeur de id // // => RelatingPropertyDefinition ATTENTION multiplicité pas gérée // => lpRelatedObjects lien vers sa def => IfcElementQuantity // // // int res = 0; TiXmlHandle hLocalBaseRoot(_hRoot); //std::string str_SearchedID(lpRelatingObj->Attribute("id")); int int_nbcount = 0; TiXmlHandle hNullHandle=nullptr; TiXmlHandle hLocalVariableRoot1(hLocalBaseRoot.Child(pKeyword1, int_nbcount));//"IfcRelDefinesByProperties" //bool boo_IsItTheEnd = false; //while (!boo_IsItTheEnd) while (hLocalVariableRoot1.ToNode() != nullptr) { // Pour une recherche à partir du nom d'entité, // à priori le plus optimisé est d'utiliser les routines de base du parser: "TiXmlHandle.Child(pKeyword1,..)" TiXmlHandle hLocalVariableRoot2(hLocalVariableRoot1.FirstChild(pKeyword2));//"RelatingPropertyDefinition" TiXmlElement *RelatingElmt = hLocalVariableRoot2.Child(0).ToElement(); if (nullptr != RelatingElmt) { if (string(RelatingElmt->Value()) == string(pKeyword3)) //"IfcElementQuantity" { // Recuperation de la def de l'élément dont la ref est RelatingElmt TiXmlElement *RelatingElmt2 = nullptr; res = FindObjectFromRef(RelatingElmt, RelatingElmt2); TiXmlHandle hLocalVariableRoot3(hLocalVariableRoot1.FirstChild(pKeyword4));//"RelatedObjects" int int_Index = 0; TiXmlElement *RelatedElmt = hLocalVariableRoot3.Child(int_Index).ToElement(); while (RelatedElmt) { // Recuperation de la def de l'élément dont la ref est RelatedElmt TiXmlElement *RelatedElmt2 = nullptr; res = FindObjectFromRef(RelatedElmt, RelatedElmt2); _map_BE_Quantities[RelatedElmt2] = RelatingElmt2;// pIfcEntity->Attribute("id"); int_Index++; RelatedElmt = hLocalVariableRoot3.Child(int_Index).ToElement(); }// while (RelatedElmt) }// if (hLocalVariableRoot3.ToElement()->Value() == pKeyword3) }// if (nullptr != RelatingElmt) int_nbcount++; hLocalVariableRoot1=hLocalBaseRoot.Child(pKeyword1, int_nbcount);//"IfcRelDefinesByProperties" }//while (hLocalVariableRoot1) // }// if (nullptr != hLocalVariableRoot3.ToElement()) // else // boo_IsItTheEnd = true; //}//while (!boo_IsItFound) return res; } int ifcXML_File::ScanIfcRelDefinesByPropertiesForQuantities() { // // 1JljiXweR195uhzlxzvQeN // // // // // // // // // // // // OU // // // 1ctrdyLJ_$SL9WtGdfK2n1 // // // // // // // // // // int res = 0; // Recherche de toutes les ifcentity de type pKeyword1 sur lesquelles se fait le scan const char* pKeyword1 = "IfcRelDefinesByProperties"; // Parmi les ifcentity de type pKeyword1 on ne s'interesse qu'à ceux qui ont l'entité "RelatingPropertyDefinition" en attribut pKeyword2 // et comme sous-type "IfcElementQuantity" en attribut pKeyword3 const char* pKeyword2 = "RelatingPropertyDefinition"; const char* pKeyword3 = "IfcElementQuantity"; // Pour ces ifcentities de type pKeyword1 liées à "RelatingPropertyDefinition"->"IfcElementQuantity" on récupère les entités sous l'attribut pKeyword4 dans "RelatedObjects" const char* pKeyword4 = "RelatedObjects"; // Chargement en mémoire de toutes les associations => _map_BE_Quantities[TiXmlElement "BuildingElement"]=TiXmlElement "IfcElementQuantity" // Permet une recherche optimisée des définitions des entités à partir de leur "ref" qui se fait par leur "Id" (en index de la map) => cf. FindObjectFromRef res = ScanAssociateRelatedAndRelatingEnt(pKeyword1, pKeyword2, pKeyword3, pKeyword4); return res; } diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.h index 4cbf8fe..c5e49d5 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.h +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.h @@ -1,61 +1,63 @@ #pragma once #include #include using namespace std; #include "tinyxml.h" #include "ifc_Tree.h" #include //typedef std::map Map_String_String; typedef std::map Map_String_ptrTiXmlElement; typedef std::map Map_ptrTiXmlElement_ptrTiXmlElement; class ifcXML_File { public: ifcXML_File(); ~ifcXML_File(); int LoadFile(char *strFileName); int LoadIfcEntities(TiXmlHandle &hroot); int FindRelatedBuildingElementAndConnectionGeometryInRelSpaceBoundaryFromRelatingSpace(TiXmlElement* &lpRelatingObj, list *lpRelatedObjects, list *lpsecondRelatedObjects); int FindRelatedObjectsInRelAggregatesFromRelatingObject(TiXmlElement* &lpRelatingObj, list *lpRelatedObjects); int FindRepresentationInSpace(TiXmlElement* &pElem, list *lpRelatedObjects); int FindObjectsInRelFromRelatingEnt(TiXmlElement* &lpRelatingObj, list *lpRelatedObjects, const char* pKeyword1, const char* pKeyword2, const char* pKeyword3, const char* pKeyword4 = nullptr, list *lpsecondRelatedObjects = nullptr); int FindObjectFromRef(TiXmlElement* &RelatedElmt, TiXmlElement* &lpObject); //int FindObjectFromRefAndPath(TiXmlElement* &RelatedElmt, list::iterator &lst_PathBegin, list::iterator &lst_PathEnd, list &lpObject); int FindObjectFromRefAndPathBy3(TiXmlElement* &RelatedElmt, list::iterator &lst_Path, list::iterator &lst_PathEnd, list >> &lllpObject, list &lpObjectFace); int ScanAssociateRelatedAndRelatingEnt(const char* pKeyword1, const char* pKeyword2, const char* pKeyword3, const char* pKeyword4 = nullptr); int ScanIfcRelDefinesByPropertiesForQuantities(); int FindOneSpecificLinkedObjectFromFirstLinkPath(TiXmlElement* pElement, string st_Path[2], TiXmlElement* &lpObject); int FindSeveralSpecificLinkedObjectsFromFirstLinkPath(TiXmlElement* pElement, string st_Path[2], list &lpObject); int FindAllLinkedObjectsFromFirstLinkPath(TiXmlElement* pElement, string &st_Path, list &lpObject); int FindIfcLocalPlacement(TiXmlElement* pElement, TiXmlElement* &lpObject); + int FindIfcAxis2Placement3D(TiXmlElement* pElement, TiXmlElement* &lpObject); int FindIfcGeometricRepresentationContext(TiXmlElement* pElement, TiXmlElement* &lpObject); int FindIfcGeometricRepresentationSubContext(TiXmlElement* pElement, TiXmlElement* &lpObject); int FindIfcCurveBoundedPlanePlacemcent(TiXmlElement* pElement, TiXmlElement* &lpObject); int FindIfcShapeRepresentationBrep(TiXmlElement* pElement, TiXmlElement* &lpObject); int ReadOneSpecificValueOfAnEntity(TiXmlElement *pIfcEntity, string &st_Path, string &st_value); int ReadIdAndTypeOfAnEntity(TiXmlElement* pElement, Map_String_String &m_messages); int ReadAllValuesOfAnEntity(TiXmlElement* pIfcEntity, list &li_messages); int ReadIfcAxis2Placement3DMatrix(TiXmlElement* pElement, double Matrix[3][4]); + int ReadIfcDirectionVector(TiXmlElement* pElement, double Vector[3]); int ReadPtsDefiningPolyloopOrPolyline(list &llBoundsOfOneCFsFace_Face, list> &FacePtsCoord); int ReadKeyWordsAndValuesOfIfcElementQuantity(TiXmlElement* pElement, Map_String_String &m_messages); ifc_Tree* GetData(); private: TiXmlHandle _hRoot; Map_String_ptrTiXmlElement _map_ID_Elmt; ifc_Tree *_cl_ifcTree; Map_ptrTiXmlElement_ptrTiXmlElement _map_BE_Quantities; }; diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.cpp index 241a152..91741f6 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.cpp +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.cpp @@ -1,64 +1,73 @@ // // /////////////////////////////////////////////////// // INTERFACES A APPELER DEPUIS LE CODE "EXTERNE" // /////////////////////////////////////////////////// // // #include "ifc_BIMxBEMEngine.h" #include #include #include #include "ifcXML_File.h" #include "LoadDataAtBEMFormat.h" ifcXML_File *_iFile=nullptr; LoadDataAtBEMFormat* _iLesosaiFormat =nullptr; int __stdcall ifcxml_BIMxBEMEPFL_LoadXMLFileForBEM(char *chr_FilePath) { int res = 0; // //Chargement en mémoire d'une structure générique de données typés BEM (optimisée pour modification) _iFile = new ifcXML_File(); res = _iFile->LoadFile(chr_FilePath); return res; } void __stdcall ifcxml_BIMxBEMEPFL_UnLoadXMLFileForBEM() { // //Desalloc des données membres ifc_BIMxBEMEngine if (_iFile) delete _iFile; _iFile = nullptr; return; } //Fournit la structure dans une chaine de caractères -int __stdcall ifcxml_BIMxBEMEPFL_GetEntitiesDefinition(const char *&chr_EntDef) +int __stdcall ifcxml_BIMxBEMEPFL_GetEntitiesDefinition(const char *&chr_EntDef, const char *&chr_Logfile, double dbl_Minisurf) //Surface mini vue comme nulle pour Lesosai { int res = 0; // //Conversion de la structure générique de données typés BEM (optimisée pour modification) au format attendu par Lesosai - _iLesosaiFormat = new LoadDataAtBEMFormat(); + _iLesosaiFormat = new LoadDataAtBEMFormat(dbl_Minisurf); res = _iLesosaiFormat->LoadLesosaiFormat(_iFile->GetData()); if (res) return res; //Lecture de la structure Lesosai sous forme de string *str_EntDef = nullptr; res = _iLesosaiFormat->GetLesosaiEntitiesDefinition(str_EntDef); if (res) return res; //Conversion string en const char* if (str_EntDef) chr_EntDef=str_EntDef->c_str(); + //Lecture de la Log + string *str_LogFile = nullptr; + res = _iLesosaiFormat->GetLesosaiLogFile(str_LogFile); + if (res) return res; + + //Conversion string en const char* + if (str_LogFile) + chr_Logfile = str_LogFile->c_str(); + return res; } diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.h index 47c9757..e0a89a3 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.h +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.h @@ -1,28 +1,28 @@ // // /////////////////////////////////////////////////// // INTERFACES A APPELER DEPUIS LE CODE "EXTERNE" // /////////////////////////////////////////////////// // // #pragma once #ifndef __HEADER__IFC_BIMxBEMEPFLENGINE__ #define __HEADER__IFC_BIMxBEMEPFLENGINE__ #endif #include using namespace std; #ifdef __cplusplus extern "C" { #endif __declspec(dllexport) int __stdcall ifcxml_BIMxBEMEPFL_LoadXMLFileForBEM(char *chr_FilePath); __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_UnLoadXMLFileForBEM(); - __declspec(dllexport) int __stdcall ifcxml_BIMxBEMEPFL_GetEntitiesDefinition(const char *&chr_EntDef); + __declspec(dllexport) int __stdcall ifcxml_BIMxBEMEPFL_GetEntitiesDefinition(const char *&chr_EntDef, const char *&chr_Logfile, double dbl_Minisurf); //Surface mini vue comme nulle pour Lesosai #ifdef __cplusplus } #endif diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.cpp index 15dcb5b..baa8f33 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.cpp +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.cpp @@ -1,347 +1,353 @@ #include "ifc_Tree.h" - ifc_Tree::ifc_Tree(): _st_IfcTree(nullptr) { } ifc_Tree::~ifc_Tree() { // //Desalloc des données membres de ifc_Tree if (_st_IfcTree) delete_STRUCT_IFCENTITY(_st_IfcTree); _st_IfcTree = nullptr; } STRUCT_IFCENTITY *&ifc_Tree::Getstruct() { return _st_IfcTree; } void ifc_Tree::delete_STRUCT_IFCENTITY(STRUCT_IFCENTITY* &st_IfcTree, STRUCT_IFCENTITY* st_IfcCurrentFather) { // //Descente dans l'arborescence jusqu'aux élément sans enfants (membre "st_Contains" vide) list ::iterator it_Elem; for (it_Elem = (st_IfcTree->st_Contains).begin(); it_Elem != (st_IfcTree->st_Contains).end(); it_Elem++) { if ((*it_Elem)) delete_STRUCT_IFCENTITY((*it_Elem), st_IfcTree); }// for (it_Elem = (st_IfcTree->st_Contains).begin(); it_Elem != (st_IfcTree->st_Contains).end(); it_Elem++) st_IfcTree->st_Contains.clear(); // //Désallocations effectives // delete[] st_IfcTree->ch_GlobalId; st_IfcTree->ch_GlobalId = nullptr; delete[] st_IfcTree->ch_Id; st_IfcTree->ch_Id = nullptr; delete[] st_IfcTree->ch_Name; st_IfcTree->ch_Name = nullptr; delete[] st_IfcTree->ch_Type; st_IfcTree->ch_Type = nullptr; delete st_IfcTree->map_DefValues; st_IfcTree->map_DefValues = nullptr; list::iterator it_l_Points; for (it_l_Points = (st_IfcTree->db_RelativePlacement).begin(); it_l_Points != (st_IfcTree->db_RelativePlacement).end(); it_l_Points++) { delete (*it_l_Points); *it_l_Points = nullptr; }// for (it_l_Points = (st_IfcTree->db_RelativePlacement).begin(); it_l_Points != (st_IfcTree->db_RelativePlacement).end(); it_l_Points++) st_IfcTree->db_RelativePlacement.clear(); for (it_l_Points = (st_IfcTree->db_Centroid).begin(); it_l_Points != (st_IfcTree->db_Centroid).end(); it_l_Points++) { delete (*it_l_Points); *it_l_Points = nullptr; }// for (it_l_Points = (st_IfcTree->db_RelativePlacement).begin(); it_l_Points != (st_IfcTree->db_RelativePlacement).end(); it_l_Points++) st_IfcTree->db_RelativePlacement.clear(); list >::iterator it_ll_Points; for (it_ll_Points = (st_IfcTree->st_PointsDesContours).begin(); it_ll_Points != (st_IfcTree->st_PointsDesContours).end(); it_ll_Points++) { for (it_l_Points = (*it_ll_Points).begin(); it_l_Points != (*it_ll_Points).end(); it_l_Points++) { delete (*it_l_Points); *it_l_Points = nullptr; }// for (it_l_Points = (*it_ll_Points).begin(); it_l_Points != (*it_ll_Points).end(); it_l_Points++) // (*it_ll_Points).clear(); }// for (it_ll_Points = (st_IfcTree->st_PointsDesContours).begin(); it_ll_Points != (st_IfcTree->st_PointsDesContours).end(); it_ll_Points++) st_IfcTree->st_PointsDesContours.clear(); // // Nettoyage des listes référencant l'objet que l'on est en train de détruire // Pour les liens non binaires (ternaires ou plus) la structure en cours d'effacement (st_IfcTree) est référencée dans les Contains de plusieurs pères // Afin déviter un crash mémoire par la désallocation d'une structure déjà détruite, il faut déréférencer la structure // en cours d'effacement des listes de BelongsTo des autres pères (que celui en cours = st_IfcCurrentFather) // Exemple: IfcConnectionSurfaceGeometry est référencé à la fois dans le st_Contains de IfSpace et des BuildingElements (IfcWall,...) list ::iterator it_ElemInBelong; for (it_ElemInBelong = (st_IfcTree->st_BelongsTo).begin(); it_ElemInBelong != (st_IfcTree->st_BelongsTo).end(); it_ElemInBelong++) { if ((*it_ElemInBelong) != st_IfcCurrentFather) { list ::iterator it_ElemInBelongContains; for (it_ElemInBelongContains = ((*it_ElemInBelong)->st_Contains).begin(); it_ElemInBelongContains != ((*it_ElemInBelong)->st_Contains).end(); it_ElemInBelongContains++) { if ((*it_ElemInBelongContains) == st_IfcTree) { (*it_ElemInBelong)->st_Contains.erase(it_ElemInBelongContains); break; }// if ((*it_ElemInBelongContains) == st_IfcTree) }// for (it_ElemInBelongContains = ((*it_ElemInBelong)->st_Contains).begin(); it_ElemInBelongContains != ((*it_ElemInBelong)->st_Contains).end(); it_ElemInBelongContains++) }// if ((*it_ElemInBelong) != st_IfcCurrentFather) }// for (it_ElemInBelong = (st_IfcTree->st_BelongsTo).begin(); it_ElemInBelong != (st_IfcTree->st_BelongsTo).end(); it_ElemInBelong++) st_IfcTree->st_BelongsTo.clear(); //La liste st_FaceToFace référence des objets désalloués par ailleurs, du coup pas d'action de désallocation spécifique //TIFCSurface list ::iterator it_ElemInTIFCSurfaceContain; if (st_IfcTree->st_TIFCSurface) { for (it_ElemInTIFCSurfaceContain = (st_IfcTree->st_TIFCSurface->st_Contains).begin(); it_ElemInTIFCSurfaceContain != (st_IfcTree->st_TIFCSurface->st_Contains).end(); it_ElemInTIFCSurfaceContain++) { if ((*it_ElemInTIFCSurfaceContain) != st_IfcTree) { //(*it_ElemInTIFCSurfaceContain)->st_TIFCSurface.clear(); (*it_ElemInTIFCSurfaceContain)->st_TIFCSurface = nullptr; break; }// if ((*it_ElemInTIFCSurfaceContain) != st_IfcTree) }// for (it_ElemInTIFCSurfaceContain = (st_IfcTree->st_TIFCSurface->st_Contains).begin(); it_ElemInTIFCSurfaceContain != (st_IfcTree->st_TIFCSurface->st_Contains).end(); it_ElemInTIFCSurfaceContain++) delete st_IfcTree->st_TIFCSurface; st_IfcTree->st_TIFCSurface = nullptr; }// if (st_IfcTree->st_TIFCSurface) delete st_IfcTree; st_IfcTree = nullptr; } void ifc_Tree::FillAttributeOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, Map_String_String &map_messages, double db_LocalMat[3][4], STRUCT_IFCENTITY *st_IfcBelongTo, STRUCT_IFCENTITY *st_IfcBelongTo2) { //la structure st_IfcTree est celle que l'on initialise/renseigne dans cette routine //les structure st_IfcBelongTo est un pere de st_IfcTree (=> vient de la relation binaire ifcRelAggregates) //les structure st_IfcBelongTo2 est un 2nd père de st_IfcTree (=> vient de la relation ternaire IfcRelSpaceBoundary) if (st_IfcTree) { // Pour les tailles: http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ FillNameAndIDAttributeOf_STRUCT_IFCENTITY(st_IfcTree, map_messages); if (st_IfcBelongTo) { st_IfcTree->st_BelongsTo.push_back(st_IfcBelongTo); st_IfcBelongTo->st_Contains.push_back(st_IfcTree); }// if (st_IfcBelongTo) if (st_IfcBelongTo2) { st_IfcTree->st_BelongsTo.push_back(st_IfcBelongTo2); st_IfcBelongTo2->st_Contains.push_back(st_IfcTree); }// if (st_IfcBelongTo) FillRelativePlacementOf_STRUCT_IFCENTITY(st_IfcTree, db_LocalMat); }// if (st_IfcTree) } void ifc_Tree::FillAttributeOfExisting_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, Map_String_String &map_messages, double db_LocalMat[3][4], STRUCT_IFCENTITY *st_IfcBelongTo, STRUCT_IFCENTITY *st_IfcBelongTo2) { //la structure st_IfcTree est celle que l'on initialise/renseigne dans cette routine //les structure st_IfcBelongTo est un pere de st_IfcTree (=> vient de la relation binaire ifcRelAggregates) //les structure st_IfcBelongTo2 est un 2nd père de st_IfcTree (=> vient de la relation ternaire IfcRelSpaceBoundary) if (st_IfcTree) { if (st_IfcBelongTo) { //Faire boucle pour tester existence du pointeur list ::iterator it_Elem; bool bo_IsItInList = false; for (it_Elem = (st_IfcTree->st_BelongsTo).begin(); it_Elem != (st_IfcTree->st_BelongsTo).end(); it_Elem++) { if ((*it_Elem) == st_IfcBelongTo) { bo_IsItInList = true; break; }// if ((*it_Elem) == st_IfcBelongTo) }// for (it_Elem = (st_IfcTree->st_BelongsTo).begin(); it_Elem != (st_IfcTree->st_BelongsTo).end(); it_Elem++) if (!bo_IsItInList) st_IfcTree->st_BelongsTo.push_back(st_IfcBelongTo); bo_IsItInList = false; for (it_Elem = (st_IfcBelongTo->st_Contains).begin(); it_Elem != (st_IfcBelongTo->st_Contains).end(); it_Elem++) { if ((*it_Elem) == st_IfcTree) { bo_IsItInList = true; break; }// if ((*it_Elem) == st_IfcBelongTo) }// for (it_Elem = (st_IfcBelongTo->st_Contains).begin(); it_Elem != (st_IfcBelongTo->st_Contains).end(); it_Elem++) if (!bo_IsItInList) st_IfcBelongTo->st_Contains.push_back(st_IfcTree); }// if (st_IfcBelongTo) }// if (st_IfcTree) } void ifc_Tree::FillNameAndIDAttributeOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, Map_String_String &map_messages) { // Pour les tailles: http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ char *ch_copy22 = new char[23];//size+1 pour que strncpy mette'\0' strncpy(ch_copy22, map_messages["GlobalId"].c_str(), 23); st_IfcTree->ch_GlobalId = ch_copy22; if (map_messages.count("LongName")) { char *ch_copy255 = new char[256];//size+1 pour que strncpy mette'\0' strncpy(ch_copy255, map_messages["LongName"].c_str(), 256); st_IfcTree->ch_Name = ch_copy255; } else { char *ch_copy255 = new char[256];//size+1 pour que strncpy mette'\0' strncpy(ch_copy255, map_messages["Name"].c_str(), 256); st_IfcTree->ch_Name = ch_copy255; }// else if (map_messages.count("LongName")) char *ch_copy9 = new char[16];//size+1 pour que strncpy mette'\0' strncpy(ch_copy9, map_messages["Id"].c_str(), 16); st_IfcTree->ch_Id = ch_copy9; char *ch_copy55 = new char[56];//size+1 pour que strncpy mette'\0' strncpy(ch_copy55, map_messages["Type"].c_str(), 56); st_IfcTree->ch_Type = ch_copy55; + + if (map_messages.count("PredefinedType")) + { + char *ch_copy55 = new char[56];//size+1 pour que strncpy mette'\0' + strncpy(ch_copy55, map_messages["PredefinedType"].c_str(), 56); + st_IfcTree->ch_PredifinedType = ch_copy55; + }// if (map_messages.count("PredefinedType")) } void ifc_Tree::FillRelativePlacementOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, double db_LocalMat[3][4]) { //la structure st_IfcTree est celle que l'on initialise/renseigne dans cette routine //les structure st_IfcBelongTo est un pere de st_IfcTree (=> vient de la relation binaire ifcRelAggregates) //les structure st_IfcBelongTo2 est un 2nd père de st_IfcTree (=> vient de la relation ternaire IfcRelSpaceBoundary) if (st_IfcTree) { // Pour les tailles: http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ if (db_LocalMat) { for (int i_col = 0; i_col < 4; i_col++) { for (int i_lin = 0; i_lin < 3; i_lin++) { double *db_Val = new double(); *db_Val = db_LocalMat[i_lin][i_col]; st_IfcTree->db_RelativePlacement.push_back(db_Val);//(db_LocalMat[i_lin][i_col]) }// for (int i_lin = 0; i_lin < 3; i_lin++) }// for (int i_col = 0; i_col < 4; i_col++) }// if (db_LocalMat) }// if (st_IfcTree) } void ifc_Tree::FillCentroidOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, double db_CentroidCoord[3]) { //la structure st_IfcTree est celle que l'on initialise/renseigne dans cette routine //les structure st_IfcBelongTo est un pere de st_IfcTree (=> vient de la relation binaire ifcRelAggregates) //les structure st_IfcBelongTo2 est un 2nd père de st_IfcTree (=> vient de la relation ternaire IfcRelSpaceBoundary) if (st_IfcTree) { // Pour les tailles: http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ if (db_CentroidCoord) { for (int i_coord = 0; i_coord < 3; i_coord++) { double *db_Val = new double(); *db_Val = db_CentroidCoord[i_coord]; st_IfcTree->db_Centroid.push_back(db_Val);//(db_CentroidCoord[i_coord]) }// for (int i_coord = 0; i_coord < 3; i_coord++) }// if (db_CentroidCoord) }// if (st_IfcTree) } void ifc_Tree::FillGeomAttributeOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcSubFacGeomRep, list> &SubFacePtsCoord, STRUCT_IFCENTITY *st_IfcBelongTo, Map_String_String &map_messages) { FillNameAndIDAttributeOf_STRUCT_IFCENTITY(st_IfcSubFacGeomRep, map_messages); st_IfcSubFacGeomRep->st_PointsDesContours = SubFacePtsCoord; if (st_IfcBelongTo) { st_IfcSubFacGeomRep->st_BelongsTo.push_back(st_IfcBelongTo); st_IfcBelongTo->st_Contains.push_back(st_IfcSubFacGeomRep); }// if (st_IfcBelongTo) } void ifc_Tree::FillQuantitiesAttributeOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, Map_String_String &map_messages) { if (map_messages.size() != 0) { Map_String_String* mp_copy = new Map_String_String; *mp_copy = map_messages; if (mp_copy) st_IfcTree->map_DefValues = mp_copy; }// if (map_messages.size != 0) } int ifc_Tree::BuildTIFCSurfaceTreeFrom_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcEntCS1) { int res = 0; //On vérifie qu'il n'y a qu'une IfcConnectionSurfaceGeometry en vis-à-vis // car la TIFCSurface associe des paires de IfcConnectionSurfaceGeometry (pas plus) //A REVOIR: Par contre il peut ne pas y avoir de vis-à-vis (dans ce cas, c'est geoExt = mur exterieur, il est quand même en vis-à-vis?????) if (st_IfcEntCS1 && st_IfcEntCS1->st_FaceToFace.size()==1) { //Recup de la 2nde IfcConnectionSurfaceGeometry (en vis-à-vis) STRUCT_IFCENTITY* st_IfcEntCS2 = *(st_IfcEntCS1->st_FaceToFace.begin()); //On vérifie que cette IfcConnectionSurfaceGeometry (st_IfcEntCS2) n'a pas déjà sa TIFCSurface //car à sa création la même TIFCSurface est associée à 2 IfcConnectionSurfaceGeometry // => sinon erreur if (st_IfcEntCS2 && st_IfcEntCS2->st_TIFCSurface == nullptr) { // ATTENTION: la taille du nom "Ch_Id" est limité à 16 dans FillNameAndIDAttributeOf_STRUCT_IFCENTITY Map_String_String map_messages; map_messages["Id"] = string(st_IfcEntCS1->ch_Id) + string(st_IfcEntCS2->ch_Id); map_messages["Type"] = "TIFCSurface"; // Indiquer le type du TIFCSurface (ifcWall...) : map_messages["Type"] = ... //Création et Remplissage de la structure de "TIFCSurface" STRUCT_IFCENTITY * st_TIFCSurface = new STRUCT_IFCENTITY; FillNameAndIDAttributeOf_STRUCT_IFCENTITY(st_TIFCSurface, map_messages); //FillAttributeOf_STRUCT_IFCENTITY(st_IfcContain, map_messages, db_LocalMat, &(*st_IfcBelongTo)); st_IfcEntCS1->st_TIFCSurface = st_TIFCSurface; st_IfcEntCS2->st_TIFCSurface = st_TIFCSurface; if (st_TIFCSurface) { st_TIFCSurface->st_Contains.push_back(st_IfcEntCS1); st_TIFCSurface->st_Contains.push_back(st_IfcEntCS2); }// if (st_TIFCSurface) }// if (st_IfcEntCS2 && st_IfcEntCS2->st_TIFCSurface==nullptr) else res = 3001;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine }// if (st_IfcEntCS1 && st_IfcEntCS1->st_FaceToFace.size()==1) else { if (st_IfcEntCS1 && st_IfcEntCS1->st_FaceToFace.size() == 0) { //SOIT MUR exterieur //SOIT dalle entre étage => pas sûr car dalles devraientt se traiter comme les murs intérieurs??!!?? // ATTENTION: la taille du nom "Ch_Id" est limité à 16 dans FillNameAndIDAttributeOf_STRUCT_IFCENTITY Map_String_String map_messages; map_messages["Id"] = string(st_IfcEntCS1->ch_Id) + "------"; map_messages["Type"] = "TIFCSurface"; // Indiquer le type du TIFCSurface (ifcWall...) : map_messages["Type"] = ... //Création et Remplissage de la structure de "TIFCSurface" STRUCT_IFCENTITY * st_TIFCSurface = new STRUCT_IFCENTITY; FillNameAndIDAttributeOf_STRUCT_IFCENTITY(st_TIFCSurface, map_messages); //FillAttributeOf_STRUCT_IFCENTITY(st_IfcContain, map_messages, db_LocalMat, &(*st_IfcBelongTo)); st_IfcEntCS1->st_TIFCSurface = st_TIFCSurface; //st_IfcEntCS2->st_TIFCSurface = st_TIFCSurface; if (st_TIFCSurface) { st_TIFCSurface->st_Contains.push_back(st_IfcEntCS1); //st_TIFCSurface->st_Contains.push_back(st_IfcEntCS2); }// if (st_TIFCSurface) }// if (st_IfcEntCS1 && st_IfcEntCS1->st_FaceToFace.size() == 0) }// else if (st_IfcEntCS1->st_FaceToFace.size()==1) return res; } \ No newline at end of file diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.h index 034dedf..8eecbac 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.h +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.h @@ -1,60 +1,79 @@ #pragma once #include #include +#include +#include using namespace std; typedef map Map_String_String; //IMPORTANT: Toute modif de la structure doit assurer son "delete" (cf. ifc_Tree::delete_STRUCT_IFCENTITY) struct STRUCT_IFCENTITY { const char *ch_GlobalId = nullptr; const char *ch_Type = nullptr; + const char *ch_PredifinedType = nullptr; const char *ch_Id = nullptr; const char *ch_Name = nullptr; list st_BelongsTo; list st_Contains; list st_FaceToFace; //list st_SideBySide; STRUCT_IFCENTITY* st_TIFCSurface = nullptr; - map mp_SideBySide; + set>, function>, pair>)>> mp_SideBySide; +// set>> mp_SideBySide; + //map> mp_SideBySide; + //map mp_SideBySide; list db_RelativePlacement; list> st_PointsDesContours; bool bo_ArePointsDesContoursALoop = false;//Si true = les 1er et dernier points de st_PointsDesContours sont identiques list db_Centroid; Map_String_String* map_DefValues = nullptr;// tableau des noms des attributs géométriques (Length, Width,...) et de leur valeur (en string) }; +typedef function>, pair>)> Comparator; typedef map Map_String_ptrSTRUCT_IFCENTITY; +//extern Comparator compFunctor; +//Comparator compFunctor = +// [](pair> elem1, pair> elem2) +//{ +// return elem1.second.first < elem2.second.first; +//}; class ifc_Tree { public: ifc_Tree(); ~ifc_Tree(); void FillAttributeOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, Map_String_String &map_messages, double db_LocalMat[3][4] = nullptr, STRUCT_IFCENTITY *st_IfcBelongTo = nullptr, STRUCT_IFCENTITY *st_IfcBelongTo2 = nullptr); void FillAttributeOfExisting_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, Map_String_String &map_messages, double db_LocalMat[3][4] = nullptr, STRUCT_IFCENTITY *st_IfcBelongTo = nullptr, STRUCT_IFCENTITY *st_IfcBelongTo2 = nullptr); void FillNameAndIDAttributeOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, Map_String_String &map_messages); void FillRelativePlacementOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, double db_LocalMat[3][4]); void FillGeomAttributeOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcSubFacGeomRep, list> &SubFacePtsCoord, STRUCT_IFCENTITY *st_IfcBelongTo, Map_String_String &map_messages); void FillCentroidOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, double db_CentroidCoord[3]); void FillQuantitiesAttributeOf_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree, Map_String_String &map_messages); void delete_STRUCT_IFCENTITY(STRUCT_IFCENTITY *&st_IfcTree, STRUCT_IFCENTITY* st_IfcCurrentFather = nullptr); //Creation d'entité (TIFCSurface) à partir des autres entités STRUCT_IFCENTITY (IfcConnectionSurfaceGeometry) déjà définies (pas à partir des entités xml comme dans ifc_Tree.template.h) int BuildTIFCSurfaceTreeFrom_STRUCT_IFCENTITY(STRUCT_IFCENTITY* st_IfcTree); + Comparator compFunctor = + [](pair> elem1, pair> elem2) + { + return elem1.second.first < elem2.second.first; + }; + #include "ifc_Tree.template.h" STRUCT_IFCENTITY *&Getstruct(); private: STRUCT_IFCENTITY *_st_IfcTree; Map_String_ptrSTRUCT_IFCENTITY _map_ID_IfcEnt; }; diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h index 17f7fc6..304386e 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h @@ -1,606 +1,623 @@ template int ifc_Tree::BuildTreeFromRoot(Type_Elmt_Of_Source *&pElem/*, STRUCT_IFCENTITY *&st_IfcTree*/, Type_Source * const& ifcXmlFile) { int res = 0; //lecture des Id et type de "IfcProject" Map_String_String m_messages; res = ifcXmlFile->ReadIdAndTypeOfAnEntity(pElem, m_messages); if (res) return res; + //Recup du positionnement relatif + Type_Elmt_Of_Source *lpObjectGeomrepCtx = nullptr; + res = ifcXmlFile->FindIfcGeometricRepresentationContext(pElem, lpObjectGeomrepCtx); + if (res) return res; + //Recup du positionnement relatif Type_Elmt_Of_Source *lpObjectPlac = nullptr; - res = ifcXmlFile->FindIfcGeometricRepresentationContext(pElem, lpObjectPlac); + res = ifcXmlFile->FindIfcAxis2Placement3D(lpObjectGeomrepCtx, lpObjectPlac); if (res) return res; //Recup de la matrice de position double db_LocalMat[3][4]; res = ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); if (res) return res; + //Recup du vecteur Nord géographique + double db_GeoNorth[3]; + res = ifcXmlFile->ReadIfcDirectionVector(lpObjectGeomrepCtx, db_GeoNorth); + if (res) return res; + //Création et Remplissage de la structure de "IfcProject" _st_IfcTree = new STRUCT_IFCENTITY(); FillAttributeOf_STRUCT_IFCENTITY(_st_IfcTree, m_messages, db_LocalMat); + //On met le Nord Géographique dans l'attribut "Centroid" de l'ifcProject + FillCentroidOf_STRUCT_IFCENTITY(_st_IfcTree, db_GeoNorth); + //Recupération chainée des entités successives de "IfcProject" res = BuildTreeFrom(pElem, ifcXmlFile, _st_IfcTree); if (res) return res; return res; } template int ifc_Tree::BuildTreeFromRelAggregates(list &lpRelatedObjects, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { int res = 0; //Boucle sur les RelatedObjects de IfcRelAggregates en cours 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); if (res) return res; //Recup du positionnement relatif Type_Elmt_Of_Source *lpObjectPlac = nullptr; res = ifcXmlFile->FindIfcLocalPlacement(*it_Elem, lpObjectPlac); if (res) return res; //Recup de la matrice de position double db_LocalMat[3][4]; res = ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); if (res) return res; + ////Recup du PredefinedType (soit sous ifcEntity soit sous ifcEntityType via IfcRelDefinesByType de l'ifcEntity) + //res = ifcXmlFile->ReadPredefinedTypeOfAnEntity(*it_Elem, map_messages); + //if (res) return res; + //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 res = BuildTreeFrom(*it_Elem, ifcXmlFile, st_IfcContain); if (res) return res; }// 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) { int res = 0; //Boucle sur les IfcProductDefinitionShape de IfcSpace en cours 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); if (res) return res; // !!!! 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 //IfcConnectionSurfaceGeometry int ifc_Tree::BuildTreeFromRelSpaceBoundary(list &lpRelatedBuildingElement, list &lpConnectionSurfaceGeometry, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) { int res = 0; //Boucle à la fois sur les éléments de construction et sur les ConnectionSurfaceGeometry (correspondance unaire 1 <-> 1) 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); if (res) return res; //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); if (res) return res; 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); if (res) return res; //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 //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. // // // int res = 0; //Recup de repere local P/R reprere global Type_Elmt_Of_Source *lpObjectPlac = nullptr; res = ifcXmlFile->FindIfcCurveBoundedPlanePlacemcent(pElem, lpObjectPlac); if (res) return res; double db_LocalMat[3][4]; res = ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); if (res) return res; 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); if (res) return res; //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 2001;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine if (lllBoundaryOfSurface_SubFace.size() != lpObjectSubFace.size()) return 2002;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine // //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); if (res) return res; 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); if (res) return res; //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; res = ifcXmlFile->FindIfcShapeRepresentationBrep(pElem, lpObjectFound); if (res) return res; if (lpObjectFound) { //Recup de repere local P/R reprere global Type_Elmt_Of_Source *lpObjectPlac = nullptr; res = ifcXmlFile->FindIfcGeometricRepresentationSubContext(lpObjectFound, lpObjectPlac); if (res) return res; double db_LocalMat[3][4]; res = ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); if (res) return res; 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); if (res) return res; //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 2003;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine if ( (*(lllCFsFacesOfOneItem_Face.begin())).size() != lpObjectFace.size()) return 2004;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine // //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); if (res) return res; 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); if (res) return res; //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) { int res = 0; // // IfcRelAggregates // //Recuperation des IfcEntity liés à pElem ("IfcProject",ifcSite...) par le lien binaire IfcRelAggregates list lpRelatedObjects; res = ifcXmlFile->FindRelatedObjectsInRelAggregatesFromRelatingObject(pElem, &lpRelatedObjects); if (res) return res; // 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) { res = BuildTreeFromRelAggregates(lpRelatedObjects, ifcXmlFile, &(*st_IfcBelongTo)); if (res) return res; }// if (lpRelatedObjects.size!=0) else { //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") ) { // //lecture du Quantities des "IfcSpace" Map_String_String map_messages; res = ifcXmlFile->ReadKeyWordsAndValuesOfIfcElementQuantity(pElem, map_messages); if (res) return res; 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); if (res) return res; res = BuildTreeFromShapeOfSpace(lpShape, ifcXmlFile, &(*st_IfcBelongTo)); if (res) return res; // // IfcRelSpaceBoundary // //Recuperation des IfcEntity liés à "IfcSpace" par le lien ternaire IfcRelSpaceBoundary list lpRelatedBuildingElement; list lpConnectionSurfaceGeometry; res = ifcXmlFile->FindRelatedBuildingElementAndConnectionGeometryInRelSpaceBoundaryFromRelatingSpace(pElem, &lpRelatedBuildingElement, &lpConnectionSurfaceGeometry); if (res) return res; if (lpRelatedBuildingElement.size() != 0 && lpRelatedBuildingElement.size() == lpConnectionSurfaceGeometry.size()) { res = BuildTreeFromRelSpaceBoundary(lpRelatedBuildingElement, lpConnectionSurfaceGeometry, ifcXmlFile, &(*st_IfcBelongTo)); if (res) return res; }// 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 (res) return res; }// 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 (res) return res; }// if (string(pElem->Value()) == string("IfcProductDefinitionShape")) return res; } diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.cpp index e6f165e..04a2e8c 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.cpp +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.cpp @@ -1,1095 +1,1274 @@ #include "ifc_TreePostTreatment.h" //#include #include +#include +//#include const double db_eps= 0.00001; +const double db_ep_mur_max = 0.3; ifc_TreePostTreatment::ifc_TreePostTreatment(ifc_Tree* CurrentIfcTree) { _CurrentIfcTree = CurrentIfcTree; } ifc_TreePostTreatment::~ifc_TreePostTreatment() { } int ifc_TreePostTreatment::BasifyTree(Map_Basified_Tree *&map_BasifTree) { int res = 0; + if (_map_BasifTree.size() != 0) + _map_BasifTree.clear(); + STRUCT_IFCENTITY* st_IfcTree = nullptr; if (_CurrentIfcTree) { st_IfcTree =_CurrentIfcTree->Getstruct(); if (st_IfcTree) res = BasifyTreeFrom(st_IfcTree); else res = 4002;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine map_BasifTree = &_map_BasifTree; }// if (_CurrentIfcTree) else res = 4001;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine return res; } int ifc_TreePostTreatment::BasifyTreeFrom(STRUCT_IFCENTITY *&st_IfcTree) { int res = 0; //Memo adresse pointeur (si existe pas ajouté) et son type "Ifc" // => la map permet de ne pas référencer de multiple fois une même entité // dans l'arbre, des entités sont référencés plusieurs fois car elles appartiennent à plusieurs objets _map_BasifTree[st_IfcTree] = st_IfcTree->ch_Type; list ::iterator it_Elem; for (it_Elem = (st_IfcTree->st_Contains).begin(); it_Elem != (st_IfcTree->st_Contains).end(); it_Elem++) { res = BasifyTreeFrom((*it_Elem)); if (res) return res; }// for (it_Elem = (st_IfcTree->st_Contains).begin(); it_Elem != (st_IfcTree->st_Contains).end(); it_Elem++) return res; } int ifc_TreePostTreatment::CompleteBasifiedTreeFromByTIFCSurfaces() { int res = 0; std::map::reverse_iterator it_Elem; for (it_Elem = _map_BasifTree.rbegin(); it_Elem != _map_BasifTree.rend(); it_Elem++) { if (it_Elem->first->st_TIFCSurface) _map_BasifTree[it_Elem->first->st_TIFCSurface] = it_Elem->first->st_TIFCSurface->ch_Type; }// for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) return res; } -//Retrait dans les contours (st_PointsDesContours) du derniers point lorsqu'il est égal au 1er (+ consigne bool bo_IsItLoop=true) -int ifc_TreePostTreatment::RemoveLastPointOfLoopContours() +//Retrait dans les contours (st_PointsDesContours) du dernier point lorsqu'il est égal au 1er (+ consigne bool bo_IsItLoop=true) +int ifc_TreePostTreatment::RemoveLastPointOfLoopContours(string *&str_LogFile) { int res = 0; std::map::iterator it_Elem; for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) { if (it_Elem->first->st_PointsDesContours.size() != 0) - res = RemoveLastPointOfOneLoopContour(it_Elem->first); + res = RemoveLastPointOfOneLoopContour(it_Elem->first,str_LogFile); if (res) return res; }// for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) return res; } //Retrait dans le contour (st_PointsDesContours) du derniers point lorsqu'il est égal au 1er (+ consigne bool bo_IsItLoop=true) -int ifc_TreePostTreatment::RemoveLastPointOfOneLoopContour(STRUCT_IFCENTITY *st_IfcEnt) +int ifc_TreePostTreatment::RemoveLastPointOfOneLoopContour(STRUCT_IFCENTITY *st_IfcEnt, string *&str_LogFile) { int res = 0; //Boucle sur les différents sous-contours list > ::iterator it_llPt; for (it_llPt = (st_IfcEnt->st_PointsDesContours).begin(); it_llPt != (st_IfcEnt->st_PointsDesContours).end(); it_llPt++) { //Verif si 1er pt=dernier pt => si oui retirer le dernier pt (les 3 dernières coordonnées) + consigne bool bo_IsItLoop=true list ::iterator it_lPt = it_llPt->begin(); double X1 = *(*it_lPt); it_lPt++; double Y1 = *(*it_lPt); it_lPt++; double Z1 = *(*it_lPt); it_lPt = it_llPt->end(); it_lPt--; double ZN = *(*it_lPt); it_lPt--; double YN = *(*it_lPt); it_lPt--; double XN = *(*it_lPt); double db_Dist = sqrt((X1 - XN)*(X1 - XN) + (Y1 - YN)*(Y1 - YN) + (Z1 - ZN)*(Z1 - ZN)); if (db_Dist < db_eps) { (*it_llPt).pop_back(); (*it_llPt).pop_back(); (*it_llPt).pop_back(); st_IfcEnt->bo_ArePointsDesContoursALoop = true; + + //Consigner l'effacement du dernier point enlever dans un fichier "log" (ou mettre en mémoire => même principe que pour le fichier bimxbem) + int int_Step = 0; + string str_Header = "Remove Last Point If Equal First Point :"; + RecordLog(int_Step, *str_LogFile, str_Header, st_IfcEnt); + }// if (db_Dist < 0.0000001) }// for (it_llPt = (st_IfcEnt->st_PointsDesContours).begin(); it_llPt != (st_IfcEnt->st_PointsDesContours).end(); it_llPt++) return res; } //Calcul des surfaces IfcConnectionSurfaceGeometry int ifc_TreePostTreatment::ComputeIfcConnectionSurfaceGeometrySurface() { int res = 0; std::map::iterator it_Elem; for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) { if (it_Elem->second == "IfcConnectionSurfaceGeometry") res = ComputeOneIfcConnectionSurfaceGeometrySurface(it_Elem->first); if (res) return res; }// for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) return res; } //Calcul de la surface d'une IfcConnectionSurfaceGeometry int ifc_TreePostTreatment::ComputeOneIfcConnectionSurfaceGeometrySurface(STRUCT_IFCENTITY *st_IfcEntCS) { int res = 0; //Recup de toutes les coordonnées de tous les points du contour double db_TotalSurf = 0.0; vector vc_PointCoordCtr1; for (list::iterator it_lEnt = (st_IfcEntCS->st_Contains).begin(); it_lEnt != (st_IfcEntCS->st_Contains).end(); it_lEnt++) { for (list>::iterator it_llCtr = ((*it_lEnt)->st_PointsDesContours).begin(); it_llCtr != ((*it_lEnt)->st_PointsDesContours).end(); it_llCtr++) { //Recup du contour vc_PointCoordCtr1.insert(vc_PointCoordCtr1.end(), (*it_llCtr).begin(), (*it_llCtr).end()); //Fermer le contour par ajout du premier Pt en dernier (nécessaire au calcul de la surface) vector::iterator it_CoordPt1_end = vc_PointCoordCtr1.begin(); ++++++it_CoordPt1_end; vc_PointCoordCtr1.insert(vc_PointCoordCtr1.end(), vc_PointCoordCtr1.begin(), it_CoordPt1_end); //Calcul de la surface définie par ce contour + Somme des differentes surfaces déjà calculés db_TotalSurf += ComputeSurfaceFromAContour(vc_PointCoordCtr1); }// for (list>::iterator it_llCtr = ((*it_lEnt)->st_PointsDesContours).begin(); it_llCtr != ((*it_lEnt)->st_PointsDesContours).end(); it_llCtr++) }// for (list::iterator it_lEnt = (st_IfcEntCS->st_Contains).begin(); it_lEnt != (st_IfcEntCS->st_Contains).end(); it_lEnt++) Map_String_String map_messages; map_messages["ComputedArea"] = to_string(db_TotalSurf); if (_CurrentIfcTree) _CurrentIfcTree->FillQuantitiesAttributeOf_STRUCT_IFCENTITY(st_IfcEntCS, map_messages); else res = 4003;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine return res; } //Calcul d'une surface plane à partir de ses contours double ifc_TreePostTreatment::ComputeSurfaceFromAContour(vector &vc_PointCoordCtr) { //int res = 0; double db_Surf = 0.0; vector::iterator it_Coord1Pt1;/*P1_x*/ for (it_Coord1Pt1 = vc_PointCoordCtr.begin(); it_Coord1Pt1 != ------(vc_PointCoordCtr.end()); ++++++it_Coord1Pt1) { vector::iterator it_Coord2Pt1 = it_Coord1Pt1;/*P1_x*/ ++it_Coord2Pt1;/*P1_y*/ vector::iterator it_Coord1Pt2 = it_Coord2Pt1;/*P1_y*/ ++it_Coord1Pt2;/*P1_z*/ ++it_Coord1Pt2;/*P2_x*/ vector::iterator it_Coord2Pt2 = it_Coord1Pt2;/*P2_x*/ ++it_Coord2Pt2;/*P2_y*/ db_Surf += (*(*it_Coord1Pt1)*(*(*it_Coord2Pt2)) - *(*it_Coord2Pt1)*(*(*it_Coord1Pt2))) / 2; }// for (it_Coord1Pt1 = vc_PointCoordCtr.begin(); it_Coord1Pt1 != vc_PointCoordCtr.end(); ++(++(++it_Coord1Pt1))) return db_Surf; } +//Retrait des IfcConnectionSurfaceGeometry de surfaces inférieures à dbl_Minisurf +int ifc_TreePostTreatment::RemoveQuasiNullIfcConnectionSurfaceGeometrySurface(double dbl_Minisurf, string *&str_LogFile) +{ + int res = 0; + + std::map::iterator it_Elem; + for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) + { + if (it_Elem->second == "IfcConnectionSurfaceGeometry") + res = RemoveOneQuasiNullIfcConnectionSurfaceGeometrySurface(it_Elem->first,dbl_Minisurf, str_LogFile); + if (res) return res; + }// for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) + + return res; +} + +void ifc_TreePostTreatment::RecordLog(int &int_Step, string &str_LogFile, string &str_Header, STRUCT_IFCENTITY *&st_IfcEnt) +{ + switch (int_Step) + { + case 0: + str_LogFile = str_LogFile /*+ "\n"*/ + str_Header + "\n"; + str_LogFile = str_LogFile + "\t" + st_IfcEnt->ch_Id + "\n"; + break; + case 1: + str_LogFile = str_LogFile /*+ "\n" */ + str_Header + "\n"; + str_LogFile = str_LogFile + "\t" + st_IfcEnt->ch_Id + " (Surf = " + st_IfcEnt->map_DefValues->at("ComputedArea") + ")\n"; + break; + case 2: + str_LogFile = str_LogFile /*+ "\n" */ + str_Header + "\n"; + break; + default: return; + }// switch (int_Step) + + return; +} + +int ifc_TreePostTreatment::RemoveOneQuasiNullIfcConnectionSurfaceGeometrySurface(STRUCT_IFCENTITY *st_IfcEntCS, double dbl_Minisurf, string *&str_LogFile) +{ + int res = 0; + + double dbl_Surf = abs(std::stod(st_IfcEntCS->map_DefValues->at("ComputedArea"))); + if (dbl_Surf même principe que pour le fichier bimxbem) + int int_Step = 1; + string str_Header = "Remove Quasi Null Surface < "+ std::to_string(dbl_Minisurf)+ ":"; + RecordLog(int_Step, *str_LogFile, str_Header, st_IfcEntCS); + // + // Nettoyage des listes référencant l'objet que l'on est en train de détruire + // Pour les liens non binaires (ternaires ou plus) la structure en cours d'effacement (st_IfcTree) est référencée dans les Contains de plusieurs pères + // Afin déviter un crash mémoire par la désallocation d'une structure déjà détruite, il faut déréférencer la structure + // en cours d'effacement des listes de BelongsTo des autres pères (que celui en cours = st_IfcCurrentFather) + // Exemple: IfcConnectionSurfaceGeometry est référencé à la fois dans le st_Contains de IfSpace et des BuildingElements (IfcWall,...) + _CurrentIfcTree->delete_STRUCT_IFCENTITY(st_IfcEntCS); + st_IfcEntCS = nullptr; + } + + return res; +} + //Creation des TIFCSurfaces par concatenation des IfcConnectionSurfaceGeometry en vis-à-vis int ifc_TreePostTreatment::CreateTIFCSurfaces() { int res = 0; std::map::iterator it_Elem; for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) { if (it_Elem->second == "IfcConnectionSurfaceGeometry") res= CreateTIFCSurface(it_Elem->first); if (res) return res; }// for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) return res; } //Creation d'une TIFCSurface par concatenation des 2 IfcConnectionSurfaceGeometry en vis-à-vis int ifc_TreePostTreatment::CreateTIFCSurface(STRUCT_IFCENTITY *st_IfcEntCS) { int res = 0; //On vérifie que cette IfcConnectionSurfaceGeometry (st_IfcEntCS) n'a pas déjà sa TIFCSurface //car à sa création la même TIFCSurface est associée à 2 IfcConnectionSurfaceGeometry if (st_IfcEntCS && st_IfcEntCS->st_TIFCSurface==nullptr) { if (_CurrentIfcTree) res = _CurrentIfcTree->BuildTIFCSurfaceTreeFrom_STRUCT_IFCENTITY(st_IfcEntCS); else res = 4005;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine } //else // res = 4004;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine return res; } //Calcul des isobarycentres des IfcConnectionSurfaceGeometry int ifc_TreePostTreatment::CentroidsComputation() { int res = 0; std::map::iterator it_Elem; for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) { if (it_Elem->second == "IfcConnectionSurfaceGeometry") res= CentroidComputation(it_Elem->first); if (res) return res; }// for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) return res; } //Calcul de l'isobarycentre d'une IfcConnectionSurfaceGeometry int ifc_TreePostTreatment::CentroidComputation(STRUCT_IFCENTITY *st_IfcEntCS) { int res = 0; //Init isobarycentre double db_IsoBar[3] = { 0.,0.,0. }; //Compteur "i" qui, au final, sera egal au nombre de points des contours fois 3(=nbre de composantes=x,y,z) int i = 0; list ::iterator it_Elem; for (it_Elem = (st_IfcEntCS->st_Contains).begin(); it_Elem != (st_IfcEntCS->st_Contains).end(); it_Elem++) { //Boucle sur les coord pour calculer l'isobarycentre list > ::iterator it_llPt; for (it_llPt = ((*it_Elem)->st_PointsDesContours).begin(); it_llPt != ((*it_Elem)->st_PointsDesContours).end(); it_llPt++) { //lire la liste des points (le dernier point est toujours différent du 1er car a été enlevé par routine RemoveLastPointOfLoopContours) list ::iterator it_lPt; for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) { db_IsoBar[i % 3] += *(*it_lPt); i++; }// for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) }// for (it_llPt = ((*it_Elem)->st_PointsDesContours).begin(); it_llPt != ((*it_Elem)->st_PointsDesContours).end(); it_llPt++) }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) //Finalisation du calcul de l'isobarycentre for(int j=0;j<3;j++) db_IsoBar[j] /= (i / 3); //Mémo dans la structure if (_CurrentIfcTree) _CurrentIfcTree->FillCentroidOf_STRUCT_IFCENTITY(st_IfcEntCS, db_IsoBar); else res = 4006;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine return res; } -int ifc_TreePostTreatment::RelimitSideBySideSurfaces() +//Recherche des IfcConnectionSurfaceGeometry pouvant avoir des côtés à étendre (i.e. qui ont au moins 1 SideBySide) +int ifc_TreePostTreatment::RelimitSideBySideSurfaces(string *&str_LogFile) { int res = 0; + //Traitement des IfcConnectionSurfaceGeometry pouvant avoir des côtés à étendre std::map::iterator it_Elem; for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) { - //Traitement des IfcConnectionSurfaceGeometry ayant 2 côté à étendre - //Recherche des IfcConnectionSurfaceGeometry avec 2 SideBySide - if (it_Elem->second == "IfcConnectionSurfaceGeometry" /*&& it_Elem->first->st_SideBySide.size()==2*/) - res = RelimitSideBySideSurfacesOfMiddleIfcConnectionSurfaceGeometry(it_Elem->first); + //Recherche des IfcConnectionSurfaceGeometry qui ont au moins 1 SideBySide + if (it_Elem->second == "IfcConnectionSurfaceGeometry" && it_Elem->first->mp_SideBySide.size() != 0) + res = RelimitSideBySideSurfacesOfOneIfcConnectionSurfaceGeometry(it_Elem->first, str_LogFile); if (res) return res; }// for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) return res; } -//Raccord du IfcConnectionSurfaceGeometry milieu PAS SEULEMENT!!! (entre 2 autres IfcConnectionSurfaceGeometry) -int ifc_TreePostTreatment::RelimitSideBySideSurfacesOfMiddleIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *st_IfcEntCS) +//Boucles sur les IfcConnectionSurfaceGeometry côte-àcôte avec l'IfcConnectionSurfaceGeometry en cours (pour extension du IfcConnectionSurfaceGeometry si nécessaire) +int ifc_TreePostTreatment::RelimitSideBySideSurfacesOfOneIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *st_IfcEntCS, string *&str_LogFile) { int res = 0; - //Retrouver les 2 IfcConnectionSurfaceGeometry qui sont côte-à-côte avec l'IfcConnectionSurfaceGeometry en cours - map ::iterator it_SideBySideIfcEntCS; + //Retrouver les IfcConnectionSurfaceGeometry qui sont côte-à-côte avec l'IfcConnectionSurfaceGeometry en cours + set>>::iterator it_SideBySideIfcEntCS; + //set>, Comparator>::iterator it_SideBySideIfcEntCS; for (it_SideBySideIfcEntCS = (st_IfcEntCS->mp_SideBySide).begin(); it_SideBySideIfcEntCS != (st_IfcEntCS->mp_SideBySide).end(); it_SideBySideIfcEntCS++) { - //retrouver les paires de points les plus proches (chaque point appartenant à l'un ou l'autre des IfcConnectionSurfaceGeometry) - if (!(*it_SideBySideIfcEntCS).second) + //retrouver les paires de points les plus proches (chaque point appartenant à l'un ou l'autre des IfcConnectionSurfaceGeometry côte-à-côtes) + if (!(*it_SideBySideIfcEntCS).second.second) { - RelimitOneSideBySideSurfaceOfMiddleIfcConnectionSurfaceGeometry(st_IfcEntCS, (*it_SideBySideIfcEntCS).first); - (*it_SideBySideIfcEntCS).second = true; - (*it_SideBySideIfcEntCS).first->mp_SideBySide[st_IfcEntCS] = true; + RelimitOneSideBySideSurfaceOfOneIfcConnectionSurfaceGeometry(st_IfcEntCS, (*it_SideBySideIfcEntCS).first, str_LogFile); + //(*it_SideBySideIfcEntCS).second.second = true; + //(*it_SideBySideIfcEntCS).first->mp_SideBySide[st_IfcEntCS].second = true; }// if (!(*it_SideBySideIfcEntCS).second) }// for (it_Elem2 = (it_Elem1->first->st_Contains).begin(); it_Elem2 != (it_Elem1->first->st_Contains).end(); it_Elem2++) return res; } -int ifc_TreePostTreatment::RelimitOneSideBySideSurfaceOfMiddleIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *&st_IfcEntCS1, STRUCT_IFCENTITY *st_IfcEntCS2) +//Extension si besoin de l'IfcConnectionSurfaceGeometry en cours et d'un des IfcConnectionSurfaceGeometry côte-à-côtes +//A priori on a 3 cas: +// les IfcConnectionSurfaceGeometry en cours et côte-à-côte sont "coller" (Dist des pairs de pts les + proches = 0) => ne rien faire +// les IfcConnectionSurfaceGeometry en cours et côte-à-côte sont "disjoints" avec Dist des pairs de pts les + proches >> épaisseurs murs => ne rien faire +// les IfcConnectionSurfaceGeometry en cours et côte-à-côte sont "disjoints" avec Dist des pairs de pts les + proches ~ épaisseurs murs => jonction par milieu de la dist (cf. schéma): +// +// 2 ifcConn séparées Raccord des 2 ifcconn +// par epaisseur mur par leur milieu +// --- --- -------- +// | | => | +// | | | +// --- --- -------- +int ifc_TreePostTreatment::RelimitOneSideBySideSurfaceOfOneIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *&st_IfcEntCS1, STRUCT_IFCENTITY *st_IfcEntCS2, string *&str_LogFile) { int res = 0; - //Recup de toutes les coordonnées de tous les points du 1er contour + //ATTENTION: ne pas lire les pts du ctr1 dans la routine précédente car les coordonnées sont suceptibles d'être modifiées => il faut les relire à chaque passage! + //Recup de toutes les coordonnées de tous les points du 1er contour (IfcConnectionSurfaceGeometry en cours) vector vc_PointCoordCtr1; for (list::iterator it_lEnt = (st_IfcEntCS1->st_Contains).begin(); it_lEnt != (st_IfcEntCS1->st_Contains).end(); it_lEnt++) for (list>::iterator it_llCtr = ((*it_lEnt)->st_PointsDesContours).begin(); it_llCtr != ((*it_lEnt)->st_PointsDesContours).end(); it_llCtr++) vc_PointCoordCtr1.insert(vc_PointCoordCtr1.end(), (*it_llCtr).begin(), (*it_llCtr).end()); - //Recup de toutes les coordonnées de tous les points du 2ème contour + //Recup de toutes les coordonnées de tous les points du 2ème contour (IfcConnectionSurfaceGeometry côte-à-côte) vector vc_PointCoordCtr2; for (list::iterator it_lEnt = (st_IfcEntCS2->st_Contains).begin(); it_lEnt != (st_IfcEntCS2->st_Contains).end(); it_lEnt++) for (list>::iterator it_llCtr = ((*it_lEnt)->st_PointsDesContours).begin(); it_llCtr != ((*it_lEnt)->st_PointsDesContours).end(); it_llCtr++) vc_PointCoordCtr2.insert(vc_PointCoordCtr2.end(), (*it_llCtr).begin(), (*it_llCtr).end()); // //Calcul des distances entre chaque paire de points appartenant à chacun des contours des IfcConnectionSurfaceGeometry // li_IndPtCtr1_IndPtCtr2_Dist[iterateur debut Pt_J du contour1, iterateur debut Pt_J du contour2]=distance // Utilisation d'une liste pour profiter du tri optimisée "list::sort()" list< pair< pair::iterator, vector::iterator>, double>> li_IndPtCtr1_IndPtCtr2_Dist; - //Boucle sur st_Contains pour retrouver tous les IfcConnectionSurfaceGeometry + //Boucle sur tous les points de chacun des contours des IfcConnectionSurfaceGeometry en cours et côte-à-côte vector::iterator it_CoordCtr1; vector::iterator it_CoordCtr2; for (it_CoordCtr1 = vc_PointCoordCtr1.begin(); it_CoordCtr1 != vc_PointCoordCtr1.end(); ++(++(++it_CoordCtr1))) { + vector::iterator it_CoordCtr1_end = it_CoordCtr1; ++++++it_CoordCtr1_end; + vector vc_Point1(it_CoordCtr1, it_CoordCtr1_end); + for (it_CoordCtr2 = vc_PointCoordCtr2.begin(); it_CoordCtr2 != vc_PointCoordCtr2.end(); ++(++(++it_CoordCtr2))) { - vector::iterator it_CoordCtr1_end = it_CoordCtr1; ++++++it_CoordCtr1_end; vector::iterator it_CoordCtr2_end = it_CoordCtr2; ++++++it_CoordCtr2_end; - vector vc_Point1(it_CoordCtr1, it_CoordCtr1_end); vector vc_Point2(it_CoordCtr2, it_CoordCtr2_end); //Calculer distance entre les 2 points des 2 IfcConnectionSurfaceGeometry double db_dist=ComputePtPtDistance(vc_Point1, vc_Point2); //Memo de la distance entre les 2 points des 2 IfcConnectionSurfaceGeometry vc_Point1 et vc_Point2 li_IndPtCtr1_IndPtCtr2_Dist.push_back(std::make_pair(std::make_pair(it_CoordCtr1, it_CoordCtr2), db_dist)); }// for (vector::iterator it_CoordCtr2 = vc_PointCoordCtr2.begin(); it_CoordCtr2 != vc_PointCoordCtr2.end(); it_CoordCtr2++) }// for (vector::iterator it_CoordCtr1 = vc_PointCoordCtr1.begin(); it_CoordCtr1 != vc_PointCoordCtr1.end(); it_CoordCtr1++) //Trier les paires par proximité pour trouver les points à rejoindre li_IndPtCtr1_IndPtCtr2_Dist.sort([](auto lhs, auto rhs) { return lhs.second < rhs.second; }); //QUE FAIRE SI des paires de points sont quasi l'un sur l'autre => merger les 2 IfcConnectionSurfaceGeometry?? // ou verifier que l'une a une surface quasi nulle // => la retirer? => Traitement à faire dès le début après RemoveLastPointOfLoopContours() mais attention au retrait à faire dans IfcSpace et elmt cstruction (Wall,...) // En tout cas si la 1ere paire de point est confondue on peut supposer que les 2 surfaces sont déjà connectées => pas de raccord à faire list< pair< pair::iterator, vector::iterator>, double>>::iterator it_IndPtCtr1_IndPtCtr2_Dist = li_IndPtCtr1_IndPtCtr2_Dist.begin(); - if ((*it_IndPtCtr1_IndPtCtr2_Dist).second > db_eps) + //Si les contours ne sont pas "coller" (Dist > db_eps) et pas "disjoints" avec Dist >> épaisseurs murs max + // => on fait la jonction par le milieu des pairs de points distants les plus proches (jusqu'à distance arbitrairement au max 20% de plus que la 1ère distance la plus proche) + // + //Si Dist mini > épaisseurs murs max => rien à raccorder (il y a certainement une surface entre l'Ifcconn en cours et celle côte-à-côte) => voir un autre côte-à-côte + if ((*it_IndPtCtr1_IndPtCtr2_Dist).second < db_ep_mur_max) { - //Memo de la distance de reference - double db_Distref = (*it_IndPtCtr1_IndPtCtr2_Dist).second; - for (it_IndPtCtr1_IndPtCtr2_Dist; it_IndPtCtr1_IndPtCtr2_Dist!= li_IndPtCtr1_IndPtCtr2_Dist.end();++it_IndPtCtr1_IndPtCtr2_Dist) + // + //Si Dist mini < db_eps => rien à raccorder (les 2 surfaces sont connectées) => voir un autre côte-à-côte + if ((*it_IndPtCtr1_IndPtCtr2_Dist).second > db_eps) { - // - //Remplacement des points les plus proches appartenant à un même côté (par leur point milieu) - // HP: côté à peu près parallèle => les points d'un même côté sont les 1ères paires de même ordre de distance (arbitrairement au max 20% de plus que la 1ère distance) - if ((*it_IndPtCtr1_IndPtCtr2_Dist).second < 1.2*db_Distref) + //Memo de la distance de reference + double db_Distref = (*it_IndPtCtr1_IndPtCtr2_Dist).second; + + //ATTENTION: il faut aussi voir si au moins les 2 premières paires de points ont à peu près la même distance: + // sinon c'est un coin de surf qui est proche d'un autre coin d'une autre surf (pas côte-àcôte sur tout un côté) => ne pas raccorder dans ce cas + list< pair< pair::iterator, vector::iterator>, double>>::iterator it_IndPtCtr1_IndPtCtr2_Dist_Next = it_IndPtCtr1_IndPtCtr2_Dist; + it_IndPtCtr1_IndPtCtr2_Dist_Next++; + if ((*it_IndPtCtr1_IndPtCtr2_Dist_Next).second < 1.2*db_Distref) { - // - //Modification des 2 surfaces => remplacer les paires de points les plus proches par un même point milieu - //HP: les côtés à modifier sont des droites parallèles => remplacement des premières paires repérées par une distance similaire - it_CoordCtr1 = (*it_IndPtCtr1_IndPtCtr2_Dist).first.first; - it_CoordCtr2 = (*it_IndPtCtr1_IndPtCtr2_Dist).first.second; - - double db_NewCoord_X = ((*it_CoordCtr1)[0] + (*it_CoordCtr2)[0]) / 2.0; ++it_CoordCtr1; ++it_CoordCtr2; - double db_NewCoord_Y = ((*it_CoordCtr1)[0] + (*it_CoordCtr2)[0]) / 2.0; ++it_CoordCtr1; ++it_CoordCtr2; - double db_NewCoord_Z = ((*it_CoordCtr1)[0] + (*it_CoordCtr2)[0]) / 2.0; - - *(*((*it_IndPtCtr1_IndPtCtr2_Dist).first.first)) = db_NewCoord_X; - *(*((*it_IndPtCtr1_IndPtCtr2_Dist).first.second)) = db_NewCoord_X; - *(*(++(*it_IndPtCtr1_IndPtCtr2_Dist).first.first)) = db_NewCoord_Y; - *(*(++(*it_IndPtCtr1_IndPtCtr2_Dist).first.second)) = db_NewCoord_Y; - *(*(++(*it_IndPtCtr1_IndPtCtr2_Dist).first.first)) = db_NewCoord_Z; - *(*(++(*it_IndPtCtr1_IndPtCtr2_Dist).first.second)) = db_NewCoord_Z; - }// if ((*it_IndPtCtr1_IndPtCtr2_Dist).second < 1.2*db_Distref) - else - break; - }// for (it_IndPtCtr1_IndPtCtr2_Dist; it_IndPtCtr1_IndPtCtr2_Dist!= li_IndPtCtr1_IndPtCtr2_Dist.end;++it_IndPtCtr1_IndPtCtr2_Dist) - }// if ((*it_IndPtCtr1_IndPtCtr2_Dist).second > db_eps) + //ATTENTION: il faut aussi voir si les 2 paires de points les plus proches ont bien des points distincts entre paires: + // pour (P1,P2) et (P3,P4) il faut P1 différent de P3 et P2 different de P4 + // sinon comme précédemment c'est un coin de surf qui est proche d'un autre coin d'une autre surf (pas côte-àcôte sur tout un côté) et + // qui en plus est une minuscule surface (quasi-ligne) d'où un 2nd point proche du même coin => ne pas raccorder dans ce cas + if ((*it_IndPtCtr1_IndPtCtr2_Dist).first.first != (*it_IndPtCtr1_IndPtCtr2_Dist_Next).first.first + && (*it_IndPtCtr1_IndPtCtr2_Dist).first.second != (*it_IndPtCtr1_IndPtCtr2_Dist_Next).first.second) + { + // + //ATTENTION: Lorsqu'on a 2 minuscules surfaces (quasi-ligne) en côte-à-côte, on peut avoir en plus des 2 paires les plus proches + // 2 autres paires qui sont en fait la croisée des points précédents => il ne faut pas modifier les points de ces paires! + // ------ ------ ------ ------ + // | | et X + // ------ ------ ------ ------ + // Si les points des paires suivants les 2 premières reprennent les points précédents => stopper le raccord + // test à faire paire après paire (et non par doublons de paires) car par exemple il peut y avoir 3 points côte-à-côtes qui se raccordent) + // => on compte le nombre de pairs modifiables (ne reprenant pas un des points des paires précédentes) + int i_MaxNbModifiablePt = 1; + + // + //REMARQUE: Ce test pourrait peut-être servir aussi au test prcdt équivalent mais en terme + //de cas concret le 1er test correspond à un cas identifié un peu différent de celui-ci. + //ici côté en côte-à-côte mais hauteur minuscule, dans cas prcdt ce sont les coins qui sont proches + //De plus le test ici verifie "a posteriori" les raccords, alors que le test prcdt verifie "a priori" pour éviter de commencer un raccord + bool bo_IsModifiable = true; + list< pair< pair::iterator, vector::iterator>, double>>::iterator it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst = it_IndPtCtr1_IndPtCtr2_Dist; + it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst++; + for (it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst; it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst != li_IndPtCtr1_IndPtCtr2_Dist.end(); ++it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst) + { + list< pair< pair::iterator, vector::iterator>, double>>::iterator it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst = it_IndPtCtr1_IndPtCtr2_Dist; + for (it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst; it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst != it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst; ++it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst) + { + if ((*it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst).first.first == (*it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst).first.first + || (*it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst).first.second == (*it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst).first.second) + { + bo_IsModifiable = false; + break; + }// if ((*it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst).first.first == (*it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst).first.first + // || (*it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst).first.second == (*it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst).first.second) + }//for (it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst; it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst != it_IndPtCtr1_IndPtCtr2_Dist_Cur_Tst; ++it_IndPtCtr1_IndPtCtr2_Dist_Prev_Tst) + + if (bo_IsModifiable) + i_MaxNbModifiablePt++; + else + break; + }// for (int icpt = 1; icpt < i_NbModifiedPt; i_NbModifiedPt++) + + //Variable pour compter le nombre de paires de points modifiées + int i_NbModifiedPt = 0; + string str_Header = "Join 2 Surfaces <" + std::string(st_IfcEntCS1->ch_Id) + ">--<" + st_IfcEntCS2->ch_Id + "> :"; + for (it_IndPtCtr1_IndPtCtr2_Dist; it_IndPtCtr1_IndPtCtr2_Dist!= li_IndPtCtr1_IndPtCtr2_Dist.end();++it_IndPtCtr1_IndPtCtr2_Dist) + { + // + // 2 ifcConn séparées Raccord des 2 ifcconn + // par epaisseur mur par leur milieu + // --- --- -------- + // | | => | + // | | | + // --- --- -------- + // + //Remplacement des points les plus proches appartenant à un même côté (par leur point milieu) + // HP: côté à peu près parallèle => les points d'un même côté sont les 1ères paires de même ordre de distance (arbitrairement au max 20% de plus que la 1ère distance) + if ((*it_IndPtCtr1_IndPtCtr2_Dist).second < 1.2*db_Distref) + { + // + // On incrémente le nombre de paires de points modifiées + i_NbModifiedPt++; + + //On applique la relimitation sur les pts milieux que sur les pairs modifiables (ne reprenant pas un des points des paires précédentes) + if (i_NbModifiedPt<=i_MaxNbModifiablePt) + { + //On prend un itérateur intermédiaire pour ne pas interférer avec celui (it_IndPtCtr1_IndPtCtr2_Dist) qui est utilisé pour les tests + list< pair< pair::iterator, vector::iterator>, double>>::iterator it_IndPtCtr1_IndPtCtr2_Dist_Cur = it_IndPtCtr1_IndPtCtr2_Dist; + + //Modification des 2 surfaces => remplacer les paires de points les plus proches par un même point milieu + //HP: les côtés à modifier sont des droites parallèles => remplacement des premières paires repérées par une distance similaire + it_CoordCtr1 = (*it_IndPtCtr1_IndPtCtr2_Dist_Cur).first.first; + it_CoordCtr2 = (*it_IndPtCtr1_IndPtCtr2_Dist_Cur).first.second; + + double db_NewCoord_X = ((*it_CoordCtr1)[0] + (*it_CoordCtr2)[0]) / 2.0; ++it_CoordCtr1; ++it_CoordCtr2; + double db_NewCoord_Y = ((*it_CoordCtr1)[0] + (*it_CoordCtr2)[0]) / 2.0; ++it_CoordCtr1; ++it_CoordCtr2; + double db_NewCoord_Z = ((*it_CoordCtr1)[0] + (*it_CoordCtr2)[0]) / 2.0; + + *(*((*it_IndPtCtr1_IndPtCtr2_Dist_Cur).first.first)) = db_NewCoord_X; + *(*((*it_IndPtCtr1_IndPtCtr2_Dist_Cur).first.second)) = db_NewCoord_X; + *(*(++(*it_IndPtCtr1_IndPtCtr2_Dist_Cur).first.first)) = db_NewCoord_Y; + *(*(++(*it_IndPtCtr1_IndPtCtr2_Dist_Cur).first.second)) = db_NewCoord_Y; + *(*(++(*it_IndPtCtr1_IndPtCtr2_Dist_Cur).first.first)) = db_NewCoord_Z; + *(*(++(*it_IndPtCtr1_IndPtCtr2_Dist_Cur).first.second)) = db_NewCoord_Z; + + str_Header += "\n\tDist(P1,P2)=" + std::to_string((*it_IndPtCtr1_IndPtCtr2_Dist).second) + ";"; + + }// if (bo_DoContinue) + else + { + // + //Consigner le raccord de l'IfcConnectionSurfaceGeometry dans un fichier "log" (ou mettre en mémoire => même principe que pour le fichier bimxbem) + int int_Step = 2; + RecordLog(int_Step, *str_LogFile, str_Header, st_IfcEntCS1); + + break; + }// else if (bo_DoContinue) + }// if ((*it_IndPtCtr1_IndPtCtr2_Dist).second < 1.2*db_Distref) + else + { + // + //Consigner le raccord de l'IfcConnectionSurfaceGeometry dans un fichier "log" (ou mettre en mémoire => même principe que pour le fichier bimxbem) + int int_Step = 2; + RecordLog(int_Step, *str_LogFile, str_Header, st_IfcEntCS1); + + break; + }// else if ((*it_IndPtCtr1_IndPtCtr2_Dist).second < 1.2*db_Distref) + }// for (it_IndPtCtr1_IndPtCtr2_Dist; it_IndPtCtr1_IndPtCtr2_Dist!= li_IndPtCtr1_IndPtCtr2_Dist.end();++it_IndPtCtr1_IndPtCtr2_Dist) + }//if ((*it_IndPtCtr1_IndPtCtr2_Dist).first.first != (*it_IndPtCtr1_IndPtCtr2_Dist_Next).first.first + // && (*it_IndPtCtr1_IndPtCtr2_Dist).first.second != (*it_IndPtCtr1_IndPtCtr2_Dist_Next).first.second) + }// if ((*it_IndPtCtr1_IndPtCtr2_Dist_Next).second < 1.2*db_Distref) + }// if ((*it_IndPtCtr1_IndPtCtr2_Dist).second > db_eps) + }// if ((*it_IndPtCtr1_IndPtCtr2_Dist).second < db_ep_mur_max) return res; } int ifc_TreePostTreatment::TransformEntitiesToWorlCoordFrame() { int res = 0; std::map::iterator it_Elem; for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) { if (it_Elem->first->st_PointsDesContours.size() != 0) { //Décompte du nombre de coord de points size_t i_Size = 0; list > ::iterator it_llPt; for (it_llPt = (it_Elem->first->st_PointsDesContours).begin(); it_llPt != (it_Elem->first->st_PointsDesContours).end(); it_llPt++) i_Size += it_llPt->size(); //Allocation mémoire pour recueillir les coordonnées des points à modifier double * db_CoordPts = new double[i_Size]; //Boucle sur les listes de coord int i = 0; for (it_llPt = (it_Elem->first->st_PointsDesContours).begin(); it_llPt != (it_Elem->first->st_PointsDesContours).end(); it_llPt++) { //lire la liste des points list ::iterator it_lPt; for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) { db_CoordPts[i] = *(*it_lPt); i++; }// for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) }// for (it_llPt = (it_Elem->first->st_PointsDesContours).begin(); it_llPt != (it_Elem->first->st_PointsDesContours).end(); it_llPt++) //Changer les coordonnées pour les mettre P/R au referentiel projet res = TransformEntityToWorlCoordFrame(it_Elem->first, db_CoordPts, i_Size); if (res) return res; //Mémoriser dans la structure les points modifiés //A FAIRE //new liste de liste... i = 0; for (it_llPt = (it_Elem->first->st_PointsDesContours).begin(); it_llPt != (it_Elem->first->st_PointsDesContours).end(); it_llPt++) { //new liste... //lire la liste des points list ::iterator it_lPt; for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) { //liste...push_back(db_CoordPts[i]); *(*it_lPt) = db_CoordPts[i]; i++; }// for (it_lPt = (*it_llPt).begin(); it_lPt != (*it_llPt).end(); it_lPt++) //liste de liste...push_back(liste...); }// for (it_llPt = (it_Elem->first->st_PointsDesContours).begin(); it_llPt != (it_Elem->first->st_PointsDesContours).end(); it_llPt++) //it_Elem->first->st_PointsDesContoursRefAbs= liste de liste...; if (db_CoordPts) delete[] db_CoordPts; db_CoordPts = nullptr; }// if (it_Elem->first->st_PointsDesContours.size != 0) }// for (it_Elem = _map_BasifTree.begin(); it_Elem != _map_BasifTree.end(); it_Elem++) return res; } int ifc_TreePostTreatment::TransformEntityToWorlCoordFrame(STRUCT_IFCENTITY *st_IfcEnt, double *&db_CoordPts, size_t int_Size) { int res = 0; //S'il existe db_RelativePlacement sur l'entité en cours on l'applique if (st_IfcEnt->db_RelativePlacement.size() != 0) { list ::iterator it_val = (st_IfcEnt->db_RelativePlacement).begin(); double U1[3]; U1[0] = *(*it_val); it_val++; U1[1] = *(*it_val); it_val++; U1[2] = *(*it_val); it_val++; double U2[3]; U2[0] = *(*it_val); it_val++; U2[1] = *(*it_val); it_val++; U2[2] = *(*it_val); it_val++; double U3[3]; U3[0] = *(*it_val); it_val++; U3[1] = *(*it_val); it_val++; U3[2] = *(*it_val); it_val++; double O[3]; O[0] = *(*it_val); it_val++; O[1] = *(*it_val); it_val++; O[2] = *(*it_val); it_val++; //Coordonnées dans le nouveau repère for (int iCoord = 0; iCoord < int_Size; iCoord += 3) { double db_NewCoordPts[3] = { 0, 0, 0 }; db_NewCoordPts[0] = O[0] + U1[0] * db_CoordPts[iCoord] + U2[0] * db_CoordPts[iCoord + 1] + U3[0] * db_CoordPts[iCoord + 2]; db_NewCoordPts[1] = O[1] + U1[1] * db_CoordPts[iCoord] + U2[1] * db_CoordPts[iCoord + 1] + U3[1] * db_CoordPts[iCoord + 2]; db_NewCoordPts[2] = O[2] + U1[2] * db_CoordPts[iCoord] + U2[2] * db_CoordPts[iCoord + 1] + U3[2] * db_CoordPts[iCoord + 2]; db_CoordPts[iCoord + 0] = db_NewCoordPts[0]; db_CoordPts[iCoord + 1] = db_NewCoordPts[1]; db_CoordPts[iCoord + 2] = db_NewCoordPts[2]; }// for (int iCoord = 0; iCoord < int_Size; iCoord += 3) }// if (st_IfcEnt->db_RelativePlacement.size != 0) //Remonter les BelongsTo pour appliquer à chaque pas le db_RelativePlacement s'il existe //IMPORTANT: S'il existe 2 BelongsTo (on se trouve au niveau du IfcConnectionSurfaceGeometry) prendre le ifcSpace et non l'élément de construction if (st_IfcEnt->st_BelongsTo.size() == 1) { res = TransformEntityToWorlCoordFrame(*(st_IfcEnt->st_BelongsTo.begin()), db_CoordPts, int_Size); if (res) return res; }// if (st_IfcEnt->st_BelongsTo.size == 1) else if (st_IfcEnt->st_BelongsTo.size() == 2) { list ::iterator it_Elem = (st_IfcEnt->st_BelongsTo).begin(); if (string((*it_Elem)->ch_Type) == "IfcSpace") { res = TransformEntityToWorlCoordFrame((*it_Elem), db_CoordPts, int_Size); if (res) return res; }// if ((*it_Elem)->ch_Type = "IfcSpace") else { it_Elem++; if (string((*it_Elem)->ch_Type) == "IfcSpace") { res = TransformEntityToWorlCoordFrame((*it_Elem), db_CoordPts, int_Size); if (res) return res; }// if (string((*it_Elem)->ch_Type) == "IfcSpace") else res = 4008;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine }// else if ((*it_Elem)->ch_Type = "IfcSpace") }// if (st_IfcEnt->st_BelongsTo.size == 1) else if (st_IfcEnt->st_BelongsTo.size() > 2) res = 4007;//Format erreur: XXXYYY XXX=numero identifiant la routine , YYY=numéro de l'erreur dans cette routine return res; } //Recherche des surfaces IfcConnectionSurfaceGeometry en vis-à-vis et côte-à-côte int ifc_TreePostTreatment::FindFaceToFaceAndSideBySideSurfaces() { int res = 0; //Recherche de tous les elements de construction // => sont sous IfcSpace->st_Contains et ce qui n'est ni IfcConnectionSurfaceGeometry ni IfcProductDefinitionShape std::map map_BuildingElem_Type; std::map::iterator it_Elem1; for (it_Elem1 = _map_BasifTree.begin(); it_Elem1 != _map_BasifTree.end(); it_Elem1++) { if (it_Elem1->second == "IfcSpace") { list ::iterator it_Elem2; for (it_Elem2 = (it_Elem1->first->st_Contains).begin(); it_Elem2 != (it_Elem1->first->st_Contains).end(); it_Elem2++) { //HP: Le contains des spaces est composé de IfcProductDefinitionShape, de IfcConnectionSurfaceGeometry et d'élément de construction - if (string((*it_Elem2)->ch_Type) != "IfcConnectionSurfaceGeometry" && string((*it_Elem2)->ch_Type) != "IfcProductDefinitionShape") - map_BuildingElem_Type[(*it_Elem2)] = (*it_Elem2)->ch_Type; + //Recup des Elements de Construction + if (string((*it_Elem2)->ch_Type) != "IfcConnectionSurfaceGeometry") + { + if(string((*it_Elem2)->ch_Type) != "IfcProductDefinitionShape") + map_BuildingElem_Type[(*it_Elem2)] = (*it_Elem2)->ch_Type; + }// + else + { + //On initialise le set mp_SideBySide pour y mettre le comparatur qui ordonne selon la distance croissante + set>, Comparator> setOfIfcConnSideBySide_Init(_CurrentIfcTree->compFunctor); + (*it_Elem2)->mp_SideBySide = setOfIfcConnSideBySide_Init; + } }// for (it_Elem2 = (it_Elem1->first->st_Contains).begin(); it_Elem2 != (it_Elem1->first->st_Contains).end(); it_Elem2++) }// if (it_Elem1->second == "IfcSpace") }// for (it_Elem1 = _map_BasifTree.begin(); it_Elem1 != _map_BasifTree.end(); it_Elem1++) //Boucle sur les elements de construction - std::map::iterator it_BuildingElem; + map::iterator it_BuildingElem; for (it_BuildingElem = map_BuildingElem_Type.begin(); it_BuildingElem != map_BuildingElem_Type.end(); it_BuildingElem++) { res = FindFaceToFaceAndSideBySideSurfacesOfOneBuildingelement(it_BuildingElem->first); if (res) return res; }// for (it_BuildingElem = map_BuildingElem_Type.begin(); it_BuildingElem != map_BuildingElem_Type.end(); it_BuildingElem++) return res; } //Routine pour trouver sur un même élément de construction // les surfaces en vis à vis (chacun appartenant à un espace différent) // les surfaces côte à côte (chacun appartenant à un même espace) int ifc_TreePostTreatment::FindFaceToFaceAndSideBySideSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcEntBE) { int res = 0; // //Préparations des éléments d'informations nécessaires aux algo de FaceToFace et SideBySide // //Mapping entre les IfcConnectionSurfaceGeometry de l'élément de construction et leur IfcSpace map map_IfcConn_IfcSpace; map map_IfcSpace_NbIfcConn; list ::iterator it_Elem1; list ::iterator it_Elem2; for (it_Elem1 = (st_IfcEntBE->st_Contains).begin(); it_Elem1 != (st_IfcEntBE->st_Contains).end(); it_Elem1++) { for (it_Elem2 = ((*it_Elem1)->st_BelongsTo).begin(); it_Elem2 != ((*it_Elem1)->st_BelongsTo).end(); it_Elem2++) { if (string((*it_Elem2)->ch_Type) == "IfcSpace") { map_IfcConn_IfcSpace[(*it_Elem1)] = (*it_Elem2); map_IfcSpace_NbIfcConn[(*it_Elem2)] += 1; }// if (string((*it_Elem2)->ch_Type) == "IfcSpace") }// for (it_Elem2 = ((*it_Elem1)->st_BelongsTo).begin(); it_Elem2 != ((*it_Elem1)->st_BelongsTo).end(); it_Elem2++) }// for (it_Elem1 = (st_IfcEntBE->st_Contains).begin(); it_Elem1 != (st_IfcEntBE->st_Contains).end(); it_Elem1++) // //Calcul des distances entre centre de gravité de chaque paire de IfcConnectionSurfaceGeometry // li_IfcConn_IfcConn_Dist[IfcConnectionSurfaceGeometry1, IfcConnectionSurfaceGeometry2]=distance // Utilisation d'une liste pour profiter du tri optimisée "list::sort()" list< pair< pair, double>> li_IfcConn_IfcConn_Dist; //Boucle sur st_Contains pour retrouver tous les IfcConnectionSurfaceGeometry for (it_Elem1 = (st_IfcEntBE->st_Contains).begin(); it_Elem1 != (st_IfcEntBE->st_Contains).end(); it_Elem1++) { //Calculer distance entre chaque IfcConnectionSurfaceGeometry de l'élément de construction // même si appartiennent à même ifcspace => utile pour les SideBySide it_Elem1++; for (it_Elem2 = it_Elem1, it_Elem1--; it_Elem2 != (st_IfcEntBE->st_Contains).end(); it_Elem2++) { //Calcul distance des isobarycentres std::vector vc_CentroidElem1((*it_Elem1)->db_Centroid.begin(), (*it_Elem1)->db_Centroid.end()); std::vector vc_CentroidElem2((*it_Elem2)->db_Centroid.begin(), (*it_Elem2)->db_Centroid.end()); double db_dist = ComputePtPtDistance(vc_CentroidElem1, vc_CentroidElem2); //Init de la carte qui indiquera si la paire d'IfcConnectionSurfaceGeometry en index n'est pas cote à cote //map_CanBeSideBySide[std::make_pair((*it_Elem1), (*it_Elem2))] = true; //Memo de la distance entre les 2 IfcConnectionSurfaceGeometry (*it_Elem1) et (*it_Elem2) li_IfcConn_IfcConn_Dist.push_back(std::make_pair(std::make_pair((*it_Elem1), (*it_Elem2)), db_dist)); //}// if (map_IfcConn_IfcSpace[(*it_Elem1)] != map_IfcConn_IfcSpace[(*it_Elem2)]) }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) }// for (it_Elem = (st_IfcEnt->st_Contains).begin(); it_Elem != (st_IfcEnt->st_Contains).end(); it_Elem++) //Trier les paires par proximité pour trouver les surfaces en "vis à vis" et celles "côte à côte" (sur un même élément de construction) li_IfcConn_IfcConn_Dist.sort([](auto lhs, auto rhs) { return lhs.second < rhs.second; }); // //Détection des IfcConnectionSurfaceGeometry en vis-à-vis res = FindFaceToFaceSurfacesOfOneBuildingelement(st_IfcEntBE, map_IfcConn_IfcSpace, li_IfcConn_IfcConn_Dist); if (res) return res; // //Détection des IfcConnectionSurfaceGeometry en côte-à-côte res = FindSideBySideSurfacesOfOneBuildingelement(st_IfcEntBE, map_IfcConn_IfcSpace, li_IfcConn_IfcConn_Dist, map_IfcSpace_NbIfcConn); return res; } -//bool compare_dist(const pair< pair, double> &first, const pair< pair, double> &second) -//bool ifc_TreePostTreatment::compare_dist(const pair< pair, double> &first, const pair< pair, double> &second) -//{ -// if (first.second < second.second) -// return true; -// return false; -//} - //Algo pour détecter les IfcConnectionSurfaceGeometry en vis-à-vis // st_IfcEntBE est l'élément de construction en cours (on utilise son épaisseur pour éviter des faux positifs) // map_IfcConn_IfcSpace associe un IfcConnectionSurfaceGeometry (de l'élément de construction en cours) avec son IfcSpace (utiliser pour ne pas associer 2 IfcConnectionSurfaceGeometry du même IfcSpace) // li_IfcConn_IfcConn_Dist: liste de paire d'IfcConnectionSurfaceGeometry ORDONNEE en fonction de leur distance (permet de déterminer les vis-à-vis) int ifc_TreePostTreatment::FindFaceToFaceSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcEntBE, map &map_IfcConn_IfcSpace, list< pair< pair, double>> &li_IfcConn_IfcConn_Dist) { int res = 0; //Surfaces en vis à vis (sur un même élément de construction) //Repérer les surfaces les plus proches et en vis à vis (=distance centre de gravite < 2*epaisseur mur) std::map map_IsEntityFound; for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) { //Si les 2 IfcConnectionSurfaceGeometry appartiennent à des ifcspace différent=> on continue (sinon on passe à une autre pair) if (map_IfcConn_IfcSpace[(*it).first.first] != map_IfcConn_IfcSpace[(*it).first.second]) { //Si les 2 IfcConnectionSurfaceGeometry n'ont pas encore touvé leur vis à vis => on continue (sinon on passe à une autre pair) if (!map_IsEntityFound[(*it).first.first] && !map_IsEntityFound[(*it).first.second]) { //la distance entre 2 surfaces en vis a vis est environ l'epaisseur du mur //par contre s'il n'y a pas de mur en vis a vis (mur exterieur) les plus proches peuvent etre des surface cote à cote et non en vis a vis // => le "if" qui suit permet d'exclure ce genre de faux positifs (cra distance des centre de gravité sont de distance > à epaisseur) double db_cp = (*it).second; double db_rd = std::stod(st_IfcEntBE->map_DefValues->at("Width")); if ((*it).second < 2 * std::stod(st_IfcEntBE->map_DefValues->at("Width"))) { (*it).first.first->st_FaceToFace.push_back((*it).first.second); (*it).first.second->st_FaceToFace.push_back((*it).first.first); map_IsEntityFound[(*it).first.first] = true; map_IsEntityFound[(*it).first.second] = true; }// if ((*it).second < 2*std::stod(st_IfcEnt->map_DefValues->at("Width"))) }// if (!map_IsEntityFound[(*it).first.first] && !map_IsEntityFound[(*it).first.second]) }// if (map_IfcConn_IfcSpace[(*it).first.first] != map_IfcConn_IfcSpace[(*it).first.second]) }// for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) return res; } //Algo pour détecter les IfcConnectionSurfaceGeometry côte-à-côte // st_IfcEntBE est l'élément de construction en cours (n'est pas utilisé mais si besoin pourrait l'être...) // map_IfcConn_IfcSpace associe un IfcConnectionSurfaceGeometry (de l'élément de construction en cours) avec son IfcSpace (utiliser pour ne pas associer des IfcConnectionSurfaceGeometry d'IfcSpaces différents) -// li_IfcConn_IfcConn_Dist: liste de paire d'IfcConnectionSurfaceGeometry ORDONNEE en fonction de leur distance (permet de déterminer les côte-à-côte) +// li_IfcConn_IfcConn_Dist: liste de paire d'IfcConnectionSurfaceGeometry (de l'élément de construction en cours) ORDONNEE en fonction de leur distance (permet de déterminer les côte-à-côte) // map_IfcSpace_NbIfcConn détermine le nombre d'IfcConnectionSurfaceGeometry par IfcSpace (permet à la fois de boucler sur les ifcSpaces et de déterminer "l'algo" en fonction du nombre d'IfcConnectionSurfaceGeometry) int ifc_TreePostTreatment::FindSideBySideSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcEntBE, map &map_IfcConn_IfcSpace, list< pair< pair, double>> &li_IfcConn_IfcConn_Dist, map &map_IfcSpace_NbIfcConn) { int res = 0; //Surfaces côte à côte (sur un même élément de construction) //Paires de Surfaces les plus proches qui ne soient pas en vis à vis et appartenant à un même espace //Repérer les paires de surfaces appartenant à même espace - //Cas triviaux: - // - S'il n'y a que 1 surface pas de côte à côte - // - S'il n'y a que 2 surfaces => 1 seule paire côte à côte - // - S'il y a strictement plus que 2 surfaces - // => A1) prendre la 1ere paire la plus proche à "iso-espace" = (S1 et S2) - // => A2) prendre la 2ème paire la plus proche contenant S1 = (S1 et S3) - // => A3) prendre la 3ème paire (S2 et S3) - // A1 et A2 => dist (S1 et S3) > (S1 et S2) - // A3 => soit dist (S2 et S3) > (S1 et S3) implique S1 au milieu de S2 et S3 - // => soit dist (S2 et S3) < (S1 et S3) implique S2 au milieu de S1 et S3 (dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide) - // - // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) - // A1) S1--S2 - // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) - // - // Le processus A1, A2 et A3 est à répéter en excluant la surface ayant déjà ses 2 SideBySide - // => a priori pour 3 surfaces d'un même espace processus à faire 1 fois, pour 4 surfaces 2 fois, pour N surfaces N-2 fois map ::iterator mp_Space; for (mp_Space = map_IfcSpace_NbIfcConn.begin(); mp_Space != map_IfcSpace_NbIfcConn.end(); mp_Space++) { - // - //USECASE à 2 IfcConnectionSurfaceGeometry par ifcSpace - if ((*mp_Space).second == 2) - { - for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) - { - //Si les 2 IfcConnectionSurfaceGeometry appartiennent à 1 même ifcspace => on continue - if (map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) - { - //Si les 2 IfcConnectionSurfaceGeometry appartiennent au même ifcspace en cours => on continue - if (map_IfcConn_IfcSpace[(*it).first.first] == (*mp_Space).first) - { - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - - (*it).first.first->mp_SideBySide[(*it).first.second]=false; - (*it).first.second->mp_SideBySide[(*it).first.first]=false; - - //Il n'y a que 2 IfcConnectionSurfaceGeometry => on peut arrêter la boucle sur les pairs - break; - }// if (map_IfcConn_IfcSpace[(*it).first.first] == (*mp_Space).first) - }// if (map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) - }//for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) - }// if ((*mp_Space).second == 2) - // - //USECASE à plus de 2 IfcConnectionSurfaceGeometry par ifcSpace - else if ((*mp_Space).second > 2) + for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) { - //Recherche des 3 pairs it, it2 et it3 d'IfcConnectionSurfaceGeometry appartenant au même IfcSpace en cours - //BOUCLE POUR CHERCHER it - list< pair< pair, double>>::iterator it; - list< pair< pair, double>>::iterator it2; - list< pair< pair, double>>::iterator it3; - for (it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); it++) + //Si les 2 IfcConnectionSurfaceGeometry appartiennent à 1 même ifcspace => on continue + if (map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) { - bool bo_AreTheTwoPairsFound = false; - //it=S1-S2? //Si les 2 IfcConnectionSurfaceGeometry appartiennent au même ifcspace en cours => on continue - //bool bo_CanBeSideBySide = map_CanBeSideBySide[std::make_pair((*it).first.first, (*it).first.second)]; - if ((map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) && (map_IfcConn_IfcSpace[(*it).first.first] == (*mp_Space).first)) + if (map_IfcConn_IfcSpace[(*it).first.first] == (*mp_Space).first) { - //A ce stade, on a la 1ere paire d'ifcConn it=S1-S2, on cherche la prochaine paire la plus proche (it2=S1-S3 ou it2=S3-S1) - //BOUCLE POUR CHERCHER it2 - //it++; - //for (it2 = it, it--; it2 != li_IfcConn_IfcConn_Dist.end(); it2++) - for (it2 = li_IfcConn_IfcConn_Dist.begin(); it2 != li_IfcConn_IfcConn_Dist.end(); it2++) - { - //it2=S1-S3? - //Si la 1ere IfcConnectionSurfaceGeometry de it2 est S1 et si la 2nde IfcConn (S3) appartient au même ifcspace => on continue - if ((it2 != it) && (*it2).first.first == (*it).first.first && map_IfcConn_IfcSpace[(*it2).first.second] == (*mp_Space).first) - { - //A ce stade, on a les 2 paires d'ifcConn it=S1-S2 et it2=S1-S3, on cherche la derniere paire it3=S2-S3 ou it3=S3-S2 - //BOUCLE POUR CHERCHER it3 - //it2++; - //for (it3 = it2, it2--; it3 != li_IfcConn_IfcConn_Dist.end(); it3++) - for (it3 = li_IfcConn_IfcConn_Dist.begin(); it3 != li_IfcConn_IfcConn_Dist.end(); it3++) - { - //it3=S2-S3? - //Si la 1ere IfcConnectionSurfaceGeometry de it3 est S2 et la 2nde de it3 est S3 => on a les 3 paires pour renseigner les SideBySide - if ((*it3).first.first == (*it).first.second && (*it3).first.second == (*it2).first.second) - { - //A ce stade, on a les 3 paires d'ifcConn it=S1-S2 , it2=S1-S3, it3=S2-S3 - //avec les conditions: S1-S2 < S1-S3 - // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) - // A1) S1--S2 - // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) - - // Si S2-S3 < S1-S3 => S2 entre S1 et S3 (S1-S2-S3) - if ((*it3).second<(*it2).second) - { - - ////S1->sideBySide(S2) - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - - ////S2->sideBySide(S1) - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - ////S2->sideBySide(S3) - //(*it).first.second->st_SideBySide.push_back((*it2).first.second); - - ////S3->sideBySide(S2) - //(*it2).first.second->st_SideBySide.push_back((*it).first.second); - - //S1->sideBySide(S2) - (*it).first.first->mp_SideBySide[(*it).first.second]=false; - - //S2->sideBySide(S1) - (*it).first.second->mp_SideBySide[(*it).first.first] = false; - //S2->sideBySide(S3) - (*it).first.second->mp_SideBySide[(*it2).first.second] = false; - - //S3->sideBySide(S2) - (*it2).first.second->mp_SideBySide[(*it).first.second] = false; - - //Indication que S1 et S3 ne peuvent pas être cote à cote - //map_CanBeSideBySide[std::make_pair((*it).first.first, (*it2).first.second)] = false; - bo_AreTheTwoPairsFound = true; - }// if ((*it3).second<(*it2).second) - - // Si S2-S3 > S1-S3 => S1 entre S2 et S3 (S3-S1-S2) - if ((*it3).second>(*it2).second) - { - ////S3->sideBySide(S1) - //(*it2).first.second->st_SideBySide.push_back((*it).first.first); - - ////S1->sideBySide(S3) - //(*it).first.first->st_SideBySide.push_back((*it2).first.second); - ////S1->sideBySide(S2) - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - - ////S2->sideBySide(S1) - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - - //S3->sideBySide(S1) - (*it2).first.second->mp_SideBySide[(*it).first.first] = false; - - //S1->sideBySide(S3) - (*it).first.first->mp_SideBySide[(*it2).first.second] = false; - //S1->sideBySide(S2) - (*it).first.first->mp_SideBySide[(*it).first.second] = false; - - //S2->sideBySide(S1) - (*it).first.second->mp_SideBySide[(*it).first.first] = false; - - //Indication que S2 et S3 ne peuvent pas être cote à cote - //map_CanBeSideBySide[std::make_pair((*it).first.second, (*it2).first.second)] = false; - bo_AreTheTwoPairsFound = true; - }// if ((*it3).second>(*it2).second) - }// if ((*it3).first.first == (*it).first.second && (*it3).first.second == (*it2).first.second) - //it3=S3-S2? - //Si la 1ere IfcConnectionSurfaceGeometry de it3 est S3 et la 2nde de it3 est S2 => on a les 3 paires pour renseigner les SideBySide - if ((*it3).first.first == (*it2).first.second && (*it3).first.second == (*it).first.second) - { - //A ce stade, on a les 3 paires d'ifcConn it=S1-S2 , it2=S1-S3, it3=S3-S2 - //avec les conditions: S1-S2 < S1-S3 - // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) - // A1) S1--S2 - // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) - - // Si S3-S2 < S1-S3 => S2 entre S1 et S3 (S1-S2-S3) - if ((*it3).second<(*it2).second) - { - ////S1->sideBySide(S2) - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - - ////S2->sideBySide(S1) - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - ////S2->sideBySide(S3) - //(*it).first.second->st_SideBySide.push_back((*it2).first.second); - - ////S3->sideBySide(S2) - //(*it2).first.second->st_SideBySide.push_back((*it).first.second); - - //S1->sideBySide(S2) - (*it).first.first->mp_SideBySide[(*it).first.second] = false; - - //S2->sideBySide(S1) - (*it).first.second->mp_SideBySide[(*it).first.first] = false; - //S2->sideBySide(S3) - (*it).first.second->mp_SideBySide[(*it2).first.second] = false; - - //S3->sideBySide(S2) - (*it2).first.second->mp_SideBySide[(*it).first.second] = false; - - //Indication que S1 et S3 ne peuvent pas être cote à cote - //map_CanBeSideBySide[std::make_pair((*it).first.first, (*it2).first.second)] = false; - bo_AreTheTwoPairsFound = true; - }// if ((*it3).second<(*it2).second) - - // Si S3-S2 > S1-S3 => S1 entre S2 et S3 (S3-S1-S2) - if ((*it3).second>(*it2).second) - { - ////S3->sideBySide(S1) - //(*it2).first.second->st_SideBySide.push_back((*it).first.first); - - ////S1->sideBySide(S3) - //(*it).first.first->st_SideBySide.push_back((*it2).first.second); - ////S1->sideBySide(S2) - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - - ////S2->sideBySide(S1) - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - - //S3->sideBySide(S1) - (*it2).first.second->mp_SideBySide[(*it).first.first] = false; - - //S1->sideBySide(S3) - (*it).first.first->mp_SideBySide[(*it2).first.second] = false; - //S1->sideBySide(S2) - (*it).first.first->mp_SideBySide[(*it).first.second] = false; - - //S2->sideBySide(S1) - (*it).first.second->mp_SideBySide[(*it).first.first] = false; - - //Indication que S2 et S3 ne peuvent pas être cote à cote - //map_CanBeSideBySide[std::make_pair((*it).first.second, (*it2).first.second)] = false; - bo_AreTheTwoPairsFound = true; - }// if ((*it3).second>(*it2).second) - }// if ((*it3).first.first == (*it2).first.second && (*it3).first.second == (*it).first.second) - - if (bo_AreTheTwoPairsFound) break; - }// for (list< pair< pair, double>>::iterator it3 = it2, it2--; it3 != li_IfcConn_IfcConn_Dist.end(); ++it3) - }// if ((it2 != it) && (*it2).first.first == (*it).first.first && map_IfcConn_IfcSpace[(*it2).first.second] == (*mp_Space).first) - //it2=S3-S1? - //Si la 2nde IfcConnectionSurfaceGeometry de it2 est S1 et si la 1ere IfcConn (S3) appartient au même ifcspace => on continue - if ((it2 != it) && (*it2).first.second == (*it).first.first && map_IfcConn_IfcSpace[(*it2).first.first] == (*mp_Space).first) - { - //A ce stade, on a les 2 paires d'ifcConn it=S1-S2 et it2=S3-S1, on cherche la derniere paire it3=S2-S3 ou it3=S3-S2 - //BOUCLE POUR CHERCHER it3 - it2++; - for (it3 = it2, it2--; it3 != li_IfcConn_IfcConn_Dist.end(); it3++) - { - //it3=S2-S3? - //Si la 1ere IfcConnectionSurfaceGeometry de it3 est S2 et la 2nde de it3 est S3 => on a les 3 paires pour renseigner les SideBySide - if ((*it3).first.first == (*it).first.second && (*it3).first.second == (*it2).first.first) - { - //A ce stade, on a les 3 paires d'ifcConn it=S1-S2 , it2=S3-S1, it3=S2-S3 - //avec les conditions: S1-S2 < S3-S1 - // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) - // A1) S1--S2 - // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) - - // Si S2-S3 < S3-S1 => S2 entre S1 et S3 (S1-S2-S3) - if ((*it3).second<(*it2).second) - { - ////S1->sideBySide(S2) - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - - ////S2->sideBySide(S1) - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - ////S2->sideBySide(S3) - //(*it).first.second->st_SideBySide.push_back((*it2).first.first); - - ////S3->sideBySide(S2) - //(*it2).first.first->st_SideBySide.push_back((*it).first.second); - - //S1->sideBySide(S2) - (*it).first.first->mp_SideBySide[(*it).first.second] = false; - - //S2->sideBySide(S1) - (*it).first.second->mp_SideBySide[(*it).first.first] = false; - //S2->sideBySide(S3) - (*it).first.second->mp_SideBySide[(*it2).first.first] = false; - - //S3->sideBySide(S2) - (*it2).first.first->mp_SideBySide[(*it).first.second] = false; - - //Indication que S1 et S3 ne peuvent pas être cote à cote - //map_CanBeSideBySide[std::make_pair((*it).first.first, (*it2).first.first)] = false; - bo_AreTheTwoPairsFound = true; - }// if ((*it3).second<(*it2).second) - - // Si S2-S3 > S3-S1 => S1 entre S2 et S3 (S3-S1-S2) - if ((*it3).second>(*it2).second) - { - ////S3->sideBySide(S1) - //(*it2).first.first->st_SideBySide.push_back((*it).first.first); - - ////S1->sideBySide(S3) - //(*it).first.first->st_SideBySide.push_back((*it2).first.first); - ////S1->sideBySide(S2) - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - - ////S2->sideBySide(S1) - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - - //S3->sideBySide(S1) - (*it2).first.first->mp_SideBySide[(*it).first.first] = false; - - //S1->sideBySide(S3) - (*it).first.first->mp_SideBySide[(*it2).first.first] = false; - //S1->sideBySide(S2) - (*it).first.first->mp_SideBySide[(*it).first.second] = false; - - //S2->sideBySide(S1) - (*it).first.second->mp_SideBySide[(*it).first.first] = false; - - //Indication que S2 et S3 ne peuvent pas être cote à cote - //map_CanBeSideBySide[std::make_pair((*it).first.second, (*it2).first.first)] = false; - bo_AreTheTwoPairsFound = true; - }// if ((*it3).second>(*it2).second) - }// if ((*it3).first.first == (*it).first.second && (*it3).first.second == (*it2).first.first) - //it3=S3-S2? - //Si la 1ere IfcConnectionSurfaceGeometry de it3 est S3 et la 2nde de it3 est S2 => on a les 3 paires pour renseigner les SideBySide - if ((*it3).first.first == (*it2).first.first && (*it3).first.second == (*it).first.second) - { - //A ce stade, on a les 3 paires d'ifcConn it=S1-S2 , it2=S3-S1, it3=S3-S2 - //avec les conditions: S1-S2 < S3-S1 - // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) - // A1) S1--S2 - // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) - - // Si S3-S2 < S3-S1 => S2 entre S1 et S3 (S1-S2-S3) - if ((*it3).second<(*it2).second) - { - ////S1->sideBySide(S2) - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - - ////S2->sideBySide(S1) - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - ////S2->sideBySide(S3) - //(*it).first.second->st_SideBySide.push_back((*it2).first.first); - - ////S3->sideBySide(S2) - //(*it2).first.first->st_SideBySide.push_back((*it).first.second); - - //S1->sideBySide(S2) - (*it).first.first->mp_SideBySide[(*it).first.second] = false; - - //S2->sideBySide(S1) - (*it).first.second->mp_SideBySide[(*it).first.first] = false; - //S2->sideBySide(S3) - (*it).first.second->mp_SideBySide[(*it2).first.first] = false; - - //S3->sideBySide(S2) - (*it2).first.first->mp_SideBySide[(*it).first.second] = false; - - //Indication que S1 et S3 ne peuvent pas être cote à cote - //map_CanBeSideBySide[std::make_pair((*it).first.first, (*it2).first.first)] = false; - bo_AreTheTwoPairsFound = true; - }// if ((*it3).second<(*it2).second) - - // Si S3-S2 > S3-S1 => S1 entre S2 et S3 (S3-S1-S2) - if ((*it3).second>(*it2).second) - { - ////S3->sideBySide(S1) - //(*it2).first.first->st_SideBySide.push_back((*it).first.first); - - ////S1->sideBySide(S3) - //(*it).first.first->st_SideBySide.push_back((*it2).first.first); - ////S1->sideBySide(S2) - //(*it).first.first->st_SideBySide.push_back((*it).first.second); - - ////S2->sideBySide(S1) - //(*it).first.second->st_SideBySide.push_back((*it).first.first); - - //S3->sideBySide(S1) - (*it2).first.first->mp_SideBySide[(*it).first.first] = false; - - //S1->sideBySide(S3) - (*it).first.first->mp_SideBySide[(*it2).first.first] = false; - //S1->sideBySide(S2) - (*it).first.first->mp_SideBySide[(*it).first.second] = false; - - //S2->sideBySide(S1) - (*it).first.second->mp_SideBySide[(*it).first.first] = false; - - //Indication que S2 et S3 ne peuvent pas être cote à cote - //map_CanBeSideBySide[std::make_pair((*it).first.second, (*it2).first.first)] = false; - bo_AreTheTwoPairsFound = true; - }// if ((*it3).second>(*it2).second) - }// if ((*it3).first.first == (*it2).first.first && (*it3).first.second == (*it).first.second) - - if (bo_AreTheTwoPairsFound) break; - }// for (list< pair< pair, double>>::iterator it3 = it2, it2--; it3 != li_IfcConn_IfcConn_Dist.end(); ++it3) - }// if ((*it2).first.second == (*it).first.first && map_IfcConn_IfcSpace[(*it2).first.first] == (*mp_Space).first) - - if (bo_AreTheTwoPairsFound) break; - }// for (list< pair< pair, double>>::iterator it2 = it, it--; it2 != li_IfcConn_IfcConn_Dist.end(); ++it2) - }// if (map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) - }//for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) - }// else if ((*mp_Space).second > 2) + (*it).first.first->mp_SideBySide.insert(std::make_pair((*it).first.second, std::make_pair((*it).second, false))); + (*it).first.second->mp_SideBySide.insert(std::make_pair((*it).first.first, std::make_pair((*it).second, false))); + + //REMARQUE: + // Si besoin d'optimiser on peut mettre un compteur ici pour compter le nombre de pairs trouvées. + // et mettre un test, pour faire un break, sur le nombre de pairs car il doit y en avoir : ((*mp_Space).second-1)*(*mp_Space).second)/2 + // Pour rappel, map_IfcConn_IfcSpace contient les ifcConn appartenant à un seul mur + //break; + }// if (map_IfcConn_IfcSpace[(*it).first.first] == (*mp_Space).first) + }// if (map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) + }//for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) }// for (mp_Elem1 = map_IfcSpace_NbIfcConn.begin(); mp_Elem1 != map_IfcSpace_NbIfcConn.end(); mp_Elem1++) return res; } double ifc_TreePostTreatment::ComputePtPtDistance(vector &vc_Point1, vector &vc_Point2) { double db_dist = sqrt((*vc_Point2[0] - *vc_Point1[0])*(*vc_Point2[0] - *vc_Point1[0]) + (*vc_Point2[1] - *vc_Point1[1])*(*vc_Point2[1] - *vc_Point1[1]) + (*vc_Point2[2] - *vc_Point1[2])*(*vc_Point2[2] - *vc_Point1[2])); return db_dist; } + +map>::iterator ifc_TreePostTreatment::get_Index_Of_Max(map> &x) +{ + map>::iterator first = x.begin(); + map>::iterator last = x.end(); + + map>::iterator largest = first; + if (first == last) return largest; + while (++first != last) + if ((*largest).second.second<(*first).second.second) + largest = first; + return largest; +} + +//int ifc_TreePostTreatment::SortSideBySideSurfacesOfIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *st_IfcEntCS) +//{ +// int i_Res = 0; +// +// // Declaring the type of Predicate that accepts 2 pairs and return a bool +// //typedef function>, pair>)> Comparator; +// +// // Defining a lambda function to compare two pairs. It will compare two pairs using second field +// //Comparator compFunctor = +// // [](pair> elem1, pair> elem2) +// //{ +// // return elem1.second.first < elem2.second.first; +// //}; +// +// // Declaring a set that will store the pairs using above comparision logic +// //map, Comparator> mapOfIfcConnSideBySide(st_IfcEntCS->mp_SideBySide.begin(), st_IfcEntCS->mp_SideBySide.end(), compFunctor); +// set>, Comparator> setOfIfcConnSideBySide(st_IfcEntCS->mp_SideBySide.begin(), st_IfcEntCS->mp_SideBySide.end(), _CurrentIfcTree->compFunctor); +// +// st_IfcEntCS->mp_SideBySide.swap(setOfIfcConnSideBySide); +// +// // Iterate over a set using range base for loop +// // It will display the items in sorted order of values +// //for (pair> element : setOfIfcConnSideBySide) +// //{ +// // st_IfcEntCS->mp_SideBySide.insert(element); +// //}// for (pair> element : setOfIfcConnSideBySide) +// +// return i_Res; +//} + +//// +//// POUR MEMO (1/2)... +//// +// +//Algo pour détecter les côte-à-côtes (cette détection permet de repérer les surfaces qui sont espacé de l'épaisseurs d'un mur pour les prolonger l'un vers l'autre) +// => ATTENTION: Algo pas fiable si les surfaces ne sont pas distribuer "selon une direction" i.e. s'il y a des surfaces à droite/gauche (1 direction) mais aussi en haut/en bas (2nde direction)!!! +// Par exemple le problème arrive avec les "surfaces quasi-nulles" qui sont bien souvent des quasi-lignes sur différents bords! +//int ifc_TreePostTreatment::FillSideBySideSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcConn_Left, STRUCT_IFCENTITY *st_IfcConn_Middle, STRUCT_IFCENTITY *st_IfcConn_Right, double dbl_Dist_Left_Mid, double dbl_Dist_Mid_Right) +//{ +// int iRes = 0; +// +// // ajouter systematiquement les 2 plus proches et retirer les max si plus de 2 proches! +// //S1->sideBySide(S2) +// st_IfcConn_Left->mp_SideBySide[st_IfcConn_Middle] = std::make_pair(false, dbl_Dist_Left_Mid); +// //S2->sideBySide(S1) +// st_IfcConn_Middle->mp_SideBySide[st_IfcConn_Left] = std::make_pair(false, dbl_Dist_Left_Mid); +// //S2->sideBySide(S3) +// st_IfcConn_Middle->mp_SideBySide[st_IfcConn_Right] = std::make_pair(false, dbl_Dist_Mid_Right); +// //S3->sideBySide(S2) +// st_IfcConn_Right->mp_SideBySide[st_IfcConn_Middle] = std::make_pair(false, dbl_Dist_Mid_Right); +// +// //retirer le max si plus de 2 proches! +// if (st_IfcConn_Middle->mp_SideBySide.size() > 2) +// { +// map>::iterator max_it_f_s = get_Index_Of_Max(st_IfcConn_Middle->mp_SideBySide); +// (*max_it_f_s).first->mp_SideBySide.erase(st_IfcConn_Middle); +// st_IfcConn_Middle->mp_SideBySide.erase(max_it_f_s); +// }// if (st_IfcConn_Middle->mp_SideBySide.size() > 1) +// +// //retirer le max si plus de 2 proches! +// if (st_IfcConn_Left->mp_SideBySide.size() > 2) +// { +// map>::iterator max_it_f_s = get_Index_Of_Max(st_IfcConn_Left->mp_SideBySide); +// (*max_it_f_s).first->mp_SideBySide.erase(st_IfcConn_Left); +// st_IfcConn_Left->mp_SideBySide.erase(max_it_f_s); +// }// if (st_IfcConn_Left->mp_SideBySide.size() > 1) +// +// //retirer le max si plus de 2 proches! +// if (st_IfcConn_Right->mp_SideBySide.size() > 2) +// { +// map>::iterator max_it_f_s = get_Index_Of_Max(st_IfcConn_Right->mp_SideBySide); +// (*max_it_f_s).first->mp_SideBySide.erase(st_IfcConn_Right); +// st_IfcConn_Right->mp_SideBySide.erase(max_it_f_s); +// }// if (st_IfcConn_Right->mp_SideBySide.size() > 1) +// +// return iRes; +//} +//// +//// POUR MEMO (2/2)... +//// +////Algo pour détecter les IfcConnectionSurfaceGeometry côte-à-côte +//// st_IfcEntBE est l'élément de construction en cours (n'est pas utilisé mais si besoin pourrait l'être...) +//// map_IfcConn_IfcSpace associe un IfcConnectionSurfaceGeometry (de l'élément de construction en cours) avec son IfcSpace (utiliser pour ne pas associer des IfcConnectionSurfaceGeometry d'IfcSpaces différents) +//// li_IfcConn_IfcConn_Dist: liste de paire d'IfcConnectionSurfaceGeometry (de l'élément de construction en cours) ORDONNEE en fonction de leur distance (permet de déterminer les côte-à-côte) +//// map_IfcSpace_NbIfcConn détermine le nombre d'IfcConnectionSurfaceGeometry par IfcSpace (permet à la fois de boucler sur les ifcSpaces et de déterminer "l'algo" en fonction du nombre d'IfcConnectionSurfaceGeometry) +//int ifc_TreePostTreatment::FindSideBySideSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcEntBE, map &map_IfcConn_IfcSpace, list< pair< pair, double>> &li_IfcConn_IfcConn_Dist, map &map_IfcSpace_NbIfcConn) +//{ +// int res = 0; +// +// //Surfaces côte à côte (sur un même élément de construction) +// //Paires de Surfaces les plus proches qui ne soient pas en vis à vis et appartenant à un même espace +// //Repérer les paires de surfaces appartenant à même espace +// //Cas triviaux: +// // - S'il n'y a que 1 surface pas de côte à côte +// // - S'il n'y a que 2 surfaces => 1 seule paire côte à côte +// // - S'il y a strictement plus que 2 surfaces +// // => A1) prendre la 1ere paire la plus proche à "iso-espace" = (S1 et S2) +// // => A2) prendre la 2ème paire la plus proche contenant S1 = (S1 et S3) +// // => A3) prendre la 3ème paire (S2 et S3) +// // A1 et A2 => dist (S1 et S3) > (S1 et S2) +// // A3 => soit dist (S2 et S3) > (S1 et S3) implique S1 au milieu de S2 et S3 +// // => soit dist (S2 et S3) < (S1 et S3) implique S2 au milieu de S1 et S3 (dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide) +// // +// // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) +// // A1) S1--S2 +// // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) +// // +// // Le processus A1, A2 et A3 est à répéter en excluant la surface ayant déjà ses 2 SideBySide +// // => a priori pour 3 surfaces d'un même espace processus à faire 1 fois, pour 4 surfaces 2 fois, pour N surfaces N-2 fois +// map ::iterator mp_Space; +// for (mp_Space = map_IfcSpace_NbIfcConn.begin(); mp_Space != map_IfcSpace_NbIfcConn.end(); mp_Space++) +// { +// // +// //USECASE à 2 IfcConnectionSurfaceGeometry par ifcSpace +// if ((*mp_Space).second == 2) +// { +// for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) +// { +// //Si les 2 IfcConnectionSurfaceGeometry appartiennent à 1 même ifcspace => on continue +// if (map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) +// { +// //Si les 2 IfcConnectionSurfaceGeometry appartiennent au même ifcspace en cours => on continue +// if (map_IfcConn_IfcSpace[(*it).first.first] == (*mp_Space).first) +// { +// //(*it).first.first->st_SideBySide.push_back((*it).first.second); +// //(*it).first.second->st_SideBySide.push_back((*it).first.first); +// +// (*it).first.first->mp_SideBySide[(*it).first.second] = std::make_pair(false, (*it).second); +// (*it).first.second->mp_SideBySide[(*it).first.first] = std::make_pair(false, (*it).second); +// +// //Il n'y a que 2 IfcConnectionSurfaceGeometry => on peut arrêter la boucle sur les pairs +// break; +// }// if (map_IfcConn_IfcSpace[(*it).first.first] == (*mp_Space).first) +// }// if (map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) +// }//for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) +// }// if ((*mp_Space).second == 2) +// // +// //USECASE à plus de 2 IfcConnectionSurfaceGeometry par ifcSpace +// else if ((*mp_Space).second > 2) +// { +// //Recherche des 3 pairs it, it2 et it3 d'IfcConnectionSurfaceGeometry appartenant au même IfcSpace en cours +// //BOUCLE POUR CHERCHER it +// list< pair< pair, double>>::iterator it; +// list< pair< pair, double>>::iterator it2; +// list< pair< pair, double>>::iterator it3; +// for (it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); it++) +// { +// bool bo_AreTheTwoPairsFound = false; +// //it=S1-S2? +// //Si les 2 IfcConnectionSurfaceGeometry appartiennent au même ifcspace en cours => on continue +// //bool bo_CanBeSideBySide = map_CanBeSideBySide[std::make_pair((*it).first.first, (*it).first.second)]; +// if ((map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) && (map_IfcConn_IfcSpace[(*it).first.first] == (*mp_Space).first)) +// { +// //A ce stade, on a la 1ere paire d'ifcConn it=S1-S2, on cherche la prochaine paire la plus proche (it2=S1-S3 ou it2=S3-S1) +// //BOUCLE POUR CHERCHER it2 +// //it++; +// //for (it2 = it, it--; it2 != li_IfcConn_IfcConn_Dist.end(); it2++) +// for (it2 = li_IfcConn_IfcConn_Dist.begin(); it2 != li_IfcConn_IfcConn_Dist.end(); it2++) +// { +// //it2=S1-S3? +// //Si la 1ere IfcConnectionSurfaceGeometry de it2 est S1 et si la 2nde IfcConn (S3) appartient au même ifcspace => on continue +// if ((it2 != it) && (*it2).first.first == (*it).first.first && map_IfcConn_IfcSpace[(*it2).first.second] == (*mp_Space).first) +// { +// //A ce stade, on a les 2 paires d'ifcConn it=S1-S2 et it2=S1-S3, on cherche la derniere paire it3=S2-S3 ou it3=S3-S2 +// //BOUCLE POUR CHERCHER it3 +// //it2++; +// //for (it3 = it2, it2--; it3 != li_IfcConn_IfcConn_Dist.end(); it3++) +// for (it3 = li_IfcConn_IfcConn_Dist.begin(); it3 != li_IfcConn_IfcConn_Dist.end(); it3++) +// { +// //it3=S2-S3? +// //Si la 1ere IfcConnectionSurfaceGeometry de it3 est S2 et la 2nde de it3 est S3 => on a les 3 paires pour renseigner les SideBySide +// if ((*it3).first.first == (*it).first.second && (*it3).first.second == (*it2).first.second) +// { +// //A ce stade, on a les 3 paires d'ifcConn it=S1-S2 , it2=S1-S3, it3=S2-S3 +// //avec les conditions: S1-S2 < S1-S3 +// // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) +// // A1) S1--S2 +// // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) +// +// // Si S2-S3 < S1-S3 => S2 entre S1 et S3 (S1-S2-S3) +// if ((*it3).second < (*it2).second) +// { +// //S1---S2---S3 +// int res = FillSideBySideSurfacesOfOneBuildingelement((*it).first.first, (*it).first.second, (*it2).first.second, (*it).second, (*it3).second); +// +// //Indication que S1 et S3 ne peuvent pas être cote à cote +// //map_CanBeSideBySide[std::make_pair((*it).first.first, (*it2).first.second)] = false; +// bo_AreTheTwoPairsFound = true; +// }// if ((*it3).second<(*it2).second) +// +// // Si S2-S3 > S1-S3 => S1 entre S2 et S3 (S3-S1-S2) +// if ((*it3).second>(*it2).second) +// { +// //S3---S1---S2 +// int res = FillSideBySideSurfacesOfOneBuildingelement((*it2).first.second, (*it).first.first, (*it).first.second, (*it2).second, (*it).second); +// +// //Indication que S2 et S3 ne peuvent pas être cote à cote +// //map_CanBeSideBySide[std::make_pair((*it).first.second, (*it2).first.second)] = false; +// bo_AreTheTwoPairsFound = true; +// }// if ((*it3).second>(*it2).second) +// }// if ((*it3).first.first == (*it).first.second && (*it3).first.second == (*it2).first.second) +// +// //it3=S3-S2? +// //Si la 1ere IfcConnectionSurfaceGeometry de it3 est S3 et la 2nde de it3 est S2 => on a les 3 paires pour renseigner les SideBySide +// if ((*it3).first.first == (*it2).first.second && (*it3).first.second == (*it).first.second) +// { +// //A ce stade, on a les 3 paires d'ifcConn it=S1-S2 , it2=S1-S3, it3=S3-S2 +// //avec les conditions: S1-S2 < S1-S3 +// // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) +// // A1) S1--S2 +// // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) +// +// // Si S3-S2 < S1-S3 => S2 entre S1 et S3 (S1-S2-S3) +// if ((*it3).second<(*it2).second) +// { +// //S1---S2---S3 +// int res = FillSideBySideSurfacesOfOneBuildingelement((*it).first.first, (*it).first.second, (*it2).first.second, (*it).second, (*it3).second); +// +// //Indication que S1 et S3 ne peuvent pas être cote à cote +// //map_CanBeSideBySide[std::make_pair((*it).first.first, (*it2).first.second)] = false; +// bo_AreTheTwoPairsFound = true; +// }// if ((*it3).second<(*it2).second) +// +// // Si S3-S2 > S1-S3 => S1 entre S2 et S3 (S3-S1-S2) +// if ((*it3).second>(*it2).second) +// { +// //S3---S1---S2 +// int res = FillSideBySideSurfacesOfOneBuildingelement((*it2).first.second, (*it).first.first, (*it).first.second, (*it2).second, (*it).second); +// +// //Indication que S2 et S3 ne peuvent pas être cote à cote +// //map_CanBeSideBySide[std::make_pair((*it).first.second, (*it2).first.second)] = false; +// bo_AreTheTwoPairsFound = true; +// }// if ((*it3).second>(*it2).second) +// }// if ((*it3).first.first == (*it2).first.second && (*it3).first.second == (*it).first.second) +// +// if (bo_AreTheTwoPairsFound) break; +// }// for (list< pair< pair, double>>::iterator it3 = it2, it2--; it3 != li_IfcConn_IfcConn_Dist.end(); ++it3) +// }// if ((it2 != it) && (*it2).first.first == (*it).first.first && map_IfcConn_IfcSpace[(*it2).first.second] == (*mp_Space).first) +// +// //it2=S3-S1? +// //Si la 2nde IfcConnectionSurfaceGeometry de it2 est S1 et si la 1ere IfcConn (S3) appartient au même ifcspace => on continue +// if ((it2 != it) && (*it2).first.second == (*it).first.first && map_IfcConn_IfcSpace[(*it2).first.first] == (*mp_Space).first) +// { +// //A ce stade, on a les 2 paires d'ifcConn it=S1-S2 et it2=S3-S1, on cherche la derniere paire it3=S2-S3 ou it3=S3-S2 +// //BOUCLE POUR CHERCHER it3 +// it2++; +// for (it3 = it2, it2--; it3 != li_IfcConn_IfcConn_Dist.end(); it3++) +// { +// //it3=S2-S3? +// //Si la 1ere IfcConnectionSurfaceGeometry de it3 est S2 et la 2nde de it3 est S3 => on a les 3 paires pour renseigner les SideBySide +// if ((*it3).first.first == (*it).first.second && (*it3).first.second == (*it2).first.first) +// { +// //A ce stade, on a les 3 paires d'ifcConn it=S1-S2 , it2=S3-S1, it3=S2-S3 +// //avec les conditions: S1-S2 < S3-S1 +// // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) +// // A1) S1--S2 +// // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) +// +// // Si S2-S3 < S3-S1 => S2 entre S1 et S3 (S1-S2-S3) +// if ((*it3).second<(*it2).second) +// { +// //S1---S2---S3 +// int res = FillSideBySideSurfacesOfOneBuildingelement((*it).first.first, (*it).first.second, (*it2).first.first, (*it).second, (*it3).second); +// +// //Indication que S1 et S3 ne peuvent pas être cote à cote +// //map_CanBeSideBySide[std::make_pair((*it).first.first, (*it2).first.first)] = false; +// bo_AreTheTwoPairsFound = true; +// }// if ((*it3).second<(*it2).second) +// +// // Si S2-S3 > S3-S1 => S1 entre S2 et S3 (S3-S1-S2) +// if ((*it3).second>(*it2).second) +// { +// //S3---S1---S2 +// int res = FillSideBySideSurfacesOfOneBuildingelement((*it2).first.first, (*it).first.first, (*it).first.second, (*it2).second, (*it).second); +// +// //Indication que S2 et S3 ne peuvent pas être cote à cote +// //map_CanBeSideBySide[std::make_pair((*it).first.second, (*it2).first.first)] = false; +// bo_AreTheTwoPairsFound = true; +// }// if ((*it3).second>(*it2).second) +// }// if ((*it3).first.first == (*it).first.second && (*it3).first.second == (*it2).first.first) +// //it3=S3-S2? +// //Si la 1ere IfcConnectionSurfaceGeometry de it3 est S3 et la 2nde de it3 est S2 => on a les 3 paires pour renseigner les SideBySide +// if ((*it3).first.first == (*it2).first.first && (*it3).first.second == (*it).first.second) +// { +// //A ce stade, on a les 3 paires d'ifcConn it=S1-S2 , it2=S3-S1, it3=S3-S2 +// //avec les conditions: S1-S2 < S3-S1 +// // A2.1) S1-------S3 => dans ce cas S2 aura 2 SideBySide, S1 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S1 et S3 peuvent avoir un autre SideBySide S4) +// // A1) S1--S2 +// // A2.2) S3-------S1 => dans ce cas S1 aura 2 SideBySide, S2 et S3 1 SideBySide (ATTENTION: il faut ajouter les sideBySide car S2 et S3 peuvent avoir un autre SideBySide S4) +// +// // Si S3-S2 < S3-S1 => S2 entre S1 et S3 (S1-S2-S3) +// if ((*it3).second<(*it2).second) +// { +// //S1---S2---S3 +// int res = FillSideBySideSurfacesOfOneBuildingelement((*it).first.first, (*it).first.second, (*it2).first.first, (*it).second, (*it3).second); +// +// //Indication que S1 et S3 ne peuvent pas être cote à cote +// //map_CanBeSideBySide[std::make_pair((*it).first.first, (*it2).first.first)] = false; +// bo_AreTheTwoPairsFound = true; +// }// if ((*it3).second<(*it2).second) +// +// // Si S3-S2 > S3-S1 => S1 entre S2 et S3 (S3-S1-S2) +// if ((*it3).second>(*it2).second) +// { +// //S3---S1---S2 +// int res = FillSideBySideSurfacesOfOneBuildingelement((*it2).first.first, (*it).first.first, (*it).first.second, (*it2).second, (*it).second); +// +// //Indication que S2 et S3 ne peuvent pas être cote à cote +// //map_CanBeSideBySide[std::make_pair((*it).first.second, (*it2).first.first)] = false; +// bo_AreTheTwoPairsFound = true; +// }// if ((*it3).second>(*it2).second) +// }// if ((*it3).first.first == (*it2).first.first && (*it3).first.second == (*it).first.second) +// +// if (bo_AreTheTwoPairsFound) break; +// }// for (list< pair< pair, double>>::iterator it3 = it2, it2--; it3 != li_IfcConn_IfcConn_Dist.end(); ++it3) +// }// if ((*it2).first.second == (*it).first.first && map_IfcConn_IfcSpace[(*it2).first.first] == (*mp_Space).first) +// +// if (bo_AreTheTwoPairsFound) break; +// }// for (list< pair< pair, double>>::iterator it2 = it, it--; it2 != li_IfcConn_IfcConn_Dist.end(); ++it2) +// }// if (map_IfcConn_IfcSpace[(*it).first.first] == map_IfcConn_IfcSpace[(*it).first.second]) +// }//for (list< pair< pair, double>>::iterator it = li_IfcConn_IfcConn_Dist.begin(); it != li_IfcConn_IfcConn_Dist.end(); ++it) +// }// else if ((*mp_Space).second > 2) +// }// for (mp_Elem1 = map_IfcSpace_NbIfcConn.begin(); mp_Elem1 != map_IfcSpace_NbIfcConn.end(); mp_Elem1++) +// +// return res; +//} + + diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.h index 5ebb926..0abe7ab 100644 --- a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.h +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.h @@ -1,60 +1,87 @@ #pragma once #include "ifc_Tree.h" #include +//#include typedef map Map_Basified_Tree; class ifc_TreePostTreatment { public: ifc_TreePostTreatment(ifc_Tree* CurrentIfcTree); ~ifc_TreePostTreatment(); int BasifyTree(Map_Basified_Tree *&map_BasifTree); int CompleteBasifiedTreeFromByTIFCSurfaces(); //Retrait dans les contours (st_PointsDesContours) du derniers point lorsqu'il est égal au 1er (+ consigne bool bo_IsItLoop=true) - int RemoveLastPointOfLoopContours(); + int RemoveLastPointOfLoopContours(string *&str_LogFile); //Calcul des isobarycentres des IfcConnectionSurfaceGeometry int CentroidsComputation(); //Recherche des IfcConnectionSurfaceGeometry en vis-à-vis et côte-à-côte int FindFaceToFaceAndSideBySideSurfaces(); //Relimitation des IfcConnectionSurfaceGeometry en côte-à-côte - int RelimitSideBySideSurfaces(); + int RelimitSideBySideSurfaces(string *&str_LogFile); //Passer dasn le ref du projet int TransformEntitiesToWorlCoordFrame(); //Calcul des surfaces IfcConnectionSurfaceGeometry int ComputeIfcConnectionSurfaceGeometrySurface(); //Creation des TIFCSurfaces (décomposition des éléments de construction en leurs surfaces IfcConnectionSurfaceGeometry vis-à-vis) int CreateTIFCSurfaces(); + //Retrait des IfcConnectionSurfaceGeometry de surfaces inférieures à dbl_Minisurf + int RemoveQuasiNullIfcConnectionSurfaceGeometrySurface(double dbl_Minisurf, string *&str_LogFile); + private: int BasifyTreeFrom(STRUCT_IFCENTITY *&st_IfcTree); int CentroidComputation(STRUCT_IFCENTITY *st_IfcEntCS); - int RelimitSideBySideSurfacesOfMiddleIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *st_IfcEntCS); - int RelimitOneSideBySideSurfaceOfMiddleIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *&st_IfcEntCS1, STRUCT_IFCENTITY *st_IfcEntCS2); + int RelimitSideBySideSurfacesOfOneIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *st_IfcEntCS, string *&str_LogFile); + int RelimitOneSideBySideSurfaceOfOneIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *&st_IfcEntCS1, STRUCT_IFCENTITY *st_IfcEntCS2, string *&str_LogFile); int FindFaceToFaceAndSideBySideSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcEntBE); int FindFaceToFaceSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcEntBE, map &map_IfcConn_IfcSpace, list< pair< pair, double>> &li_IfcConn_IfcConn_Dist); int FindSideBySideSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcEntBE, map &map_IfcConn_IfcSpace, list< pair< pair, double>> &li_IfcConn_IfcConn_Dist, map &map_IfcSpace_NbIfcConn); int TransformEntityToWorlCoordFrame(STRUCT_IFCENTITY *st_IfcEnt, double *&db_CoordPts, size_t int_Size); - int RemoveLastPointOfOneLoopContour(STRUCT_IFCENTITY *st_IfcEnt); + int RemoveLastPointOfOneLoopContour(STRUCT_IFCENTITY *st_IfcEnt, string *&str_LogFile); int ComputeOneIfcConnectionSurfaceGeometrySurface(STRUCT_IFCENTITY *st_IfcEntCS); double ComputeSurfaceFromAContour(vector &vc_PointCoordCtr); int CreateTIFCSurface(STRUCT_IFCENTITY *st_IfcEntCS); + int RemoveOneQuasiNullIfcConnectionSurfaceGeometrySurface(STRUCT_IFCENTITY *st_IfcEntCS, double dbl_Minisurf, string *&str_LogFile); double ComputePtPtDistance(vector &vc_Point1, vector &vc_Point2); + //int SortSideBySideSurfacesOfIfcConnectionSurfaceGeometry(STRUCT_IFCENTITY *st_IfcEntCS); + //int FillSideBySideSurfacesOfOneBuildingelement(STRUCT_IFCENTITY *st_IfcConn_Left, STRUCT_IFCENTITY *st_IfcConn_Middle, STRUCT_IFCENTITY *st_IfcConn_Right, double dbl_Dist_Left_Mid, double dbl_Dist_Mid_Right); + + void RecordLog(int &int_Step, string &str_LogFile, string &str_Header, STRUCT_IFCENTITY *&st_IfcEntCS); + + map>::iterator get_Index_Of_Max(map> &x); //bool compare_dist(const pair< pair, double> &first, const pair< pair, double> &second); Map_Basified_Tree _map_BasifTree; ifc_Tree* _CurrentIfcTree; }; +//template +//map get_max(const map &x) +//{ +// using pairtype = map; +// return *std::max_element(x.begin(), x.end(), [](const pairtype &p1, const pairtype &p2) +// { +// return p1.begin()/*.second.second*/ < p2/*.second.second*/; +// }); +//} + +//template +//bool Comp(map p1, map p2) +//{ +// return p1.