diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a1e6d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,188 @@ +### Windows template +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp +*.exe + +# Windows shortcuts +*.lnk +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/dictionaries +.idea/**/shelf + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-debug/ +cmake-build-release/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C/C++ extensions +*.so +*.dll + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# pyCharm settings +_windows + +# dbnavigator settings +dbnavigator.xml \ No newline at end of file diff --git a/IfcC++/.vs/ifc_BIMxBEMEPFLEngine/v14/.suo b/IfcC++/.vs/ifc_BIMxBEMEPFLEngine/v14/.suo new file mode 100644 index 0000000..56f65f2 Binary files /dev/null and b/IfcC++/.vs/ifc_BIMxBEMEPFLEngine/v14/.suo differ diff --git a/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.exp b/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.exp new file mode 100644 index 0000000..f466134 Binary files /dev/null and b/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.exp differ diff --git a/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.lib b/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.lib new file mode 100644 index 0000000..7aba5f5 Binary files /dev/null and b/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.lib differ diff --git a/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.pdb b/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.pdb new file mode 100644 index 0000000..1c9f082 Binary files /dev/null and b/IfcC++/Debug/ifc_BIMxBEMEPFLEngine.pdb differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine.VC.db b/IfcC++/ifc_BIMxBEMEPFLEngine.VC.db new file mode 100644 index 0000000..6bc546b Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine.VC.db differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine.sln b/IfcC++/ifc_BIMxBEMEPFLEngine.sln new file mode 100644 index 0000000..f058352 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ifc_BIMxBEMEPFLEngine", "ifc_BIMxBEMEPFLEngine\ifc_BIMxBEMEPFLEngine.vcxproj", "{52B57D56-C151-4A90-A68C-D81707A0BF20}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {52B57D56-C151-4A90-A68C-D81707A0BF20}.Debug|x64.ActiveCfg = Debug|x64 + {52B57D56-C151-4A90-A68C-D81707A0BF20}.Debug|x64.Build.0 = Debug|x64 + {52B57D56-C151-4A90-A68C-D81707A0BF20}.Debug|x86.ActiveCfg = Debug|Win32 + {52B57D56-C151-4A90-A68C-D81707A0BF20}.Debug|x86.Build.0 = Debug|Win32 + {52B57D56-C151-4A90-A68C-D81707A0BF20}.Release|x64.ActiveCfg = Release|x64 + {52B57D56-C151-4A90-A68C-D81707A0BF20}.Release|x64.Build.0 = Release|x64 + {52B57D56-C151-4A90-A68C-D81707A0BF20}.Release|x86.ActiveCfg = Release|Win32 + {52B57D56-C151-4A90-A68C-D81707A0BF20}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/LoadDataAtBEMFormat.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/LoadDataAtBEMFormat.obj new file mode 100644 index 0000000..c8b71e7 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/LoadDataAtBEMFormat.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifcXML_File.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifcXML_File.obj new file mode 100644 index 0000000..75d0244 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifcXML_File.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.command.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.command.1.tlog new file mode 100644 index 0000000..4287e90 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.command.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.read.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.read.1.tlog new file mode 100644 index 0000000..840b037 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.read.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.write.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.write.1.tlog new file mode 100644 index 0000000..af9c635 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/CL.write.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.lastbuildstate b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.lastbuildstate new file mode 100644 index 0000000..94d8d7f --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v140:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=8.1 +Debug|Win32|C:\Users\adm_unites\Documents\_InnoSuisse_BIM_BEM\Code_EPFL\ifc_BIMxBEMEPFLEngine\| diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.write.1u.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.write.1u.tlog new file mode 100644 index 0000000..eb33c73 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.write.1u.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.command.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.command.1.tlog new file mode 100644 index 0000000..9ad7f80 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.command.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.read.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.write.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/link.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/unsuccessfulbuild b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMx.52B57D56.tlog/unsuccessfulbuild new file mode 100644 index 0000000..e69de29 diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMxBEMEngine.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMxBEMEngine.obj new file mode 100644 index 0000000..aa52362 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_BIMxBEMEngine.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_Tree.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_Tree.obj new file mode 100644 index 0000000..1db1fa4 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/ifc_Tree.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/vc140.idb b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/vc140.idb new file mode 100644 index 0000000..4cfc6bc Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/vc140.idb differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/vc140.pdb b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/vc140.pdb new file mode 100644 index 0000000..d3ce189 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/Debug/vc140.pdb differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.cpp new file mode 100644 index 0000000..0372042 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.cpp @@ -0,0 +1,694 @@ +#include "LoadDataAtBEMFormat.h" + +#include + +string DEB_KW0_L = "<"; +string DEB_KW1_L = "\t<"; +string DEB_KW2_L = "\t\t<"; +string DEB_KW3_L = "\t\t\t<"; + +string KW_R = ">\n"; + +string FIN_KW0_L = " 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(); + + //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(); + + //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(); + + //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 = 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()); + + *_str_EntitiesDefinitions = _str_ProjectsDefinitions + + _str_SitesDefinitions + + _str_BuildingsDefinitions + + _str_BuildingStoreysDefinitions + + _str_SpacesDefinitions + //+ _str_ProductDefinitionShapesDefinitions + + _str_TIFCSurfacesDefinitions + + _str_TIFCGeo2DDefinitions + + _str_FacesDefinitions + + _str_SubFacesDefinitions + + _str_ConnectionSurfaceGeometriesDefinitions; + + return Res; +} + +void LoadDataAtBEMFormat::OpenSets() +{ + _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() +{ + _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::ConvertIfcEnt(STRUCT_IFCENTITY *&st_IfcEnt, string &str_Balise, string &str_EntsDefinitions, string &str_ContainsName, string &str_InsideContainsName) +{ + int Res = 0; + + // Entête Début + 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 + 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 + str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + "Id=" + st_IfcEnt->ch_Id + KW_R; + + // GlobalId + str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + "GlobalId=" + st_IfcEnt->ch_GlobalId + KW_R; + + // Name + str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + "Name=" + st_IfcEnt->ch_Name + 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 + { + 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++) + { + 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++) + + // // FaceToface + //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++) + //{ + // 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++) + //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; + + //// SideBySide + //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++) + //{ + // string bo_val = ">ch_Id + bo_val + KW_R; + //}// for (it_ElemBool = (st_IfcEnt->mp_SideBySide).begin(); it_ElemBool != (st_IfcEnt->mp_SideBySide).end(); it_ElemBool++) + //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; + + //// Centroid + //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++) + //{ + // 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++) + //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; + + //// TIFCSurface + //str_Balise = _str_LESOSAI_Surface; + //str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; + //if (st_IfcEnt->st_TIFCSurface) + // str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + st_IfcEnt->st_TIFCSurface->ch_Id + KW_R; + //str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; + + 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++) + { + 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++) + + // FaceToface + 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++) + { + 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++) + str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; + + // SideBySide + 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++) + { + string bo_val=">ch_Id + bo_val + KW_R; + }// for (it_ElemBool = (st_IfcEnt->mp_SideBySide).begin(); it_ElemBool != (st_IfcEnt->mp_SideBySide).end(); it_ElemBool++) + str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; + + // Centroid + 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++) + { + 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++) + str_EntsDefinitions = str_EntsDefinitions + FIN_KW2_L + str_Balise + KW_R; + + // TIFCSurface + str_Balise = _str_LESOSAI_Surface; + str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + str_Balise + KW_R; + if(st_IfcEnt->st_TIFCSurface) + str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + st_IfcEnt->st_TIFCSurface->ch_Id + KW_R; + 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++) + { + 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") + str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + "room" + std::to_string(i_Ind) + "=" + (*it_Elem2)->ch_Id + KW_R; + else if(i_Ind==2) + str_EntsDefinitions = str_EntsDefinitions + DEB_KW2_L + "surfType" + "=" + (*it_Elem2)->ch_Type + KW_R; + }// 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 + 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++) + { + 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++) + + 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 + 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=="") + str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + (*it_Elem)->ch_Id + KW_R; + else + str_EntsDefinitions = str_EntsDefinitions + DEB_KW3_L + str_InsideContainsName + "=" + (*it_Elem)->ch_Id + KW_R; + }// 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::SpecificConversionOfContainsForSpace(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; + 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++) + { + 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++) + 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++) + { + 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 + 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::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::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::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::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 new file mode 100644 index 0000000..06112b1 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/LoadDataAtBEMFormat.h @@ -0,0 +1,75 @@ +#pragma once + +#include "ifc_Tree.h" +#include "ifc_TreePostTreatment.h" + +//typedef std::map Map_Basified_Tree; +// +class LoadDataAtBEMFormat +{ +public: + LoadDataAtBEMFormat(); + ~LoadDataAtBEMFormat(); + + int LoadLesosaiFormat(ifc_Tree* CurrentIfcTree); + int GetLesosaiEntitiesNumber(); + int GetLesosaiEntitiesAttributesSize(); + int GetLesosaiEntitiesDefinition(string *&str_EntDef); + + 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 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: + // 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; + + 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"; +}; + diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.cpp new file mode 100644 index 0000000..258948d --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.cpp @@ -0,0 +1,1154 @@ +#include "ifcXML_File.h" + + +ifcXML_File::ifcXML_File() :_hRoot(0), _cl_ifcTree(nullptr)/*, st_IfcTree(nullptr)*/ +{ +} + +ifcXML_File::~ifcXML_File() +{ + // + //Desalloc des données membres de ifcXML_File + if (_cl_ifcTree) + delete _cl_ifcTree; + _cl_ifcTree = nullptr; +} + +ifc_Tree* ifcXML_File::GetData() +{ + return _cl_ifcTree; +} + +int ifcXML_File::LoadFile(char *strFileName) +{ + // + //http://www.grinninglizard.com/tinyxmldocs/classTiXmlDocument.html + TiXmlDocument doc(strFileName); + if (!doc.LoadFile()) + return 1; + + TiXmlHandle hDoc(&doc); + TiXmlElement* pElem = hDoc.FirstChildElement().ToElement(); + + // should always have a valid root but handle gracefully if it does + if (!pElem) + return 2; + //const char *m_name = pElem->Value(); + + // memo root + _hRoot = pElem->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); + + //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(); + + //Recup de l'élément "IfcProject" + pElem = _hRoot.FirstChild("IfcProject").ToElement(); + + //ifcXML_File *cl_ifcFile = this; + // Constitution de l'arbre structure de données BIMxBEM + _cl_ifcTree = new ifc_Tree(); + //STRUCT_IFCENTITY *st_IfcTree = nullptr; + if (_cl_ifcTree) + _cl_ifcTree->BuildTreeFromRoot(pElem/*, st_IfcTree*/, this); + + //IMPORTANT: + // Delete de la structure à faire par le programme appelant apres récup du contenu de la structure + //if (st_IfcTree) + // delete_STRUCT_IFCENTITY(st_IfcTree); + + 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) +{ + // 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 0; +} + +// 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) +{ + // 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 0; +} + +// Lecture d'un attribut enfant d'une entité +int ifcXML_File::ReadOneSpecificValueOfAnEntity(TiXmlElement *pIfcEntity, string &st_Path, string &st_value) +{ + // 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 0; +} + + +///////////////////////////////////////////////////////////////////////////////////////////// +// 1.1) ROUTINES DE SPECIFIQUES DE LECTURE (DES ATTRIBUTS) DE LA DEFINITION D'UNE ENTITE // +///////////////////////////////////////////////////////////////////////////////////////////// + +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" + 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 ... +// + + //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; + int 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 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 0; +} + +// 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) +{ + lpObject = _map_ID_Elmt[RelatedElmt->Attribute("ref")]; + + return 0; +} + +//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 + // + // + + 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(); + + int 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 + // + // + + 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 Res = 0; + 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 + // + // + + 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 Res = 0; + 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 + + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + + string st_Path[2] = { "","" }; + int Res = 0; + + 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 + // + // + + string st_Path[2] = { "","" }; + int Res = 0; + + //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) +{ + // + // + // + // + // + // + // + // + // + // + // + // + // + // + + string st_Path[2] = { "","" }; + int Res = 0; + + //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); + + st_Path[0] = "WorldCoordinateSystem"; + st_Path[1] = "IfcAxis2Placement3D"; + Res = FindOneSpecificLinkedObjectFromFirstLinkPath(lpObjectFound1, st_Path, lpObject); + + return Res; +} + +int ifcXML_File::FindIfcLocalPlacement(TiXmlElement *pElement, TiXmlElement *&lpObject) +{ + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + + string st_Path[2] = { "","" }; + int Res = 0; + + 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 + // + // + // + // + + string st_Path = "Representations"; + list llpObject; + int 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) +{ + 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) + { + int res = 0; + 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 0; +} + +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) +{ + // + // + // + // + // + + string st_Path[2] = { "","" }; + int Res = 0; + + //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 + // + // + + // 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"; + + int 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 + // + // + + // 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"; + + int 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 + // + // + + 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; + int 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; + int 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 0; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// 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 + // + // + // + // + // + // + // + // + // + // + + + // 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 + int Res = ScanAssociateRelatedAndRelatingEnt(pKeyword1, pKeyword2, pKeyword3, pKeyword4); + + return Res; +} + diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.h new file mode 100644 index 0000000..4cbf8fe --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifcXML_File.h @@ -0,0 +1,61 @@ +#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 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 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_BIMxBEMEPFLEngine.vcxproj b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEPFLEngine.vcxproj new file mode 100644 index 0000000..cf9067a --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEPFLEngine.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {52B57D56-C151-4A90-A68C-D81707A0BF20} + Win32Proj + ifc_BIMxBEMEPFLEngine + 8.1 + + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;IFC_BIMXBEMEPFLENGINE_EXPORTS;%(PreprocessorDefinitions) + C:\Users\adm_unites\Documents\_InnoSuisse_BIM_BEM\Code_EPFL\tinyxml_2_6_2\tinyxml;%(AdditionalIncludeDirectories) + + + Windows + true + C:\Users\adm_unites\Documents\_InnoSuisse_BIM_BEM\Code_EPFL\tinyxml_2_6_2\tinyxml\Debugtinyxml;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;IFC_BIMXBEMEPFLENGINE_EXPORTS;%(PreprocessorDefinitions) + C:\Users\adm_unites\Documents\_InnoSuisse_BIM_BEM\Code_EPFL\tinyxml_2_6_2\tinyxml;%(AdditionalIncludeDirectories) + + + Windows + true + C:\Users\adm_unites\Documents\_InnoSuisse_BIM_BEM\Code_EPFL\tinyxml_2_6_2\tinyxml\x64\Debug\tinyxml.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;IFC_BIMXBEMEPFLENGINE_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;IFC_BIMXBEMEPFLENGINE_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEPFLEngine.vcxproj.filters b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEPFLEngine.vcxproj.filters new file mode 100644 index 0000000..a954207 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEPFLEngine.vcxproj.filters @@ -0,0 +1,56 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + + + Fichiers sources + + + Fichiers sources + + + Fichiers sources + + + Fichiers sources + + + Fichiers sources + + + + + Fichiers sources + + + \ No newline at end of file diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.cpp new file mode 100644 index 0000000..90be749 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.cpp @@ -0,0 +1,445 @@ +// +// +/////////////////////////////////////////////////// +// 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; + +void __stdcall ifcxml_BIMxBEMEPFL_LoadXMLFileForBEM(char *chr_FilePath) +{ + //wchar_t buff[64]; + ////swprintf(buff, L"%s", *chr_Val); + //size_t origsize = strlen(chr_FilePath) + 1; + //mbstowcs(buff, chr_FilePath, origsize); + //int msgboxID = MessageBox(NULL, buff, L"value=", MB_ICONWARNING | MB_YESNOCANCEL); + ////std::cout << "Valeur *char = " << *chr_Val << " et &char = " << chr_Val << std::endl; + + //Chargement en mémoire d'une structure générique de données typés BEM (optimisée pour modification) + _iFile = new ifcXML_File(); + int res = _iFile->LoadFile(chr_FilePath); + + //DEB SLC: A FAIRE + //Application d'un changement de referentiel à tous les points finaux (P/R au ref du projet) + + //Complétude des relations (sous-faces avec les spaces,...) + + //Modification de la géométrie + + //Convertit la structure générique de données typés BEM en structure spécifique/explicite BEM (Attendue pour Lesosai) + //_iExplicitBEMData = new ifcTree_To_BEMTree(); + //_iExplicitBEMData->TranslateGenericIfcDataToExplicitBEMData(_iFile->GetTree()); + //FIN SLC: A FAIRE + + return; +} + +void __stdcall ifcxml_BIMxBEMEPFL_UnLoadXMLFileForBEM() +{ + //wchar_t buff[64]; + ////swprintf(buff, L"%s", *chr_Val); + //size_t origsize = strlen(chr_FilePath) + 1; + //mbstowcs(buff, chr_FilePath, origsize); + //int msgboxID = MessageBox(NULL, buff, L"value=", MB_ICONWARNING | MB_YESNOCANCEL); + //std::cout << "Valeur *char = " << *chr_Val << " et &char = " << chr_Val << std::endl; + + // + //Desalloc des données membres ifc_BIMxBEMEngine + if (_iFile) + delete _iFile; + _iFile = nullptr; + + return; +} + +//Fournit le nombre de chacune des structures à passer +void __stdcall ifcxml_BIMxBEMEPFL_GetNumberOfEachEntities(int &iNb_Project, + int &iNb_Site, + int &iNb_Building, + int &iNb_BuildingStorey, + int &iNb_Space, + int &iNb_Face) +{ + // NOT YET IMPLEMENTED + //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(); + int res = _iLesosaiFormat->LoadLesosaiFormat(_iFile->GetData()); + + //Conversion de la structure générique de données typés BEM (optimisée pour modification) au format attendu par Lesosai + res = _iLesosaiFormat->GetLesosaiEntitiesNumber(); +} +//Fournit la dimension de chacun des attributs de chacune des structures à passer +//Voir à fournir en même temps le noms des attributs, si besoin? +void __stdcall ifcxml_BIMxBEMEPFL_GetNumberOfEachAttributesOfEachEntities(int* &iSizeByAttribute_Project, + int* &iSizeByAttribute_Site, + int* &iSizeByAttribute_Building, + int* &iSizeByAttribute_BuildingStorey, + int* &iSizeByAttribute_Space, + int* &iSizeByAttribute_Face) +{ + // NOT YET IMPLEMENTED + int res = _iLesosaiFormat->GetLesosaiEntitiesAttributesSize(); +} + +//Fournit la structure dans une chaine de caractères +void __stdcall ifcxml_BIMxBEMEPFL_GetEntitiesDefinition(const char *&chr_EntDef) +{ + // NOT YET IMPLEMENTED + //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(); + int res = _iLesosaiFormat->LoadLesosaiFormat(_iFile->GetData()); + + //Lecture de la structure Lesosai sous forme de + string *str_EntDef; + res = _iLesosaiFormat->GetLesosaiEntitiesDefinition(str_EntDef); + + //Conversion string en const char* + //const char * chr_Tree = str_EntDef->c_str(); + //chr_EntDef = *chr_Tree; + //chr_EntDef = strdup(chr_Tree); + //if(str_EntDef && 0!=str_EntDef->size()) + chr_EntDef=str_EntDef->c_str(); + + //Ajout du '\0' ? sur const ? +} + + +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////DEBUT///////////////////////////////////////////////// +/////////////////// TEST INTEROPERABILITE Pascal C++ ///////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +//STRUCT_IFCENTITY_TEST *st_IfcTreeTest = nullptr; +// +//int __stdcall functDLL() +//{ +// return 12; +//} +// +//// +//// char <= short <= int <= long/unsigned ptr <= long long +//// Proc 32bits 1 2 4 4 8 +//// Proc 64bits 1 2 4 8 +//// +//// float/bool <= double <= long double +//// Proc 32bits 4 8 12 +//// Proc 64bits 4 8 12 +//// +// +//// +//// INTEGER: short? int? long? long long? +//// +//void __stdcall ifcxml_BIMxBEMEPFL_GetrefInt(int &int_Indice) +//{ +// int_Indice = 1; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_GetptrInt(int *&int_Indice) +//{ +// if(!int_Indice) +// int_Indice = new int(); +// *int_Indice = 2; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_DelptrInt(int *&int_Indice) +//{ +// // condition ternaire=> (y < 10) ? 30 : 40; +// if (int_Indice) +// delete int_Indice; +// int_Indice = nullptr; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_SetvalInt(int int_Indice) +//{ +// wchar_t buff[64]; +// swprintf(buff, L"%d", int_Indice); +// int msgboxID = MessageBox(NULL, buff, L"value=", MB_ICONWARNING | MB_YESNOCANCEL); +// std::cout << "Valeur int = " << int_Indice << std::endl; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_SetptrInt(int *int_Indice) +//{ +// wchar_t buff[64]; +// swprintf(buff, L"%d", *int_Indice); +// int msgboxID = MessageBox(NULL, buff, L"value=", MB_ICONWARNING | MB_YESNOCANCEL); +// std::cout << "Valeur *int = " << *int_Indice << " et &int = " << int_Indice << std::endl; +// return; +//} +// +//// +//// DOUBLE +//// +// +//void __stdcall ifcxml_BIMxBEMEPFL_GetrefDbl(double &dbl_Val) +//{ +// dbl_Val = 1.23456789; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_GetptrDbl(double *&dbl_Val) +//{ +// if (!dbl_Val) +// dbl_Val = new double(); +// *dbl_Val = 9.87654321; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_DelptrDbl(double *&dbl_Val) +//{ +// // condition ternaire=> (y < 10) ? 30 : 40; +// if (dbl_Val) +// delete dbl_Val; +// dbl_Val = nullptr; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_SetvalDbl(double dbl_Val) +//{ +// wchar_t buff[64]; +// swprintf(buff, L"%f", dbl_Val); +// int msgboxID = MessageBox(NULL, buff, L"value=", MB_ICONWARNING | MB_YESNOCANCEL); +// std::cout << "Valeur double = " << dbl_Val << std::endl; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_SetptrDbl(double *dbl_Val) +//{ +// wchar_t buff[64]; +// swprintf(buff, L"%f", *dbl_Val); +// int msgboxID = MessageBox(NULL, buff, L"value=", MB_ICONWARNING | MB_YESNOCANCEL); +// std::cout << "Valeur *double = " << *dbl_Val << " et &double = " << dbl_Val << std::endl; +// return; +//} +// +//// +//// CONST CHAR*, CHAR*, CHAR** +//// +// +//void __stdcall ifcxml_BIMxBEMEPFL_GetrefChr(const char *&chr_Val) +//{ +// std::string mystring = "Hello"; +// chr_Val = mystring.c_str(); +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_GetptrChr(char *&chr_Val) +//{ +// if (!chr_Val) +// chr_Val = new char[5]; +// std::string mystring = "HELL"; +// strncpy(chr_Val, mystring.c_str(), mystring.length()); +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_DelptrChr(char *&chr_Val) +//{ +// // condition ternaire=> (y < 10) ? 30 : 40; +// if (chr_Val) +// delete [] chr_Val; +// chr_Val = nullptr; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_SetptrChr(char *chr_Val) +//{ +// wchar_t buff[64]; +// //swprintf(buff, L"%s", *chr_Val); +// size_t origsize = strlen(chr_Val) + 1; +// mbstowcs(buff, chr_Val, origsize); +// int msgboxID = MessageBox(NULL, buff, L"value=", MB_ICONWARNING | MB_YESNOCANCEL); +// //std::cout << "Valeur *char = " << *chr_Val << " et &char = " << chr_Val << std::endl; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_SetptrptrChr(char **chr_Val) +//{ +// std::cout << "Valeur char = " << chr_Val << std::endl; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_GetptrTabDbl(double *&dbl_Val, int &int_Size) +//{ +// int_Size = 3; +// if (!dbl_Val) +// dbl_Val = new double[int_Size]; +// dbl_Val[0] = 9.87654321; +// dbl_Val[1] = 8.7654321; +// dbl_Val[2] = 7.654321; +// return; +//} +// +// +//// +//// STRUCTURE +//// +// +//void __stdcall ifcxml_BIMxBEMEPFL_Initstr_IfcEntitiesTree() +//{ +// st_IfcTreeTest=new STRUCT_IFCENTITY_TEST; +// InitStructure(st_IfcTreeTest, "11"); +// +// STRUCT_IFCENTITY_TEST *st_IfcBelongTo = new STRUCT_IFCENTITY_TEST; +// InitStructure(st_IfcBelongTo, "22"); +// +// STRUCT_IFCENTITY_TEST *st_IfcBelongTo2 = new STRUCT_IFCENTITY_TEST; +// InitStructure(st_IfcBelongTo2, "33"); +// +// if (st_IfcBelongTo) +// { +// STRUCT_IFCENTITY_TEST ** pst_BelongsTo=new STRUCT_IFCENTITY_TEST*[2]; +// pst_BelongsTo[0] = st_IfcBelongTo; +// pst_BelongsTo[1] = st_IfcBelongTo2; +// +// st_IfcTreeTest->st_BelongsTo= pst_BelongsTo; +// //st_IfcBelongTo->st_Contains.push_back(st_IfcTreeTest); +// }// if (st_IfcBelongTo) +// +// //if (st_IfcBelongTo2) +// //{ +// // st_IfcTreeTest->st_BelongsTo.push_back(st_IfcBelongTo2); +// // st_IfcBelongTo2->st_Contains.push_back(st_IfcTreeTest); +// //}// if (st_IfcBelongTo) +// +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_Getstr_IfcEntitiesTree(STRUCT_IFCENTITY_TEST *&st_IfcTreeTestArg) +//{ +// st_IfcTreeTestArg=st_IfcTreeTest; +// return; +//} +// +//void __stdcall ifcxml_BIMxBEMEPFL_Delstr_IfcEntitiesTree(STRUCT_IFCENTITY_TEST *&st_IfcTreeTestArg, STRUCT_IFCENTITY_TEST* st_IfcCurrentFather) +//{ +// // +// //Descente dans l'arborescence jusqu'aux élément sans enfants (membre "st_Contains" vide) +// //list ::iterator it_Elem; +// //for (it_Elem = (st_IfcTreeTestArg->st_Contains).begin(); it_Elem != (st_IfcTreeTestArg->st_Contains).end(); it_Elem++) +// //{ +// // if ((*it_Elem)) +// // ifcxml_BIMxBEMEPFL_Delstr_IfcEntitiesTree((*it_Elem), st_IfcTreeTestArg); +// //}// for (it_Elem = (st_IfcTreeTestArg->st_Contains).begin(); it_Elem != (st_IfcTreeTestArg->st_Contains).end(); it_Elem++) +// //st_IfcTreeTestArg->st_Contains.clear(); +// +// // +// //Désallocations effectives +// // +// delete[] st_IfcTreeTestArg->ch_GlobalId; st_IfcTreeTestArg->ch_GlobalId = nullptr; +// delete[] st_IfcTreeTestArg->ch_Id; st_IfcTreeTestArg->ch_Id = nullptr; +// delete[] st_IfcTreeTestArg->ch_Name; st_IfcTreeTestArg->ch_Name = nullptr; +// delete[] st_IfcTreeTestArg->ch_Type; st_IfcTreeTestArg->ch_Type = nullptr; +// +// for (int it_l_Points = 0; it_l_Points <2; it_l_Points++) +// { +// delete st_IfcTreeTestArg->st_BelongsTo[it_l_Points]; +// st_IfcTreeTestArg->st_BelongsTo[it_l_Points] = nullptr; +// }// for (it_l_Points = (st_IfcTreeTestArg->db_RelativePlacement).begin(); it_l_Points != (st_IfcTreeTestArg->db_RelativePlacement).end(); it_l_Points++) +// +// for (int it_l_Points = 0; it_l_Points <12; it_l_Points++) +// { +// delete st_IfcTreeTestArg->db_RelativePlacement; +// st_IfcTreeTestArg->db_RelativePlacement = nullptr; +// }// for (it_l_Points = (st_IfcTreeTestArg->db_RelativePlacement).begin(); it_l_Points != (st_IfcTreeTestArg->db_RelativePlacement).end(); it_l_Points++) +// +// //list >::iterator it_ll_Points; +// //for (it_ll_Points = (st_IfcTreeTestArg->st_PointsDesContours).begin(); it_ll_Points != (st_IfcTreeTestArg->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_IfcTreeTestArg->st_PointsDesContours).begin(); it_ll_Points != (st_IfcTreeTestArg->st_PointsDesContours).end(); it_ll_Points++) +// //st_IfcTreeTestArg->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_IfcTreeTestArg) 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_IfcTreeTestArg->st_BelongsTo).begin(); it_ElemInBelong != (st_IfcTreeTestArg->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_IfcTreeTestArg) +// // { +// // (*it_ElemInBelong)->st_Contains.erase(it_ElemInBelongContains); +// // break; +// // }// if ((*it_ElemInBelongContains) == st_IfcTreeTestArg) +// // }// 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_IfcTreeTestArg->st_BelongsTo).begin(); it_ElemInBelong != (st_IfcTreeTestArg->st_BelongsTo).end(); it_ElemInBelong++) +// //st_IfcTreeTestArg->st_BelongsTo.clear(); +// +// delete st_IfcTreeTestArg; st_IfcTreeTestArg = nullptr; +// return; +//} +// +//void InitStructure(STRUCT_IFCENTITY_TEST *&st_IfcTreeTestArg, string str_mod) +//{ +// std::string str1("GlobalID_"); str1 += str_mod; +// char *ch_copy22 = new char[23];//size+1 pour que strncpy mette'\0' +// strncpy(ch_copy22, str1.c_str(), 23); +// st_IfcTreeTestArg->ch_GlobalId = ch_copy22; +// +// std::string str2("LongName_"); str2 += str_mod; +// char *ch_copy255 = new char[256];//size+1 pour que strncpy mette'\0' +// strncpy(ch_copy255, str2.c_str(), 256); +// st_IfcTreeTestArg->ch_Name = ch_copy255; +// +// std::string str3("Id_"); str3 += str_mod; +// char *ch_copy9 = new char[10];//size+1 pour que strncpy mette'\0' +// strncpy(ch_copy9, str3.c_str(), 10); +// st_IfcTreeTestArg->ch_Id = ch_copy9; +// +// std::string str4("Type_"); str4 += str_mod; +// char *ch_copy55 = new char[56];//size+1 pour que strncpy mette'\0' +// strncpy(ch_copy55, str4.c_str(), 56); +// st_IfcTreeTestArg->ch_Type = ch_copy55; +// +// double db_LocalMat[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; +// double *db_Val = new double[12]; +// int i = 0; +// 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[i] = db_LocalMat[i_lin][i_col]; +// i++; +// }// for (int i_lin = 0; i_lin < 3; i_lin++) +// }// for (int i_col = 0; i_col < 4; i_col++) +// st_IfcTreeTestArg->db_RelativePlacement=db_Val;//(db_LocalMat[i_lin][i_col]) +// }// if (db_LocalMat) +//} + +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// +/////////////////// TEST INTEROPERABILITE Pascal C++ ///////////////////////////////// +//////////////////////////////////FIN///////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.h new file mode 100644 index 0000000..68547c4 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_BIMxBEMEngine.h @@ -0,0 +1,108 @@ +// +// +/////////////////////////////////////////////////// +// 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) void __stdcall ifcxml_BIMxBEMEPFL_LoadXMLFileForBEM(char *chr_FilePath); + __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_UnLoadXMLFileForBEM(); + + //Fournit le nombre de chacune des structures à passer + __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetNumberOfEachEntities(int &iNb_Project, + int &iNb_Site, + int &iNb_Building, + int &iNb_BuildingStorey, + int &iNb_Space, + int &iNb_Face); + //Fournit la dimension de chacun des attributs de chacune des structures à passer + //Voir à fournir en même temps le noms des attributs, si besoin? + __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetNumberOfEachAttributesOfEachEntities(int* &iSizeByAttribute_Project, + int* &iSizeByAttribute_Site, + int* &iSizeByAttribute_Building, + int* &iSizeByAttribute_BuildingStorey, + int* &iSizeByAttribute_Space, + int* &iSizeByAttribute_Face); + //Fournit la structure dans une chaine de caractères + __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetEntitiesDefinition(const char *&chr_EntDef); + //__declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetEntitiesDefinition(const char *&chr_EntDef); + + +#ifdef __cplusplus +} +#endif + +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////DEBUT///////////////////////////////////////////////// +/////////////////// TEST INTEROPERABILITE Pascal C++ ///////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// + + +//struct STRUCT_IFCENTITY_TEST { +// const char *ch_GlobalId = nullptr; +// const char *ch_Type = nullptr; +// const char *ch_Id = nullptr; +// const char *ch_Name = nullptr; +// STRUCT_IFCENTITY_TEST** st_BelongsTo=nullptr; +// double* db_RelativePlacement; +// double** st_PointsDesContours; +//}; +// +//#ifdef __cplusplus +//extern "C" { +//#endif +// +// __declspec(dllexport) int __stdcall functDLL(); +// +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetrefInt(int &int_Indice); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetptrInt(int *&int_Indice); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_DelptrInt(int *&int_Indice); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_SetvalInt(int int_Indice); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_SetptrInt(int *int_Indice); +// +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetrefDbl(double &dbl_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetptrDbl(double *&dbl_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_DelptrDbl(double *&dbl_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_SetvalDbl(double dbl_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_SetptrDbl(double *dbl_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetptrTabDbl(double *&dbl_Val,int &int_Size); +// +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetrefChr(const char *&chr_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_GetptrChr(char *&chr_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_DelptrChr(char *&chr_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_SetptrChr(char *chr_Val); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_SetptrptrChr(char **chr_Val); +// +// +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_Initstr_IfcEntitiesTree(); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_Getstr_IfcEntitiesTree(STRUCT_IFCENTITY_TEST *&st_IfcTree); +// __declspec(dllexport) void __stdcall ifcxml_BIMxBEMEPFL_Delstr_IfcEntitiesTree(STRUCT_IFCENTITY_TEST *&st_IfcTree, STRUCT_IFCENTITY_TEST* st_IfcCurrentFather = nullptr); +// +// +// +// +// +//#ifdef __cplusplus +//} +//#endif +// +//void InitStructure(STRUCT_IFCENTITY_TEST *&st_IfcTreeArg, string str_mod); + +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// +/////////////////// TEST INTEROPERABILITE Pascal C++ ///////////////////////////////// +//////////////////////////////////FIN///////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.cpp new file mode 100644 index 0000000..54773bb --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.cpp @@ -0,0 +1,345 @@ +#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); + + //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; + //} + + //char *ch_copy9 = new char[10];//size+1 pour que strncpy mette'\0' + //strncpy(ch_copy9, map_messages["Id"].c_str(), 10); + //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 (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; + } + + 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; +} + +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) + + //PENSER A FAIRE LE DELETE CORRECTEMENT(ATTENTION REFERENCE MULTIPLE) = > ne deleter que les TIFCSurface mais sont referencées dans 2 IfcConnectionSurfaceGeometry + }// if (st_IfcEntCS2 && st_IfcEntCS2->st_TIFCSurface==nullptr) + else + Res = 6; + }// 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 new file mode 100644 index 0000000..034dedf --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.h @@ -0,0 +1,60 @@ +#pragma once + + +#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_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; + 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 map Map_String_ptrSTRUCT_IFCENTITY; + + +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); + +#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 new file mode 100644 index 0000000..d1e7da6 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_Tree.template.h @@ -0,0 +1,553 @@ +template +int ifc_Tree::BuildTreeFromRoot(Type_Elmt_Of_Source *&pElem/*, STRUCT_IFCENTITY *&st_IfcTree*/, Type_Source * const& ifcXmlFile) +{ + //lecture des Id et type de "IfcProject" + Map_String_String m_messages; + int iRes = ifcXmlFile->ReadIdAndTypeOfAnEntity(pElem, m_messages); + + //Recup du positionnement relatif + Type_Elmt_Of_Source *lpObjectPlac = nullptr; + ifcXmlFile->FindIfcGeometricRepresentationContext(pElem, lpObjectPlac); + + //Recup de la matrice de position + double db_LocalMat[3][4]; + ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); + + //Création et Remplissage de la structure de "IfcProject" + _st_IfcTree = new STRUCT_IFCENTITY(); + FillAttributeOf_STRUCT_IFCENTITY(_st_IfcTree, m_messages, db_LocalMat); + + //Recupération chainée des entités successives de "IfcProject" + iRes = BuildTreeFrom(pElem, ifcXmlFile, _st_IfcTree); + + return iRes; +} + +template +int ifc_Tree::BuildTreeFromRelAggregates(list &lpRelatedObjects, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) +{ + //Boucle sur les RelatedObjects de IfcRelAggregates en cours + int res = 0; + list ::iterator it_Elem; + for (it_Elem = lpRelatedObjects.begin(); it_Elem != lpRelatedObjects.end(); it_Elem++) + { + //lecture du contenu des child d'un IfcEntity liés à "IfcProject" + Map_String_String map_messages; + res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_Elem, map_messages); + + //Recup du positionnement relatif + Type_Elmt_Of_Source *lpObjectPlac = nullptr; + ifcXmlFile->FindIfcLocalPlacement(*it_Elem, lpObjectPlac); + + //Recup de la matrice de position + double db_LocalMat[3][4]; + ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); + + //Création et Remplissage de la structure de "IfcEntity" + STRUCT_IFCENTITY * st_IfcContain = new STRUCT_IFCENTITY; + FillAttributeOf_STRUCT_IFCENTITY(st_IfcContain, map_messages, db_LocalMat, &(*st_IfcBelongTo)); + + //Appel Récursif + BuildTreeFrom(*it_Elem, ifcXmlFile, st_IfcContain); + }// for (it_Elem = lpRelatedObjects.begin(); it_Elem != lpRelatedObjects.end(); it_Elem++) + + return res; +} + +template +int ifc_Tree::BuildTreeFromShapeOfSpace(list &lpShape, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) +{ + //Boucle sur les IfcProductDefinitionShape de IfcSpace en cours + int res = 0; + list ::iterator it_ElemShape; + for (it_ElemShape = lpShape.begin(); it_ElemShape != lpShape.end(); it_ElemShape++) + { + //lecture du contenu des child d'un IfcEntity liés à "IfcProject" + Map_String_String map_messages; + res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_ElemShape, map_messages); + + // !!!! IfcProductDefinitionShape n'a pas de LocalPlacement !!!! + + //Création et Remplissage de la structure de "IfcEntity" + STRUCT_IFCENTITY * st_IfcContainRep = new STRUCT_IFCENTITY; + FillAttributeOf_STRUCT_IFCENTITY(st_IfcContainRep, map_messages, nullptr, &(*st_IfcBelongTo)); + + //Appel Récursif + //1/2) A REVOIR Voir à récuperer les data (les n faces) des ifcSpaces...=> cf STRUCT_GEOMDATA_POINTS + //IfcConnectionSurfaceGeometry +int ifc_Tree::BuildTreeFromRelSpaceBoundary(list &lpRelatedBuildingElement, list &lpConnectionSurfaceGeometry, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) +{ + //Boucle à la fois sur les éléments de construction et sur les ConnectionSurfaceGeometry (correspondance unaire 1 <-> 1) + int res = 0; + list ::iterator it_ElemBE; + list ::iterator it_ElemCSG; + for (it_ElemBE = lpRelatedBuildingElement.begin(), it_ElemCSG = lpConnectionSurfaceGeometry.begin(); it_ElemBE != lpRelatedBuildingElement.end() && it_ElemCSG != lpConnectionSurfaceGeometry.end(); it_ElemBE++, it_ElemCSG++) + { + //lecture du contenu des Buildingelements de "IfcSpace" + Map_String_String map_messages; + res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_ElemBE, map_messages); + + //Création (ou recuperation) et Remplissage de la structure du Building Element "IfcWall..." + STRUCT_IFCENTITY * st_IfcContainBE = nullptr; + if (_map_ID_IfcEnt[map_messages["Id"]]) + { + st_IfcContainBE = _map_ID_IfcEnt[map_messages["Id"]]; + FillAttributeOfExisting_STRUCT_IFCENTITY(st_IfcContainBE, map_messages, nullptr, &(*st_IfcBelongTo)); + }// if (_map_ID_IfcEnt[map_messages["Id"]) + else + { + st_IfcContainBE = new STRUCT_IFCENTITY; + _map_ID_IfcEnt[map_messages["Id"]] = st_IfcContainBE; + FillAttributeOf_STRUCT_IFCENTITY(st_IfcContainBE, map_messages, nullptr, &(*st_IfcBelongTo)); + + //lecture du Quantities des Buildingelements de "IfcSpace" + map_messages.clear(); + res = ifcXmlFile->ReadKeyWordsAndValuesOfIfcElementQuantity(*it_ElemBE, map_messages); + FillQuantitiesAttributeOf_STRUCT_IFCENTITY(st_IfcContainBE, map_messages); + + //Fillattribute.... A FAIRE + }// else if (_map_ID_IfcEnt[map_messages["Id"]) + + //lecture du contenu des ConnectionSurfaceGeometry (sous-Faces) de "IfcSpace" + map_messages.clear(); + res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_ElemCSG, map_messages); + + //Création et Remplissage de la structure de "IfcConnectionSurfaceGeometry" + STRUCT_IFCENTITY * st_IfcContainCSG = new STRUCT_IFCENTITY; + FillAttributeOf_STRUCT_IFCENTITY(st_IfcContainCSG, map_messages, nullptr, &(*st_IfcBelongTo), &(*st_IfcContainBE)); + + //Appel Récursif + //2/2) A REVOIR Voir à récuperer les data (les n ss-faces) des ifcSpaces...=> cf STRUCT_GEOMDATA_POINTS + //IfcConnectionSurfaceGeometry +int ifc_Tree::BuildExplicitDataTreeFromIfcConnectionSurfaceGeometry(Type_Elmt_Of_Source* pElem, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) +{ + //Pour IfcConnectionSurfaceGeometry => 1 Sous-Face + + // + // + // + // + // + // + // => a mettre dans identifiant sous-face + // + // + // + // + // + // + // + // + // + ////// 1)/2) => 1=Plan de ref [2=Sous-Surf dans le plan de ref (=> chgmt ref)] + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // 0.9999824492 + // 0.005924630765 + // 0. + // + // + // + ////// 2)/2) => 2=Sous-Surf dans le plan de ref (=> chgmt ref) [1=Plan de ref] + // + // + // + // + // + // false + // + // + // + // continuous + // false + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // 0. + // 6.511503496 + // 0. + // + // + // + + //Recup de repere local P/R reprere global + Type_Elmt_Of_Source *lpObjectPlac = nullptr; + ifcXmlFile->FindIfcCurveBoundedPlanePlacemcent(pElem, lpObjectPlac); + + double db_LocalMat[3][4]; + int Res = ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); + + FillRelativePlacementOf_STRUCT_IFCENTITY(st_IfcBelongTo, db_LocalMat); + + //Recup des points P/R reprere local + list lst_Path_For_SubFace; + lst_Path_For_SubFace.push_back("SurfaceOnRelatingElement");// [1..1] 1 Face => gérer un 1er niveau de listes + lst_Path_For_SubFace.push_back("OuterBoundary");//[1..n] M contours => gerer un 2ème niveau de listes => 1er contour externe ensuite internes ("InnerBoundaries"? => utilité en BEM?? => ignorées pour le moment) + lst_Path_For_SubFace.push_back("Segments"); //[1..n] 1 seul contour (externe) mais contenant plusieurs segments => dans même liste?? + lst_Path_For_SubFace.push_back("ParentCurve"); + list ::iterator it_ElemForPath_SubFace; + it_ElemForPath_SubFace = lst_Path_For_SubFace.begin(); + + // + // "lll" est une liste qui dissocie les IfcPolyline par entités de type (IfcCurveBoundedPlane,...) sous SurfaceOnRelatingElement + // "ll" est une liste qui dissocie les IfcPolyline par entités de type (IfcCompositeCurve,...) sous OuterBoundary + // "l" est une liste d'entités (IfcPolyline,...) sous Segments>ParentCurve (cette liste rassemble la multiplicité de ces Segments>ParentCurve) + list lpObjectSubFace; + list >> lllBoundaryOfSurface_SubFace; + Res = ifcXmlFile->FindObjectFromRefAndPathBy3(pElem, it_ElemForPath_SubFace, lst_Path_For_SubFace.end(), lllBoundaryOfSurface_SubFace, lpObjectSubFace); + + //Recupération des points définissant chaque face + création des faces et assoc avec les "BelongTo" + //Si il y a plus d'une Rep => problème + if (lllBoundaryOfSurface_SubFace.size() > 1) + return 1; + if (lllBoundaryOfSurface_SubFace.size() != lpObjectSubFace.size()) + return 2; + // + //Recup de la Rep + list >> ::iterator it_BoundaryOfSurface = lllBoundaryOfSurface_SubFace.begin(); + // + //Boucle sur les faces de la Rep pour récupérer leurs contours + list ::iterator it_SubFace; + list > ::iterator it_SegmentsOfBoundary; + for (it_SegmentsOfBoundary = (*it_BoundaryOfSurface).begin(), it_SubFace = lpObjectSubFace.begin(); it_SegmentsOfBoundary != (*it_BoundaryOfSurface).end(); it_SegmentsOfBoundary++, it_SubFace++) + { + //lecture du contenu des child d'un IfcEntity liés à "IfcProject" + Map_String_String map_messages; + Res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_SubFace, map_messages); + + list> SubFacePtsCoord;//la list définit un des contours de la face, list> définit les contours de la face + Res = ifcXmlFile->ReadPtsDefiningPolyloopOrPolyline((*it_SegmentsOfBoundary), SubFacePtsCoord); + + //Création et Remplissage de la structure "Sous-Face" + STRUCT_IFCENTITY * st_IfcSubFacGeomRep = new STRUCT_IFCENTITY; + FillGeomAttributeOf_STRUCT_IFCENTITY(st_IfcSubFacGeomRep, SubFacePtsCoord, st_IfcBelongTo, map_messages); + }// for (it_SegmentsOfBoundary = (*it_BoundaryOfSurface).begin(); it_SegmentsOfBoundary != (*it_BoundaryOfSurface).end(); it_SegmentsOfBoundary++) + + return Res; +} + +template +int ifc_Tree::BuildExplicitDataTreeFromIfcProductDefinitionShape(Type_Elmt_Of_Source* pElem, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) +{ + //Pour IfcProductDefinitionShape => n Faces => seul l'IfcShapeRepresentation "Body" est pris en compte! + + // + // + // + // + // + // + // + ////// 1)/2) => 1=Body (=> 6 faces "Polyloops" pour cube) [et 2=FootPrint (Polylines)] + // + // + // + // + // + // Body + // Brep + // + // + // + // + // + ////// 1.1)/1.2) + // + // + // Body + // Model + // + // + // + // model_view + // + // + // + // Model + // 3 + // 1.000000000E-5 + // + // + // + // + // => !! 2 ex:double-wrapper et non 3 + // + // + // + ////// 1.2)/1.2) + // + // + // + // + // + // + // + // + // + // => a mettre dans identifiant face + // => a mettre dans identifiant face + // => a mettre dans identifiant face + // => a mettre dans identifiant face + // => a mettre dans identifiant face + // => a mettre dans identifiant face + // + // + // + // + // + // + // + // + // + // + // + // + // + // true + // + // + // + // + // + // + // + // + // + // + // + ////// 2)/2) => 2=FootPrint (Polylines) [et 1=Body (=> 6 faces "Polyloops" pour cube)] + // + // + // + // + // + // FootPrint + // GeometricCurveSet + // + // + // + // + // + ////// 2.1)/2.2) + // + // + // FootPrint + // Model + // + // + // + // model_view + // + // + ////// 2.2)/2.2) + // + // + // + // + // + // + // + + int Res = 0; + + // + //Recup de l'IfcShapeRepresentation de type BRep + Type_Elmt_Of_Source *lpObjectFound = nullptr; + ifcXmlFile->FindIfcShapeRepresentationBrep(pElem, lpObjectFound); + if (lpObjectFound) + { + //Recup de repere local P/R reprere global + Type_Elmt_Of_Source *lpObjectPlac = nullptr; + ifcXmlFile->FindIfcGeometricRepresentationSubContext(lpObjectFound, lpObjectPlac); + + double db_LocalMat[3][4]; + Res = ifcXmlFile->ReadIfcAxis2Placement3DMatrix(lpObjectPlac, db_LocalMat); + + FillRelativePlacementOf_STRUCT_IFCENTITY(st_IfcBelongTo, db_LocalMat); + + //Recup des points P/R reprere local + list lst_Path_For_BodyFaces; + lst_Path_For_BodyFaces.push_back("Items"); //[1..n] => HP: 1 seul Item pertinent pour BEM?? + lst_Path_For_BodyFaces.push_back("Outer"); + lst_Path_For_BodyFaces.push_back("CfsFaces"); //[1..n] N Faces => gérer un 1er niveau de listes + lst_Path_For_BodyFaces.push_back("Bounds"); //[1..n] M contours => gerer un 2ème niveau de listes => 1er contour externe ensuite internes? + lst_Path_For_BodyFaces.push_back("Bound"); + + list ::iterator it_ElemForPath_BodyFaces; + it_ElemForPath_BodyFaces = lst_Path_For_BodyFaces.begin(); + + // + // "lll" est une liste qui dissocie les IfcPolyLoop par entités de type (IfcFacetedBrep,...) sous Items + // "ll" est une liste qui dissocie les IfcPolyLoop par entités de type (IfcFace,...) sous CfsFaces + // "l" est une liste d'entités (IfcPolyLoop,...) sous Bounds>Bound (cette liste rassemble la multiplicité de ces Bounds>Bound) + list lpObjectFace; + list >> lllCFsFacesOfOneItem_Face; // => liste des BRep (1 seule utile pour BEM??) + Res = ifcXmlFile->FindObjectFromRefAndPathBy3(lpObjectFound, it_ElemForPath_BodyFaces, lst_Path_For_BodyFaces.end(), lllCFsFacesOfOneItem_Face, lpObjectFace); + + //Recupération des points définissant chaque face + création des faces et assoc avec les "BelongTo" + //Si il y a plus d'une Rep => problème + if (lllCFsFacesOfOneItem_Face.size() > 1) + return 1; + if ( (*(lllCFsFacesOfOneItem_Face.begin())).size() != lpObjectFace.size()) + return 2; + // + //Recup de la Rep + list >> ::iterator it_CFsFacesOfOneItem = lllCFsFacesOfOneItem_Face.begin(); + // + //Boucle sur les faces de la Rep pour récupérer leurs contours + list ::iterator it_Face; + list > ::iterator it_BoundsOfOneCFsFace; + for (it_BoundsOfOneCFsFace = (*it_CFsFacesOfOneItem).begin(), it_Face = lpObjectFace.begin(); it_BoundsOfOneCFsFace != (*it_CFsFacesOfOneItem).end(); it_BoundsOfOneCFsFace++, it_Face++) + { + //lecture du contenu des child d'un IfcEntity liés à "IfcProject" + Map_String_String map_messages; + Res = ifcXmlFile->ReadIdAndTypeOfAnEntity(*it_Face, map_messages); + + list> FacePtsCoord;//la list définit un des contours de la face, list> définit les contours de la face + Res = ifcXmlFile->ReadPtsDefiningPolyloopOrPolyline(*it_BoundsOfOneCFsFace, FacePtsCoord); + + //Création et Remplissage de la structure "Face" + STRUCT_IFCENTITY * st_IfcFacGeomRep = new STRUCT_IFCENTITY; + FillGeomAttributeOf_STRUCT_IFCENTITY(st_IfcFacGeomRep, FacePtsCoord, st_IfcBelongTo, map_messages); + }// for (it_BoundsOfOneCFsFace = (*it_CFsFacesOfOneItem).begin(); it_BoundsOfOneCFsFace != (*it_CFsFacesOfOneItem).end(); it_BoundsOfOneCFsFace++) + + }// if(lpObjectFound) + + return Res; +} + +// +/////////////////////////////////////////////////////////////////////////////////// +// Routines intermédiaires "d'aiguillage" mais ne créant pas de structure/entité // +/////////////////////////////////////////////////////////////////////////////////// +// + +template +int ifc_Tree::BuildTreeFrom(Type_Elmt_Of_Source* pElem, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) +{ + // + // IfcRelAggregates + // + //Recuperation des IfcEntity liés à pElem ("IfcProject",ifcSite...) par le lien binaire IfcRelAggregates + list lpRelatedObjects; + int res = ifcXmlFile->FindRelatedObjectsInRelAggregatesFromRelatingObject(pElem, &lpRelatedObjects); + + // Si lpRelatedObjects est vide il n'y a pas d'autre RelAggreg => à priori à partir des ifcspaces + // ???Si lpRelatedObjects est vide il n'y a pas d'autre RelAggreg => essayer alors RelProperties...??? + if (lpRelatedObjects.size() != 0) + { + BuildTreeFromRelAggregates(lpRelatedObjects, ifcXmlFile, &(*st_IfcBelongTo)); + }// if (lpRelatedObjects.size!=0) + else + { + // + //lecture du Quantities des "IfcSpace" + Map_String_String map_messages; + res = ifcXmlFile->ReadKeyWordsAndValuesOfIfcElementQuantity(pElem, map_messages); + FillQuantitiesAttributeOf_STRUCT_IFCENTITY(st_IfcBelongTo, map_messages); + + // + // IfcProductDefinitionShape + // + //récupérer le lien IfcSpace <-> Faces (pas le data geom!) => IfcProductDefinitionShape + //Recuperation de l'IfcEntity (IfcProductDefinitionShape) de "IfcSpace" consigné dans sa definition + list lpShape; + res = ifcXmlFile->FindRepresentationInSpace(pElem, &lpShape); + + BuildTreeFromShapeOfSpace(lpShape, ifcXmlFile, &(*st_IfcBelongTo)); + + // + // IfcRelSpaceBoundary + // + //Recuperation des IfcEntity liés à "IfcSpace" par le lien ternaire IfcRelSpaceBoundary + list lpRelatedBuildingElement; + list lpConnectionSurfaceGeometry; + res = ifcXmlFile->FindRelatedBuildingElementAndConnectionGeometryInRelSpaceBoundaryFromRelatingSpace(pElem, &lpRelatedBuildingElement, &lpConnectionSurfaceGeometry); + + if (lpRelatedBuildingElement.size() != 0 && lpRelatedBuildingElement.size() == lpConnectionSurfaceGeometry.size()) + { + BuildTreeFromRelSpaceBoundary(lpRelatedBuildingElement, lpConnectionSurfaceGeometry, ifcXmlFile, &(*st_IfcBelongTo)); + }// if (lpRelatedBuildingElement.size() != 0 && lpRelatedBuildingElement.size() == lpConnectionSurfaceGeometry.size()) + + }// else if (lpRelatedObjects.size!=0) + + return res; +} + +template +int ifc_Tree::BuildExplicitDataTreeFrom(Type_Elmt_Of_Source* pElem, Type_Source * const& ifcXmlFile, STRUCT_IFCENTITY *st_IfcBelongTo) +{ + int Res = 0; + + //Pour IfcConnectionSurfaceGeometry => 1 Sous-Face + if (string(pElem->Value()) == string("IfcConnectionSurfaceGeometry")) + { + Res = BuildExplicitDataTreeFromIfcConnectionSurfaceGeometry(pElem, ifcXmlFile, st_IfcBelongTo); + }// if (string(pElem->Value()) == string("IfcConnectionSurfaceGeometry")) + + //Pour IfcProductDefinitionShape => n Faces + // + // IMPORTANT (A CONFIRMER): + // HP: 1 Space <=> 1 Shape <=> 1 BRep (utile pour BEM) => N Faces et 1 Face => N contours (1 externe et N-1 internes)???? + // => du coup on élimine shape et BRep pour associer 1 Space à N Faces + // Attention: question => 1 Face peut contenir un contour externe et des contours internes??? + // => gérer liste de listes de points + // => si en général 1 seul contour externe et n internes alors 1ère liste=contour externe et les autres listes=internes + // + if (string(pElem->Value()) == string("IfcProductDefinitionShape")) + { + Res=BuildExplicitDataTreeFromIfcProductDefinitionShape(pElem, ifcXmlFile, st_IfcBelongTo); + }// if (string(pElem->Value()) == string("IfcProductDefinitionShape")) + + return 0; +} + diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.cpp b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.cpp new file mode 100644 index 0000000..4fa214f --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.cpp @@ -0,0 +1,1095 @@ +#include "ifc_TreePostTreatment.h" +//#include +#include + +const double db_eps= 0.00001; + +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; + + STRUCT_IFCENTITY* st_IfcTree = nullptr; + if (_CurrentIfcTree) + { + st_IfcTree =_CurrentIfcTree->Getstruct(); + if (st_IfcTree) + BasifyTreeFrom(st_IfcTree); + else + Res = 2; + + map_BasifTree = &_map_BasifTree; + }// if (_CurrentIfcTree) + else + Res = 1; + + + 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++) + { + BasifyTreeFrom((*it_Elem)); + }// 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() +{ + 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); + }// 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 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; + }// 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); + }// 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 = 3; + + 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; +} + +//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); + }// 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 = 5; + } + else + Res = 4; + + 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); + }// 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 = 5; + + return Res; +} + +int ifc_TreePostTreatment::RelimitSideBySideSurfaces() +{ + int Res = 0; + + 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); + + //Traitement des IfcConnectionSurfaceGeometry ayant 1 côté à étendre + //DEB: SLC A FAIRE 1 sidebyside + + }// 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) +{ + int Res = 0; + + //Retrouver les 2 IfcConnectionSurfaceGeometry qui sont côte-à-côte avec l'IfcConnectionSurfaceGeometry en cours + map ::iterator it_SideBySideIfcEntCS; + //list ::iterator it_SideBySideIfcEntCS; + //for (it_SideBySideIfcEntCS = (st_IfcEntCS->st_SideBySide).begin(); it_SideBySideIfcEntCS != (st_IfcEntCS->st_SideBySide).end(); 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) + { + RelimitOneSideBySideSurfaceOfMiddleIfcConnectionSurfaceGeometry(st_IfcEntCS, (*it_SideBySideIfcEntCS).first); + (*it_SideBySideIfcEntCS).second = true; + (*it_SideBySideIfcEntCS).first->mp_SideBySide[st_IfcEntCS] = 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) +{ + int Res = 0; + + //Recup de toutes les coordonnées de tous les points du 1er contour + 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 + 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 + vector::iterator it_CoordCtr1; + vector::iterator it_CoordCtr2; + for (it_CoordCtr1 = vc_PointCoordCtr1.begin(); it_CoordCtr1 != vc_PointCoordCtr1.end(); ++(++(++it_CoordCtr1))) + { + 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) + { + //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) + { + // + //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) + { + // + //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) + + 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); + + //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) + { + TransformEntityToWorlCoordFrame(*(st_IfcEnt->st_BelongsTo.begin()), db_CoordPts, int_Size); + }// 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") + { + TransformEntityToWorlCoordFrame((*it_Elem), db_CoordPts, int_Size); + }// if ((*it_Elem)->ch_Type = "IfcSpace") + else + { + it_Elem++; + if (string((*it_Elem)->ch_Type) == "IfcSpace") + TransformEntityToWorlCoordFrame((*it_Elem), db_CoordPts, int_Size); + else + Res = 2; + }// else if ((*it_Elem)->ch_Type = "IfcSpace") + }// if (st_IfcEnt->st_BelongsTo.size == 1) + else if (st_IfcEnt->st_BelongsTo.size() > 2) + Res = 1; + + 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; + }// 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; + for (it_BuildingElem = map_BuildingElem_Type.begin(); it_BuildingElem != map_BuildingElem_Type.end(); it_BuildingElem++) + { + Res = FindFaceToFaceAndSideBySideSurfacesOfOneBuildingelement(it_BuildingElem->first); + }// 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 + FindFaceToFaceSurfacesOfOneBuildingelement(st_IfcEntBE, map_IfcConn_IfcSpace, li_IfcConn_IfcConn_Dist); + + // + //Détection des IfcConnectionSurfaceGeometry en côte-à-côte + 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) +// 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) + { + //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->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) + }// for (mp_Elem1 = map_IfcSpace_NbIfcConn.begin(); mp_Elem1 != map_IfcSpace_NbIfcConn.end(); mp_Elem1++) + + //// + ////Retrait des redondances dans le membre SideBySide des IfcConnectionSurfaceGeometry + //for (map::iterator it_Elem1 = map_IfcConn_IfcSpace.begin(); it_Elem1 != map_IfcConn_IfcSpace.end(); it_Elem1++) + //{ + // ((*it_Elem1).first)->st_SideBySide.sort(); + // ((*it_Elem1).first)->st_SideBySide.unique(); + //}// for (map::iterator it_Elem1 = map_IfcConn_IfcSpace.begin(); it_Elem1 != map_IfcConn_IfcSpace.end(); it_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; +} diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.h b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.h new file mode 100644 index 0000000..5ebb926 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/ifc_TreePostTreatment.h @@ -0,0 +1,60 @@ +#pragma once + +#include "ifc_Tree.h" +#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(); + + //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(); + + //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(); + +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 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 ComputeOneIfcConnectionSurfaceGeometrySurface(STRUCT_IFCENTITY *st_IfcEntCS); + double ComputeSurfaceFromAContour(vector &vc_PointCoordCtr); + int CreateTIFCSurface(STRUCT_IFCENTITY *st_IfcEntCS); + + double ComputePtPtDistance(vector &vc_Point1, vector &vc_Point2); + + //bool compare_dist(const pair< pair, double> &first, const pair< pair, double> &second); + + Map_Basified_Tree _map_BasifTree; + ifc_Tree* _CurrentIfcTree; +}; + diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/LoadDataAtBEMFormat.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/LoadDataAtBEMFormat.obj new file mode 100644 index 0000000..0de3b0f Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/LoadDataAtBEMFormat.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifcXML_File.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifcXML_File.obj new file mode 100644 index 0000000..31decac Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifcXML_File.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.command.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.command.1.tlog new file mode 100644 index 0000000..3f28f81 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.command.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.read.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.read.1.tlog new file mode 100644 index 0000000..d4cb8ef Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.read.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.write.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.write.1.tlog new file mode 100644 index 0000000..6798ff9 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/CL.write.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.lastbuildstate b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.lastbuildstate new file mode 100644 index 0000000..559d534 --- /dev/null +++ b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.lastbuildstate @@ -0,0 +1,2 @@ +#TargetFrameworkVersion=v4.0:PlatformToolSet=v140:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=8.1 +Debug|x64|C:\Users\adm_unites\Documents\_InnoSuisse_BIM_BEM\Code_EPFL\BIMxBEM\IfcC++\| diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.write.1u.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.write.1u.tlog new file mode 100644 index 0000000..98de984 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/ifc_BIMxBEMEPFLEngine.write.1u.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.command.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.command.1.tlog new file mode 100644 index 0000000..ac62bb4 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.command.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.read.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.read.1.tlog new file mode 100644 index 0000000..f9b7a56 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.read.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.write.1.tlog b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.write.1.tlog new file mode 100644 index 0000000..0a6425b Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMx.52B57D56.tlog/link.write.1.tlog differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMxBEMEngine.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMxBEMEngine.obj new file mode 100644 index 0000000..734ca4c Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_BIMxBEMEngine.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_Tree.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_Tree.obj new file mode 100644 index 0000000..9ec4abd Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_Tree.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_TreePostTreatment.obj b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_TreePostTreatment.obj new file mode 100644 index 0000000..767c966 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_TreePostTreatment.obj differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_treeposttreatment.obj.enc b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_treeposttreatment.obj.enc new file mode 100644 index 0000000..9811fc0 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/ifc_treeposttreatment.obj.enc differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/loaddataatbemformat.obj.enc b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/loaddataatbemformat.obj.enc new file mode 100644 index 0000000..63102a1 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/loaddataatbemformat.obj.enc differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/vc140.idb b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/vc140.idb new file mode 100644 index 0000000..52a59cf Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/vc140.idb differ diff --git a/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/vc140.pdb b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/vc140.pdb new file mode 100644 index 0000000..2e8b570 Binary files /dev/null and b/IfcC++/ifc_BIMxBEMEPFLEngine/x64/Debug/vc140.pdb differ diff --git a/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.exp b/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.exp new file mode 100644 index 0000000..84e7a53 Binary files /dev/null and b/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.exp differ diff --git a/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.ilk b/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.ilk new file mode 100644 index 0000000..c57a2ab Binary files /dev/null and b/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.ilk differ diff --git a/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.lib b/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.lib new file mode 100644 index 0000000..c8dd14c Binary files /dev/null and b/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.lib differ diff --git a/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.pdb b/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.pdb new file mode 100644 index 0000000..2883f88 Binary files /dev/null and b/IfcC++/x64/Debug/ifc_BIMxBEMEPFLEngine.pdb differ