From 37f7fbecca9d64979f4de573dbcc880f5e3cb301 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 11 Apr 2017 17:26:30 +0200 Subject: [PATCH 01/36] Retrieve the type and the hierarchy of the IFC and write it in the .dae files --- src/ifcconvert/ColladaSerializer.cpp | 16 ++++++++++----- src/ifcconvert/ColladaSerializer.h | 3 ++- src/ifcconvert/IfcConvert.cpp | 29 +++++++++++++++++++++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 6ef394ad2e..9c26211e84 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -34,6 +34,8 @@ #include #include +using namespace IfcSchema; + static void collada_id(std::string &s) { IfcUtil::sanitate_material_name(s); @@ -66,12 +68,12 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write( const std::vector& uvs) { openMesh(mesh_id); - + // The normals vector can be empty for example when the WELD_VERTICES setting is used. // IfcOpenShell does not provide them with multiple face normals collapsed into a single vertex. const bool has_normals = !normals.empty(); const bool has_uvs = !uvs.empty(); - + addFloatSource(mesh_id, COLLADASW::LibraryGeometries::POSITIONS_SOURCE_ID_SUFFIX, positions); if (has_normals) { addFloatSource(mesh_id, COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, normals); @@ -298,14 +300,16 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n asset.setUpAxisType(COLLADASW::Asset::Z_UP); asset.add(); } - +// ******************************** +// NOTE : o->context.parent_id ????????????????? == -1 si pas de parent +// On a un type de product ifcBuildingStorey void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o) { + const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? - o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? o->name() : o->unique_id()); + o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? o->name() : (o->type() + o->unique_id())); const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); - std::vector material_references; foreach(const IfcGeom::Material& material, mesh.materials()) { if (!materials.contains(material)) { @@ -323,6 +327,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme ); } + void ColladaSerializer::ColladaExporter::endDocument() { // In fact due the XML based nature of Collada and its dependency on library nodes, // only at this point all objects are written to the stream. @@ -338,6 +343,7 @@ void ColladaSerializer::ColladaExporter::endDocument() { geometries.close(); for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { const std::string object_name = it->unique_id; + /// @todo redundant information using ID as both ID and Name, maybe omit Name or allow specifying what would be used as the name scene.add(object_name, object_name, it->representation_id, it->material_references, it->matrix); } diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index faa092203f..e466413b7b 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -177,6 +177,7 @@ private: ColladaExporter exporter; std::string unit_name; float unit_magnitude; + IfcParse::IfcFile* file; public: ColladaSerializer(const std::string& dae_filename, const SerializerSettings& settings) : GeometrySerializer(settings) @@ -197,7 +198,7 @@ public: unit_name = name; unit_magnitude = magnitude; } - void setFile(IfcParse::IfcFile*) {} + void setFile(IfcParse::IfcFile* f) { file = f; } }; #endif diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 6ec5660ebf..b13d799ad7 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -519,7 +519,7 @@ int main(int argc, char** argv) time_t start,end; time(&start); - + IfcGeom::Iterator context_iterator(settings, &ifc_file, filter_funcs); if (!context_iterator.initialize()) { /// @todo It would be nice to know and print separate error prints for a case where we found no entities @@ -577,9 +577,32 @@ int main(int argc, char** argv) do { IfcGeom::Element *geom_object = context_iterator.get(); - if (is_tesselated) { + + // Note : Ici on envoie au Serializer les obj à traier. + // Un tri a déjà été fait, on envoie pas tous les objets. Les IfcBuildingStorey ne sont déjà plus là ... + + // if the target is a .dae file, get the parent of the object + if (output_extension == ".dae" && geom_object->parent_id() != -1) + { + const IfcGeom::Element *parent_object = context_iterator.getObject(geom_object->parent_id()); + + int cptSecure = 0; + while (parent_object->type() != "IfcBuildingStorey" && cptSecure < 1000 && parent_object->parent_id() != 1) + { + cptSecure++; + parent_object = context_iterator.getObject(parent_object->parent_id()); + } + //Debug + if (geom_object->parent_id() == -1) std::cout << "Parent = -1 : " << geom_object->name(); + std::cout << '\n' << "obj " << geom_object->unique_id() << " parent = " << parent_object->name() << " of type " << parent_object->type() << '\n'; + } + + if (is_tesselated) + { serializer->write(static_cast*>(geom_object)); - } else { + } + else + { serializer->write(static_cast*>(geom_object)); } const int progress = context_iterator.progress() / 2; From b9e9bfeceb814331d73485a3807731a7308acf02 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Wed, 12 Apr 2017 13:36:12 +0200 Subject: [PATCH 02/36] Handle errors : when an object has no parent --- src/ifcconvert/ColladaSerializer.h | 3 +-- src/ifcconvert/IfcConvert.cpp | 32 ++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index e466413b7b..faa092203f 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -177,7 +177,6 @@ private: ColladaExporter exporter; std::string unit_name; float unit_magnitude; - IfcParse::IfcFile* file; public: ColladaSerializer(const std::string& dae_filename, const SerializerSettings& settings) : GeometrySerializer(settings) @@ -198,7 +197,7 @@ public: unit_name = name; unit_magnitude = magnitude; } - void setFile(IfcParse::IfcFile* f) { file = f; } + void setFile(IfcParse::IfcFile*) {} }; #endif diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index b13d799ad7..25df256629 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -578,23 +578,33 @@ int main(int argc, char** argv) do { IfcGeom::Element *geom_object = context_iterator.get(); - // Note : Ici on envoie au Serializer les obj à traier. - // Un tri a déjà été fait, on envoie pas tous les objets. Les IfcBuildingStorey ne sont déjà plus là ... - // if the target is a .dae file, get the parent of the object if (output_extension == ".dae" && geom_object->parent_id() != -1) { - const IfcGeom::Element *parent_object = context_iterator.getObject(geom_object->parent_id()); - - int cptSecure = 0; - while (parent_object->type() != "IfcBuildingStorey" && cptSecure < 1000 && parent_object->parent_id() != 1) + const IfcGeom::Element *parent_object = NULL; + bool hasParent = true; + try { parent_object = context_iterator.getObject(geom_object->parent_id()); } + catch (std::exception e) { - cptSecure++; - parent_object = context_iterator.getObject(parent_object->parent_id()); + std::cout << e.what() << '\n'; + hasParent = false; + } + + while (parent_object != NULL && parent_object->type() != "IfcBuildingStorey" && hasParent) + { + try { parent_object = context_iterator.getObject(parent_object->parent_id()); } + catch (std::exception e) + { + std::cout << e.what() << '\n'; + hasParent = false; + } + + hasParent = hasParent && parent_object->parent_id() != 1; } //Debug - if (geom_object->parent_id() == -1) std::cout << "Parent = -1 : " << geom_object->name(); - std::cout << '\n' << "obj " << geom_object->unique_id() << " parent = " << parent_object->name() << " of type " << parent_object->type() << '\n'; + //if (parent_object != NULL) std::cout << '\n' << "obj " << geom_object->unique_id() << " parent = " << parent_object->name() << " of type " << parent_object->type() << '\n'; + //else std::cout << "No parent found : " << geom_object->unique_id() << " of type : " << geom_object->type(); + } if (is_tesselated) From a2aa2bf9eb0d359f5e8b857d19c7bd1ce17e3e1a Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Wed, 12 Apr 2017 14:38:54 +0200 Subject: [PATCH 03/36] Send hierarchy data to the serializer WIP --- src/ifcconvert/ColladaSerializer.cpp | 30 +++++++++++++++++---- src/ifcconvert/ColladaSerializer.h | 2 ++ src/ifcconvert/GeometrySerializer.h | 1 + src/ifcconvert/IfcConvert.cpp | 18 ++++++++----- src/ifcconvert/OpenCascadeBasedSerializer.h | 1 + src/ifcconvert/SvgSerializer.h | 1 + src/ifcconvert/WavefrontObjSerializer.h | 1 + 7 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 9c26211e84..f1f5a96fcd 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -300,12 +300,9 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n asset.setUpAxisType(COLLADASW::Asset::Z_UP); asset.add(); } -// ******************************** -// NOTE : o->context.parent_id ????????????????? == -1 si pas de parent -// On a un type de product ifcBuildingStorey + void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o) -{ - +{ const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? o->name() : (o->type() + o->unique_id())); @@ -327,6 +324,28 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme ); } +void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) +{ + const IfcGeom::Representation::Triangulation& mesh = o->geometry(); + const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? + o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? o->name() : (o->type() + o->unique_id())); + const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); + std::vector material_references; + foreach(const IfcGeom::Material& material, mesh.materials()) { + if (!materials.contains(material)) { + materials.add(material); + } + std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES) + ? material.original_name() : material.name()); + collada_id(material_name); + material_references.push_back(material_name); + } + + deferreds.push_back( + DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs()) + ); +} void ColladaSerializer::ColladaExporter::endDocument() { // In fact due the XML based nature of Collada and its dependency on library nodes, @@ -363,6 +382,7 @@ void ColladaSerializer::write(const IfcGeom::TriangulationElement* o) { exporter.write(o); } + void ColladaSerializer::finalize() { exporter.endDocument(); } diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index faa092203f..58fa7d78b7 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -172,6 +172,7 @@ private: virtual ~ColladaExporter() {} void startDocument(const std::string& unit_name, float unit_magnitude); void write(const IfcGeom::TriangulationElement* o); + void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent); void endDocument(); }; ColladaExporter exporter; @@ -190,6 +191,7 @@ public: bool ready(); void writeHeader(); void write(const IfcGeom::TriangulationElement* o); + void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent); void write(const IfcGeom::BRepElement* /*o*/) {} void finalize(); bool isTesselated() const { return true; } diff --git a/src/ifcconvert/GeometrySerializer.h b/src/ifcconvert/GeometrySerializer.h index 7b7997d8ad..8a15b8bce3 100644 --- a/src/ifcconvert/GeometrySerializer.h +++ b/src/ifcconvert/GeometrySerializer.h @@ -70,6 +70,7 @@ public: virtual bool isTesselated() const = 0; virtual void write(const IfcGeom::TriangulationElement* o) = 0; + virtual void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* element) = 0; virtual void write(const IfcGeom::BRepElement* o) = 0; virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0; diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 25df256629..3cc19786e5 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -605,16 +605,20 @@ int main(int argc, char** argv) //if (parent_object != NULL) std::cout << '\n' << "obj " << geom_object->unique_id() << " parent = " << parent_object->name() << " of type " << parent_object->type() << '\n'; //else std::cout << "No parent found : " << geom_object->unique_id() << " of type : " << geom_object->type(); + serializer->write(static_cast*>(geom_object), parent_object); } - - if (is_tesselated) + else { - serializer->write(static_cast*>(geom_object)); - } - else - { - serializer->write(static_cast*>(geom_object)); + if (is_tesselated) + { + serializer->write(static_cast*>(geom_object)); + } + else + { + serializer->write(static_cast*>(geom_object)); + } } + const int progress = context_iterator.progress() / 2; if (old_progress != progress) Logger::ProgressBar(progress); old_progress = progress; diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.h b/src/ifcconvert/OpenCascadeBasedSerializer.h index 01c088594d..2dce8ef63f 100644 --- a/src/ifcconvert/OpenCascadeBasedSerializer.h +++ b/src/ifcconvert/OpenCascadeBasedSerializer.h @@ -40,6 +40,7 @@ public: bool ready(); virtual void writeShape(const TopoDS_Shape& shape) = 0; void write(const IfcGeom::TriangulationElement* /*o*/) {} + void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) {} void write(const IfcGeom::BRepElement* o); bool isTesselated() const { return false; } void setFile(IfcParse::IfcFile*) {} diff --git a/src/ifcconvert/SvgSerializer.h b/src/ifcconvert/SvgSerializer.h index 542541f9d0..fe12cfbeb6 100644 --- a/src/ifcconvert/SvgSerializer.h +++ b/src/ifcconvert/SvgSerializer.h @@ -60,6 +60,7 @@ public: void writeHeader(); bool ready(); void write(const IfcGeom::TriangulationElement* /*o*/) {} + void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) {} void write(const IfcGeom::BRepElement* o); void write(path_object& p, const TopoDS_Wire& wire); path_object& start_path(IfcSchema::IfcBuildingStorey* storey, const std::string& id); diff --git a/src/ifcconvert/WavefrontObjSerializer.h b/src/ifcconvert/WavefrontObjSerializer.h index 2aa9708bdc..5411d5f64f 100644 --- a/src/ifcconvert/WavefrontObjSerializer.h +++ b/src/ifcconvert/WavefrontObjSerializer.h @@ -51,6 +51,7 @@ public: void writeHeader(); void writeMaterial(const IfcGeom::Material& style); void write(const IfcGeom::TriangulationElement* o); + void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) {} void write(const IfcGeom::BRepElement* /*o*/) {} void finalize() {} bool isTesselated() const { return true; } From be326e13edb42b1de9db3437e5fb1f09ab5e97fa Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Wed, 12 Apr 2017 14:56:00 +0200 Subject: [PATCH 04/36] Send Hierarchy data to the serializer --- src/ifcconvert/ColladaSerializer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index f1f5a96fcd..84f0a32ac4 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -382,6 +382,11 @@ void ColladaSerializer::write(const IfcGeom::TriangulationElement* o) { exporter.write(o); } +void ColladaSerializer::write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) +{ + exporter.write(o, parent); +} + void ColladaSerializer::finalize() { exporter.endDocument(); From 8312853b99caea150fbc67d79e7eff3e8bdc811a Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Wed, 12 Apr 2017 15:49:05 +0200 Subject: [PATCH 05/36] add parent property to deffered objects --- src/ifcconvert/ColladaSerializer.cpp | 8 ++++---- src/ifcconvert/ColladaSerializer.h | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 84f0a32ac4..c47c48eea7 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -224,7 +224,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() { if (scene_opened) { closeVisualScene(); closeLibrary(); - + COLLADASW::Scene scene (mSW, COLLADASW::URI ("#" + scene_id)); scene.add(); } @@ -319,8 +319,8 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme } deferreds.push_back( - DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), - mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs()) + DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), "") ); } @@ -343,7 +343,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme deferreds.push_back( DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), - mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs()) + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), parent->name()) ); } diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 58fa7d78b7..86142a4722 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -132,10 +132,11 @@ private: std::vector materials; std::vector material_references; std::vector uvs; + std::string parent; DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& faces, const std::vector& edges, const std::vector& material_ids, const std::vector& materials, - const std::vector& material_references, const std::vector& uvs) + const std::vector& material_references, const std::vector& uvs, const std::string& parent) : unique_id(unique_id) , representation_id(representation_id) , type(type) @@ -148,6 +149,7 @@ private: , materials(materials) , material_references(material_references) , uvs(uvs) + , parent(parent) {} }; COLLADABU::NativeString filename; From a02b189f69fe0f28bbc8e84e2cc27fc008c563b1 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Wed, 12 Apr 2017 16:11:37 +0200 Subject: [PATCH 06/36] Bug Fix : the previous commit made the program crash when an object has no parent --- src/ifcconvert/IfcConvert.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 3cc19786e5..cbe8caa896 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -604,8 +604,9 @@ int main(int argc, char** argv) //Debug //if (parent_object != NULL) std::cout << '\n' << "obj " << geom_object->unique_id() << " parent = " << parent_object->name() << " of type " << parent_object->type() << '\n'; //else std::cout << "No parent found : " << geom_object->unique_id() << " of type : " << geom_object->type(); - - serializer->write(static_cast*>(geom_object), parent_object); + + if (parent_object != NULL) serializer->write(static_cast*>(geom_object), parent_object); + else serializer->write(static_cast*>(geom_object)); } else { From f446f25ceee5a723eddb9f73a6c7438be441fdb8 Mon Sep 17 00:00:00 2001 From: Tristan Zimpfer Date: Wed, 12 Apr 2017 17:28:29 +0200 Subject: [PATCH 07/36] Sort DeferredObject. --- src/ifcconvert/ColladaSerializer.cpp | 1 + src/ifcconvert/ColladaSerializer.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index c47c48eea7..d67bc04044 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -352,6 +352,7 @@ void ColladaSerializer::ColladaExporter::endDocument() { // only at this point all objects are written to the stream. materials.write(); std::set geometries_written; + std::sort(deferreds.begin(), deferreds.end()); for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { if (geometries_written.find(it->representation_id) != geometries_written.end()) { continue; diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 86142a4722..9ef049ed79 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -121,6 +121,10 @@ private: ColladaEffects effects; }; class DeferredObject { + friend bool operator < (const DeferredObject & def_obj1, const DeferredObject & def_obj2) + { + return (def_obj1.parent < def_obj2.parent ? true : false); + } public: std::string unique_id, representation_id, type; std::vector matrix; From 79e1e0ec040d7c621e18a8e75bc1dab0a0e9bfd2 Mon Sep 17 00:00:00 2001 From: Tristan Zimpfer Date: Thu, 13 Apr 2017 16:39:36 +0200 Subject: [PATCH 08/36] Hierarchy v1 --- src/ifcconvert/ColladaSerializer.cpp | 31 ++++++++++++++++++++++++++++ src/ifcconvert/ColladaSerializer.h | 4 ++++ 2 files changed, 35 insertions(+) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index d67bc04044..fb72473d63 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -220,6 +220,24 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add( node.end(); } +void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const std::string& node_name){ + + if (!scene_opened) { + openVisualScene(scene_id); + scene_opened = true; + } + + current_node = new COLLADASW::Node(mSW); + current_node->setNodeId(node_name); + current_node->setNodeName(node_name); + current_node->setType(COLLADASW::Node::NODE); + current_node->start(); +} + +void ColladaSerializer::ColladaExporter::ColladaScene::closeParent(){ + current_node->end(); +} + void ColladaSerializer::ColladaExporter::ColladaScene::write() { if (scene_opened) { closeVisualScene(); @@ -361,12 +379,25 @@ void ColladaSerializer::ColladaExporter::endDocument() { geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials, it->uvs); } geometries.close(); + std::string parent_name; + bool is_parent_empty = true; for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { const std::string object_name = it->unique_id; + if (parent_name != it->parent){ + if (!is_parent_empty){ + scene.closeParent(); + } + parent_name = it->parent; + scene.addParent(parent_name); + is_parent_empty = false; + } + /// @todo redundant information using ID as both ID and Name, maybe omit Name or allow specifying what would be used as the name scene.add(object_name, object_name, it->representation_id, it->material_references, it->matrix); } + + scene.closeParent(); scene.write(); stream.endDocument(); } diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 9ef049ed79..716575b632 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -30,6 +30,7 @@ #pragma GCC diagnostic ignored "-Wignored-qualifiers" #endif #include +#include #include #include #include @@ -78,6 +79,7 @@ private: const std::string scene_id; bool scene_opened; + COLLADASW::Node *current_node; public: ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryVisualScenes(&stream) @@ -87,6 +89,8 @@ private: {} void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix); + void addParent(const std::string& node_name); + void closeParent(); void write(); ColladaSerializer *serializer; }; From 9f362853d6a8dbdb43ed46ea0faa2acc840e6f65 Mon Sep 17 00:00:00 2001 From: Tristan Zimpfer Date: Wed, 19 Apr 2017 11:48:52 +0200 Subject: [PATCH 09/36] Added a matrix for the parent node and a better id. --- src/ifcconvert/ColladaSerializer.cpp | 35 +++++++++++++++++++++------- src/ifcconvert/ColladaSerializer.h | 34 ++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index fb72473d63..0890667834 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -220,16 +220,33 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add( node.end(); } -void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const std::string& node_name){ +void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::Element& parent){ if (!scene_opened) { openVisualScene(scene_id); scene_opened = true; } + const std::vector matrix = parent.transformation().matrix().data(); + + double matrix_array[4][4] = { + { (double)matrix[0], (double)matrix[3], (double)matrix[6], (double)matrix[9] }, + { (double)matrix[1], (double)matrix[4], (double)matrix[7], (double)matrix[10] }, + { (double)matrix[2], (double)matrix[5], (double)matrix[8], (double)matrix[11] }, + { 0, 0, 0, 1 } + }; + + matrix_array[0][3] += serializer->settings().offset[0]; + matrix_array[1][3] += serializer->settings().offset[1]; + matrix_array[2][3] += serializer->settings().offset[2]; + + + const std::string id = "representation-" + boost::lexical_cast(parent.id()); + current_node = new COLLADASW::Node(mSW); - current_node->setNodeId(node_name); - current_node->setNodeName(node_name); + current_node->setNodeId(id); + current_node->setNodeName(parent.name()); + current_node->addMatrix(matrix_array); current_node->setType(COLLADASW::Node::NODE); current_node->start(); } @@ -338,7 +355,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme deferreds.push_back( DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), - mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), "") + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs()) ); } @@ -361,7 +378,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme deferreds.push_back( DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), - mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), parent->name()) + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), *parent) ); } @@ -379,17 +396,17 @@ void ColladaSerializer::ColladaExporter::endDocument() { geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials, it->uvs); } geometries.close(); - std::string parent_name; + int parent_id; bool is_parent_empty = true; for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { const std::string object_name = it->unique_id; - if (parent_name != it->parent){ + if (parent_id != it->parent->id()){ if (!is_parent_empty){ scene.closeParent(); } - parent_name = it->parent; - scene.addParent(parent_name); + parent_id = it->parent->id(); + scene.addParent(*it->parent); is_parent_empty = false; } diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 716575b632..870c9a91fe 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -89,7 +89,7 @@ private: {} void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix); - void addParent(const std::string& node_name); + void addParent(const IfcGeom::Element& parent); void closeParent(); void write(); ColladaSerializer *serializer; @@ -127,7 +127,9 @@ private: class DeferredObject { friend bool operator < (const DeferredObject & def_obj1, const DeferredObject & def_obj2) { - return (def_obj1.parent < def_obj2.parent ? true : false); + const IfcGeom::Element parent1 = *def_obj1.parent; + const IfcGeom::Element parent2 = *def_obj2.parent; + return (parent1.name() < parent2.name() ? true : false); } public: std::string unique_id, representation_id, type; @@ -140,11 +142,11 @@ private: std::vector materials; std::vector material_references; std::vector uvs; - std::string parent; + const IfcGeom::Element* parent; DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& faces, const std::vector& edges, const std::vector& material_ids, const std::vector& materials, - const std::vector& material_references, const std::vector& uvs, const std::string& parent) + const std::vector& material_references, const std::vector& uvs, const IfcGeom::Element& _parent) : unique_id(unique_id) , representation_id(representation_id) , type(type) @@ -157,8 +159,28 @@ private: , materials(materials) , material_references(material_references) , uvs(uvs) - , parent(parent) - {} + { + parent = &_parent; + } + + DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, + const std::vector& vertices, const std::vector& normals, const std::vector& faces, + const std::vector& edges, const std::vector& material_ids, const std::vector& materials, + const std::vector& material_references, const std::vector& uvs) + : unique_id(unique_id) + , representation_id(representation_id) + , type(type) + , matrix(matrix) + , vertices(vertices) + , normals(normals) + , faces(faces) + , edges(edges) + , material_ids(material_ids) + , materials(materials) + , material_references(material_references) + , uvs(uvs) + { + } }; COLLADABU::NativeString filename; COLLADASW::StreamWriter stream; From ab0e47c55fb759cc161d4aede0e4dd416a01919e Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Wed, 19 Apr 2017 12:07:03 +0200 Subject: [PATCH 10/36] Options added : --use-element-types and --use-element-hierarchy --- src/ifcconvert/ColladaSerializer.cpp | 22 ++++++++++++++-------- src/ifcconvert/GeometrySerializer.h | 8 +++++++- src/ifcconvert/IfcConvert.cpp | 10 ++++++++++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index fb72473d63..124ecb9777 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -235,7 +235,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const std::stri } void ColladaSerializer::ColladaExporter::ColladaScene::closeParent(){ - current_node->end(); + if (current_node != NULL) { current_node->end(); } } void ColladaSerializer::ColladaExporter::ColladaScene::write() { @@ -323,7 +323,8 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme { const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? - o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? o->name() : (o->type() + o->unique_id())); + o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? + o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + "_" + o->name() : o->unique_id())); const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); std::vector material_references; foreach(const IfcGeom::Material& material, mesh.materials()) { @@ -346,7 +347,8 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme { const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? - o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? o->name() : (o->type() + o->unique_id())); + o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? + o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + "_" + o->name() : o->unique_id())); const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); std::vector material_references; foreach(const IfcGeom::Material& material, mesh.materials()) { @@ -359,9 +361,11 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme material_references.push_back(material_name); } + const std::string parent_name = (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) ? + parent->name() : ""); deferreds.push_back( DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), - mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), parent->name()) + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), parent_name) ); } @@ -379,13 +383,15 @@ void ColladaSerializer::ColladaExporter::endDocument() { geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials, it->uvs); } geometries.close(); - std::string parent_name; + std::string parent_name = ""; bool is_parent_empty = true; for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { const std::string object_name = it->unique_id; - - if (parent_name != it->parent){ - if (!is_parent_empty){ + + if (parent_name != it->parent) + { + if (!is_parent_empty) + { scene.closeParent(); } parent_name = it->parent; diff --git a/src/ifcconvert/GeometrySerializer.h b/src/ifcconvert/GeometrySerializer.h index 8a15b8bce3..33345b4ad1 100644 --- a/src/ifcconvert/GeometrySerializer.h +++ b/src/ifcconvert/GeometrySerializer.h @@ -43,8 +43,14 @@ public: /// Use material names instead of unique IDs for naming materials. /// Applicable for OBJ and DAE output. USE_MATERIAL_NAMES = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 3), + /// Use element types and names instead of unique IDs for naming elements. + /// Applicable for DAE output. + USE_ELEMENT_TYPES = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 4), + /// Order the elements using their IfcBuildingStorey parent + /// Applicable for DAE output + USE_ELEMENT_HIERARCHY = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 5), /// Number of different setting flags. - NUM_SETTINGS = 3 + NUM_SETTINGS = 5 }; SerializerSettings() diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index cbe8caa896..43b20e4315 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -267,6 +267,12 @@ int main(int argc, char** argv) ("use-material-names", "Use material names instead of unique IDs for naming materials upon serialization. " "Applicable for OBJ and DAE output.") + ("use-element-types", + "Use element types and names instead of unique IDs for naming elements upon serialization. " + "Applicable for DAE output.") + ("use-element-hierarchy", + "Order the elements using their IfcBuildingStorey parent. " + "Applicable for DAE output.") ("center-model", "Centers the elements upon serialization by applying the center point of " "all placements as an offset. Applicable for OBJ and DAE output.") @@ -335,6 +341,8 @@ int main(int argc, char** argv) const bool use_element_names = vmap.count("use-element-names") != 0; const bool use_element_guids = vmap.count("use-element-guids") != 0 ; const bool use_material_names = vmap.count("use-material-names") != 0; + const bool use_element_types = vmap.count("use-element-types") != 0; + const bool use_element_hierarchy = vmap.count("use-element-hierarchy") != 0; const bool no_normals = vmap.count("no-normals") != 0 ; const bool center_model = vmap.count("center-model") != 0 ; const bool model_offset = vmap.count("model-offset") != 0 ; @@ -463,6 +471,8 @@ int main(int argc, char** argv) settings.set(SerializerSettings::USE_ELEMENT_NAMES, use_element_names); settings.set(SerializerSettings::USE_ELEMENT_GUIDS, use_element_guids); settings.set(SerializerSettings::USE_MATERIAL_NAMES, use_material_names); + settings.set(SerializerSettings::USE_ELEMENT_TYPES, use_element_types); + settings.set(SerializerSettings::USE_ELEMENT_HIERARCHY, use_element_hierarchy); settings.set_deflection_tolerance(deflection_tolerance); settings.precision = precision; From 8e4febecc031993cf987b629c6e61e6648972baf Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Wed, 19 Apr 2017 16:38:35 +0200 Subject: [PATCH 11/36] clean : Remove the debug print debug : don't display the name of the element in unity anymore --- src/ifcconvert/ColladaSerializer.cpp | 24 ++++-------------------- src/ifcconvert/GeometrySerializer.h | 2 +- src/ifcconvert/IfcConvert.cpp | 7 +------ 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index d5fb37c211..9b12842e59 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -251,7 +251,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: } void ColladaSerializer::ColladaExporter::ColladaScene::closeParent(){ - if (current_node != NULL) { std::cout << "current node is not null\n"; current_node->end(); } + if (current_node != NULL) { current_node->end(); } } void ColladaSerializer::ColladaExporter::ColladaScene::write() { @@ -340,7 +340,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? - o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + "_" + o->name() : o->unique_id())); + o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() : o->unique_id())); const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); std::vector material_references; foreach(const IfcGeom::Material& material, mesh.materials()) { @@ -364,7 +364,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? - o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + "_" + o->name() : o->unique_id())); + o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() : o->unique_id())); const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); std::vector material_references; foreach(const IfcGeom::Material& material, mesh.materials()) { @@ -389,12 +389,9 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme void ColladaSerializer::ColladaExporter::endDocument() { // In fact due the XML based nature of Collada and its dependency on library nodes, // only at this point all objects are written to the stream. - std::cout << "starting end document\n"; materials.write(); std::set geometries_written; - std::cout << "sorting defered list...\n"; std::sort(deferreds.begin(), deferreds.end()); - std::cout << "done\n"; for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { if (geometries_written.find(it->representation_id) != geometries_written.end()) { continue; @@ -408,34 +405,21 @@ void ColladaSerializer::ColladaExporter::endDocument() { for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { const std::string object_name = it->unique_id; - //std::cout << "working on " << it->unique_id; - //std::cout << (it->parent == NULL ? " parent is null\n" : "parent is not null\n"); + if (it->parent != NULL && parent_id != it->parent->id()) { - std::cout << "parent description : \n --- Type : " << it->parent->type() << " \n --- Name : " << it->parent->name() << "\n"; - //std::cout << "parent is not null. Id : " << it->parent->id() << '\n'; - //std::cout << "test if parent is empty ... \n"; if (!is_parent_empty) { - //std::cout << "close parent1 ... \n"; scene.closeParent(); - //std::cout << "done\n"; } - //std::cout << "get parent id .. \n"; parent_id = it->parent->id(); - //std::cout << "add parent to scene .. \n"; scene.addParent(*it->parent); - //std::cout << "done \n"; is_parent_empty = false; } - //std::cout << "add node to scene ... \n"; /// @todo redundant information using ID as both ID and Name, maybe omit Name or allow specifying what would be used as the name scene.add(object_name, object_name, it->representation_id, it->material_references, it->matrix); - //std::cout << "done \n"; } - std::cout << "close parent2 : \n"; if (!is_parent_empty) scene.closeParent(); - std::cout << "write : \n"; scene.write(); stream.endDocument(); } diff --git a/src/ifcconvert/GeometrySerializer.h b/src/ifcconvert/GeometrySerializer.h index 33345b4ad1..4a84a50322 100644 --- a/src/ifcconvert/GeometrySerializer.h +++ b/src/ifcconvert/GeometrySerializer.h @@ -43,7 +43,7 @@ public: /// Use material names instead of unique IDs for naming materials. /// Applicable for OBJ and DAE output. USE_MATERIAL_NAMES = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 3), - /// Use element types and names instead of unique IDs for naming elements. + /// Use element types instead of unique IDs for naming elements. /// Applicable for DAE output. USE_ELEMENT_TYPES = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 4), /// Order the elements using their IfcBuildingStorey parent diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index d2f720661a..d5dc39f06f 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -268,7 +268,7 @@ int main(int argc, char** argv) "Use material names instead of unique IDs for naming materials upon serialization. " "Applicable for OBJ and DAE output.") ("use-element-types", - "Use element types and names instead of unique IDs for naming elements upon serialization. " + "Use element types instead of unique IDs for naming elements upon serialization. " "Applicable for DAE output.") ("use-element-hierarchy", "Order the elements using their IfcBuildingStorey parent. " @@ -596,7 +596,6 @@ int main(int argc, char** argv) try { parent_object = context_iterator.getObject(geom_object->parent_id()); } catch (std::exception e) { - std::cout << e.what() << '\n'; hasParent = false; } @@ -605,15 +604,11 @@ int main(int argc, char** argv) try { parent_object = context_iterator.getObject(parent_object->parent_id()); } catch (std::exception e) { - std::cout << e.what() << '\n'; hasParent = false; } hasParent = hasParent && parent_object->parent_id() != 1; } - //Debug - //if (parent_object != NULL) std::cout << '\n' << "obj " << geom_object->unique_id() << " parent = " << parent_object->name() << " of type " << parent_object->type() << '\n'; - //else std::cout << "No parent found : " << geom_object->unique_id() << " of type : " << geom_object->type(); if (parent_object != NULL) serializer->write(static_cast*>(geom_object), parent_object); else serializer->write(static_cast*>(geom_object)); From 7ce795def3db1d76be5df092ddf9acec4e6a62e0 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Thu, 20 Apr 2017 15:06:49 +0200 Subject: [PATCH 12/36] clean WIP --- src/ifcconvert/ColladaSerializer.cpp | 26 +------------------------- src/ifcconvert/ColladaSerializer.h | 24 +++++++++++++++++------- src/ifcconvert/IfcConvert.cpp | 10 ++++++---- 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 9b12842e59..8d8f0d3433 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -335,30 +335,6 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n asset.add(); } -void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o) -{ - const IfcGeom::Representation::Triangulation& mesh = o->geometry(); - const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? - o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? - o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() : o->unique_id())); - const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); - std::vector material_references; - foreach(const IfcGeom::Material& material, mesh.materials()) { - if (!materials.contains(material)) { - materials.add(material); - } - std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES) - ? material.original_name() : material.name()); - collada_id(material_name); - material_references.push_back(material_name); - } - - deferreds.push_back( - DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), - mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs()) - ); -} - void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) { const IfcGeom::Representation::Triangulation& mesh = o->geometry(); @@ -433,7 +409,7 @@ void ColladaSerializer::writeHeader() { } void ColladaSerializer::write(const IfcGeom::TriangulationElement* o) { - exporter.write(o); + exporter.write(o, NULL); } void ColladaSerializer::write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index a0f98d78df..96a5f32ab2 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -129,12 +129,20 @@ private: { const IfcGeom::Element* parent1 = def_obj1.parent; const IfcGeom::Element* parent2 = def_obj2.parent; - + std::cout << "comparing..\n"; + if (parent1 == NULL || parent2 == NULL) { - return (def_obj1.unique_id < def_obj2.unique_id ? true : false); + bool res = (def_obj1.unique_id < def_obj2.unique_id ? true : false); + std::cout << "done\n"; + return res; + } + else + { + bool res = parent1->name() < parent2->name() ? true : false; + std::cout << "done\n"; + return res; } - else return parent1->name() < parent2->name() ? true : false; } public: std::string unique_id, representation_id, type; @@ -164,8 +172,9 @@ private: , materials(materials) , material_references(material_references) , uvs(uvs) + , parent(&_parent) { - parent = &_parent; + } DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, @@ -184,8 +193,9 @@ private: , materials(materials) , material_references(material_references) , uvs(uvs) + , parent(NULL) { - parent = NULL; + } }; COLLADABU::NativeString filename; @@ -209,7 +219,7 @@ private: std::vector deferreds; virtual ~ColladaExporter() {} void startDocument(const std::string& unit_name, float unit_magnitude); - void write(const IfcGeom::TriangulationElement* o); + void write(const IfcGeom::TriangulationElement* o) {}; void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent); void endDocument(); }; @@ -228,7 +238,7 @@ public: } bool ready(); void writeHeader(); - void write(const IfcGeom::TriangulationElement* o); + void write(const IfcGeom::TriangulationElement* o); void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent); void write(const IfcGeom::BRepElement* /*o*/) {} void finalize(); diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index d5dc39f06f..5ceb200d30 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -587,11 +587,12 @@ int main(int argc, char** argv) do { IfcGeom::Element *geom_object = context_iterator.get(); - + // if the target is a .dae file, get the parent of the object - if (output_extension == ".dae" && geom_object->parent_id() != -1) + if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && output_extension == ".dae" && geom_object->parent_id() != -1) { const IfcGeom::Element *parent_object = NULL; + bool hasParent = true; try { parent_object = context_iterator.getObject(geom_object->parent_id()); } catch (std::exception e) @@ -610,8 +611,9 @@ int main(int argc, char** argv) hasParent = hasParent && parent_object->parent_id() != 1; } - if (parent_object != NULL) serializer->write(static_cast*>(geom_object), parent_object); - else serializer->write(static_cast*>(geom_object)); + serializer->write(static_cast*>(geom_object), parent_object); + //delete parent_object; + //parent_object = NULL; } else { From 95acd4c517038e8a3ad2d59deb8a9d29e65bb6a4 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Fri, 21 Apr 2017 15:49:34 +0200 Subject: [PATCH 13/36] Clean : remove debug lines Find the floor of an element in the IfcGeomIterator class --- src/ifcconvert/ColladaSerializer.cpp | 11 +- src/ifcconvert/ColladaSerializer.h | 7 +- src/ifcconvert/GeometrySerializer.h | 1 - src/ifcconvert/IfcConvert.cpp | 37 +--- src/ifcconvert/OpenCascadeBasedSerializer.h | 1 - src/ifcconvert/SvgSerializer.h | 1 - src/ifcgeom/IfcGeomElement.h | 4 + src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP | 198 ++++++++++++++++++++ src/ifcgeom/IfcGeomIterator.h | 30 +++ src/ifcgeom/IfcGeomIteratorSettings.h | 4 +- 10 files changed, 243 insertions(+), 51 deletions(-) create mode 100644 src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 8d8f0d3433..0e8b3d83a6 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -335,7 +335,7 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n asset.add(); } -void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) +void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o) { const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? @@ -355,7 +355,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme DeferredObject defered = (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) ? DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), - mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), *parent) : + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), *(o->storey())) : DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs())); deferreds.push_back(defered); @@ -409,12 +409,7 @@ void ColladaSerializer::writeHeader() { } void ColladaSerializer::write(const IfcGeom::TriangulationElement* o) { - exporter.write(o, NULL); -} - -void ColladaSerializer::write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) -{ - exporter.write(o, parent); + exporter.write(o); } diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 96a5f32ab2..82473ec4d6 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -129,18 +129,15 @@ private: { const IfcGeom::Element* parent1 = def_obj1.parent; const IfcGeom::Element* parent2 = def_obj2.parent; - std::cout << "comparing..\n"; if (parent1 == NULL || parent2 == NULL) { bool res = (def_obj1.unique_id < def_obj2.unique_id ? true : false); - std::cout << "done\n"; return res; } else { bool res = parent1->name() < parent2->name() ? true : false; - std::cout << "done\n"; return res; } } @@ -219,8 +216,7 @@ private: std::vector deferreds; virtual ~ColladaExporter() {} void startDocument(const std::string& unit_name, float unit_magnitude); - void write(const IfcGeom::TriangulationElement* o) {}; - void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent); + void write(const IfcGeom::TriangulationElement* o); void endDocument(); }; ColladaExporter exporter; @@ -239,7 +235,6 @@ public: bool ready(); void writeHeader(); void write(const IfcGeom::TriangulationElement* o); - void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent); void write(const IfcGeom::BRepElement* /*o*/) {} void finalize(); bool isTesselated() const { return true; } diff --git a/src/ifcconvert/GeometrySerializer.h b/src/ifcconvert/GeometrySerializer.h index 4a84a50322..8543c468cb 100644 --- a/src/ifcconvert/GeometrySerializer.h +++ b/src/ifcconvert/GeometrySerializer.h @@ -76,7 +76,6 @@ public: virtual bool isTesselated() const = 0; virtual void write(const IfcGeom::TriangulationElement* o) = 0; - virtual void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* element) = 0; virtual void write(const IfcGeom::BRepElement* o) = 0; virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0; diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 5ceb200d30..f6f45bb143 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -467,6 +467,7 @@ int main(int argc, char** argv) settings.set(IfcGeom::IteratorSettings::APPLY_LAYERSETS, enable_layerset_slicing); settings.set(IfcGeom::IteratorSettings::NO_NORMALS, no_normals); settings.set(IfcGeom::IteratorSettings::GENERATE_UVS, generate_uvs); + settings.set(IfcGeom::IteratorSettings::SEARCH_FLOOR, use_element_hierarchy); settings.set(SerializerSettings::USE_ELEMENT_NAMES, use_element_names); settings.set(SerializerSettings::USE_ELEMENT_GUIDS, use_element_guids); @@ -588,43 +589,13 @@ int main(int argc, char** argv) do { IfcGeom::Element *geom_object = context_iterator.get(); - // if the target is a .dae file, get the parent of the object - if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && output_extension == ".dae" && geom_object->parent_id() != -1) + if (is_tesselated) { - const IfcGeom::Element *parent_object = NULL; - - bool hasParent = true; - try { parent_object = context_iterator.getObject(geom_object->parent_id()); } - catch (std::exception e) - { - hasParent = false; - } - - while (parent_object != NULL && parent_object->type() != "IfcBuildingStorey" && hasParent) - { - try { parent_object = context_iterator.getObject(parent_object->parent_id()); } - catch (std::exception e) - { - hasParent = false; - } - - hasParent = hasParent && parent_object->parent_id() != 1; - } - - serializer->write(static_cast*>(geom_object), parent_object); - //delete parent_object; - //parent_object = NULL; + serializer->write(static_cast*>(geom_object)); } else { - if (is_tesselated) - { - serializer->write(static_cast*>(geom_object)); - } - else - { - serializer->write(static_cast*>(geom_object)); - } + serializer->write(static_cast*>(geom_object)); } const int progress = context_iterator.progress() / 2; diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.h b/src/ifcconvert/OpenCascadeBasedSerializer.h index 2dce8ef63f..01c088594d 100644 --- a/src/ifcconvert/OpenCascadeBasedSerializer.h +++ b/src/ifcconvert/OpenCascadeBasedSerializer.h @@ -40,7 +40,6 @@ public: bool ready(); virtual void writeShape(const TopoDS_Shape& shape) = 0; void write(const IfcGeom::TriangulationElement* /*o*/) {} - void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) {} void write(const IfcGeom::BRepElement* o); bool isTesselated() const { return false; } void setFile(IfcParse::IfcFile*) {} diff --git a/src/ifcconvert/SvgSerializer.h b/src/ifcconvert/SvgSerializer.h index fe12cfbeb6..542541f9d0 100644 --- a/src/ifcconvert/SvgSerializer.h +++ b/src/ifcconvert/SvgSerializer.h @@ -60,7 +60,6 @@ public: void writeHeader(); bool ready(); void write(const IfcGeom::TriangulationElement* /*o*/) {} - void write(const IfcGeom::TriangulationElement* o, const IfcGeom::Element* parent) {} void write(const IfcGeom::BRepElement* o); void write(path_object& p, const TopoDS_Wire& wire); path_object& start_path(IfcSchema::IfcBuildingStorey* storey, const std::string& id); diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index 820727533a..c2c65891c8 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -81,6 +81,7 @@ namespace IfcGeom { std::string _unique_id; Transformation

_transformation; IfcSchema::IfcProduct* product_; + const Element

* _storey; public: int id() const { return _id; } int parent_id() const { return _parent_id; } @@ -91,6 +92,8 @@ namespace IfcGeom { const std::string& unique_id() const { return _unique_id; } const Transformation

& transformation() const { return _transformation; } IfcSchema::IfcProduct* product() const { return product_; } + const Element

* storey() const { return _storey; } + void SetFloor(const Element

* floor) { _storey = floor; } Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const std::string& context, const gp_Trsf& trsf, IfcSchema::IfcProduct *product) @@ -106,6 +109,7 @@ namespace IfcGeom { oss << "-" << ctx; } _unique_id = oss.str(); + } virtual ~Element() {} }; diff --git a/src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP b/src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP new file mode 100644 index 0000000000..3a38905ea1 --- /dev/null +++ b/src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP @@ -0,0 +1,198 @@ +/******************************************************************************** + * * + * This file is part of IfcOpenShell. * + * * + * IfcOpenShell is free software: you can redistribute it and/or modify * + * it under the terms of the Lesser GNU General Public License as published by * + * the Free Software Foundation, either version 3.0 of the License, or * + * (at your option) any later version. * + * * + * IfcOpenShell is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * Lesser GNU General Public License for more details. * + * * + * You should have received a copy of the Lesser GNU General Public License * + * along with this program. If not, see . * + * * + ********************************************************************************/ + +#ifndef IFCGEOMELEMENT_H +#define IFCGEOMELEMENT_H + +#include +#include + +#include "../ifcparse/IfcGlobalId.h" + +#include "../ifcgeom/IfcGeomRepresentation.h" +#include "../ifcgeom/IfcGeomIteratorSettings.h" +#include "ifc_geom_api.h" + +namespace IfcGeom { + + template + class Matrix { + private: + std::vector

_data; + public: + Matrix(const ElementSettings& settings, const gp_Trsf& trsf) { + // Convert the gp_Trsf into a 4x3 Matrix + // Note that in case the CONVERT_BACK_UNITS setting is enabled + // the translation component of the matrix needs to be divided + // by the magnitude of the IFC model length unit because + // internally in IfcOpenShell everything is measured in meters. + for(int i = 1; i < 5; ++i) { + for (int j = 1; j < 4; ++j) { + const double trsf_value = trsf.Value(j,i); + const double matrix_value = i == 4 && settings.get(IteratorSettings::CONVERT_BACK_UNITS) + ? trsf_value / settings.unit_magnitude() + : trsf_value; + _data.push_back(static_cast

(matrix_value)); + } + } + } + const std::vector

& data() const { return _data; } + }; + + template + class Transformation { + private: + gp_Trsf trsf; + Matrix

_matrix; + public: + Transformation(const ElementSettings& settings, const gp_Trsf& trsf) + : trsf(trsf) + , _matrix(settings, trsf) + {} + const gp_Trsf& data() const { return trsf; } + const Matrix

& matrix() const { return _matrix; } + }; + + template + class Element { + private: + int _id; + int _parent_id; + std::string _name; + std::string _type; + std::string _guid; + std::string _context; + std::string _unique_id; + Transformation

_transformation; + IfcSchema::IfcProduct* product_; + Element

* _storey; + public: + int id() const { return _id; } + int parent_id() const { return _parent_id; } + const std::string& name() const { return _name; } + const std::string& type() const { return _type; } + const std::string& guid() const { return _guid; } + const std::string& context() const { return _context; } + const std::string& unique_id() const { return _unique_id; } + const Transformation

& transformation() const { return _transformation; } + IfcSchema::IfcProduct* product() const { return product_; } + const Element

* storey() const { return _storey; } + + Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, + const std::string& guid, const std::string& context, const gp_Trsf& trsf, IfcSchema::IfcProduct *product) + : _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf) + , product_(product) + { + std::ostringstream oss; + oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); + if (!_context.empty()) { + std::string ctx = _context; + std::transform(ctx.begin(), ctx.end(), ctx.begin(), ::tolower); + std::replace(ctx.begin(), ctx.end(), ' ', '-'); + oss << "-" << ctx; + } + _unique_id = oss.str(); + + _storey = NULL; + // If we want to retrieve the storey hierarchy + if (settings.get(IteratorSettings::SEARCH_FLOOR)) + { + if (_parent_id != -1) + { + bool hasParent = true; + try { _storey = context_iterator.getObject(_parent_id); } + catch (std::exception e) + { + hasParent = false; + } + + while (_storey != NULL && parent_object->type() != "IfcBuildingStorey" && hasParent) + { + try { parent_object = context_iterator.getObject(parent_object->parent_id()); } + catch (std::exception e) + { + hasParent = false; + } + + hasParent = hasParent && parent_object->parent_id() != 1; + } + } + } + } + virtual ~Element() {} + }; + + template + class BRepElement : public Element

{ + private: + boost::shared_ptr _geometry; + public: + const boost::shared_ptr& geometry_pointer() const { return _geometry; } + const Representation::BRep& geometry() const { return *_geometry; } + BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, + const std::string& context, const gp_Trsf& trsf, const boost::shared_ptr& geometry, + IfcSchema::IfcProduct* product) + : Element

(geometry->settings(),id,parent_id,name,type,guid,context,trsf, product) + , _geometry(geometry) + {} + private: + BRepElement(const BRepElement& other); + BRepElement& operator=(const BRepElement& other); + }; + + template + class TriangulationElement : public Element

{ + private: + boost::shared_ptr< Representation::Triangulation

> _geometry; + public: + const Representation::Triangulation

& geometry() const { return *_geometry; } + const boost::shared_ptr< Representation::Triangulation

>& geometry_pointer() const { return _geometry; } + TriangulationElement(const BRepElement

& shape_model) + : Element

(shape_model) + , _geometry(boost::shared_ptr >(new Representation::Triangulation

(shape_model.geometry()))) + {} + TriangulationElement(const Element

& element, const boost::shared_ptr >& geometry) + : Element

(element) + , _geometry(geometry) + {} + private: + TriangulationElement(const TriangulationElement& other); + TriangulationElement& operator=(const TriangulationElement& other); + }; + + template + class SerializedElement : public Element

{ + private: + Representation::Serialization* _geometry; + public: + const Representation::Serialization& geometry() const { return *_geometry; } + SerializedElement(const BRepElement

& shape_model) + : Element

(shape_model) + , _geometry(new Representation::Serialization(shape_model.geometry())) + {} + virtual ~SerializedElement() { + delete _geometry; + } + private: + SerializedElement(const SerializedElement& other); + SerializedElement& operator=(const SerializedElement& other); + }; +} + +#endif \ No newline at end of file diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index 1bea3ddaaa..36e53273b7 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -573,6 +573,36 @@ namespace IfcGeom { if (current_triangulation) { ret = current_triangulation; } else if (current_serialization) { ret = current_serialization; } else if (current_shape_model) { ret = current_shape_model; } + + if (settings.get(IteratorSettings::SEARCH_FLOOR)) + { + if (ret->parent_id() != -1) + { + const IfcGeom::Element

* parent_object = NULL; + + bool hasParent = true; + try { parent_object = getObject(ret->parent_id()); } + catch (std::exception e) + { + hasParent = false; + } + + while (parent_object != NULL && parent_object->type() != "IfcBuildingStorey" && hasParent) + { + + try { parent_object = getObject(parent_object->parent_id()); } + catch (std::exception e) + { + hasParent = false; + } + + hasParent = hasParent && parent_object->parent_id() != 1; + } + + if (hasParent) { ret->SetFloor(parent_object); } + } + } + return ret; } diff --git a/src/ifcgeom/IfcGeomIteratorSettings.h b/src/ifcgeom/IfcGeomIteratorSettings.h index edc6e4ac15..b99088db88 100644 --- a/src/ifcgeom/IfcGeomIteratorSettings.h +++ b/src/ifcgeom/IfcGeomIteratorSettings.h @@ -78,8 +78,10 @@ namespace IfcGeom GENERATE_UVS = 1 << 12, /// Specifies whether to slice representations according to associated IfcLayerSets. APPLY_LAYERSETS = 1 << 13, + /// Search for a parent of type IfcBuildingStorey for each representation + SEARCH_FLOOR = 1 << 14, /// Number of different setting flags. - NUM_SETTINGS = 13 + NUM_SETTINGS = 14 }; /// Used to store logical OR combination of setting flags. typedef unsigned SettingField; From 8ac18752b29da15d3c98768e1893e2aa813540dc Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Fri, 21 Apr 2017 15:59:54 +0200 Subject: [PATCH 14/36] Remove temp file --- src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP | 198 --------------------- 1 file changed, 198 deletions(-) delete mode 100644 src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP diff --git a/src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP b/src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP deleted file mode 100644 index 3a38905ea1..0000000000 --- a/src/ifcgeom/IfcGeomElement.h~RF5ff49ef.TMP +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************** - * * - * This file is part of IfcOpenShell. * - * * - * IfcOpenShell is free software: you can redistribute it and/or modify * - * it under the terms of the Lesser GNU General Public License as published by * - * the Free Software Foundation, either version 3.0 of the License, or * - * (at your option) any later version. * - * * - * IfcOpenShell is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * Lesser GNU General Public License for more details. * - * * - * You should have received a copy of the Lesser GNU General Public License * - * along with this program. If not, see . * - * * - ********************************************************************************/ - -#ifndef IFCGEOMELEMENT_H -#define IFCGEOMELEMENT_H - -#include -#include - -#include "../ifcparse/IfcGlobalId.h" - -#include "../ifcgeom/IfcGeomRepresentation.h" -#include "../ifcgeom/IfcGeomIteratorSettings.h" -#include "ifc_geom_api.h" - -namespace IfcGeom { - - template - class Matrix { - private: - std::vector

_data; - public: - Matrix(const ElementSettings& settings, const gp_Trsf& trsf) { - // Convert the gp_Trsf into a 4x3 Matrix - // Note that in case the CONVERT_BACK_UNITS setting is enabled - // the translation component of the matrix needs to be divided - // by the magnitude of the IFC model length unit because - // internally in IfcOpenShell everything is measured in meters. - for(int i = 1; i < 5; ++i) { - for (int j = 1; j < 4; ++j) { - const double trsf_value = trsf.Value(j,i); - const double matrix_value = i == 4 && settings.get(IteratorSettings::CONVERT_BACK_UNITS) - ? trsf_value / settings.unit_magnitude() - : trsf_value; - _data.push_back(static_cast

(matrix_value)); - } - } - } - const std::vector

& data() const { return _data; } - }; - - template - class Transformation { - private: - gp_Trsf trsf; - Matrix

_matrix; - public: - Transformation(const ElementSettings& settings, const gp_Trsf& trsf) - : trsf(trsf) - , _matrix(settings, trsf) - {} - const gp_Trsf& data() const { return trsf; } - const Matrix

& matrix() const { return _matrix; } - }; - - template - class Element { - private: - int _id; - int _parent_id; - std::string _name; - std::string _type; - std::string _guid; - std::string _context; - std::string _unique_id; - Transformation

_transformation; - IfcSchema::IfcProduct* product_; - Element

* _storey; - public: - int id() const { return _id; } - int parent_id() const { return _parent_id; } - const std::string& name() const { return _name; } - const std::string& type() const { return _type; } - const std::string& guid() const { return _guid; } - const std::string& context() const { return _context; } - const std::string& unique_id() const { return _unique_id; } - const Transformation

& transformation() const { return _transformation; } - IfcSchema::IfcProduct* product() const { return product_; } - const Element

* storey() const { return _storey; } - - Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, - const std::string& guid, const std::string& context, const gp_Trsf& trsf, IfcSchema::IfcProduct *product) - : _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf) - , product_(product) - { - std::ostringstream oss; - oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); - if (!_context.empty()) { - std::string ctx = _context; - std::transform(ctx.begin(), ctx.end(), ctx.begin(), ::tolower); - std::replace(ctx.begin(), ctx.end(), ' ', '-'); - oss << "-" << ctx; - } - _unique_id = oss.str(); - - _storey = NULL; - // If we want to retrieve the storey hierarchy - if (settings.get(IteratorSettings::SEARCH_FLOOR)) - { - if (_parent_id != -1) - { - bool hasParent = true; - try { _storey = context_iterator.getObject(_parent_id); } - catch (std::exception e) - { - hasParent = false; - } - - while (_storey != NULL && parent_object->type() != "IfcBuildingStorey" && hasParent) - { - try { parent_object = context_iterator.getObject(parent_object->parent_id()); } - catch (std::exception e) - { - hasParent = false; - } - - hasParent = hasParent && parent_object->parent_id() != 1; - } - } - } - } - virtual ~Element() {} - }; - - template - class BRepElement : public Element

{ - private: - boost::shared_ptr _geometry; - public: - const boost::shared_ptr& geometry_pointer() const { return _geometry; } - const Representation::BRep& geometry() const { return *_geometry; } - BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, - const std::string& context, const gp_Trsf& trsf, const boost::shared_ptr& geometry, - IfcSchema::IfcProduct* product) - : Element

(geometry->settings(),id,parent_id,name,type,guid,context,trsf, product) - , _geometry(geometry) - {} - private: - BRepElement(const BRepElement& other); - BRepElement& operator=(const BRepElement& other); - }; - - template - class TriangulationElement : public Element

{ - private: - boost::shared_ptr< Representation::Triangulation

> _geometry; - public: - const Representation::Triangulation

& geometry() const { return *_geometry; } - const boost::shared_ptr< Representation::Triangulation

>& geometry_pointer() const { return _geometry; } - TriangulationElement(const BRepElement

& shape_model) - : Element

(shape_model) - , _geometry(boost::shared_ptr >(new Representation::Triangulation

(shape_model.geometry()))) - {} - TriangulationElement(const Element

& element, const boost::shared_ptr >& geometry) - : Element

(element) - , _geometry(geometry) - {} - private: - TriangulationElement(const TriangulationElement& other); - TriangulationElement& operator=(const TriangulationElement& other); - }; - - template - class SerializedElement : public Element

{ - private: - Representation::Serialization* _geometry; - public: - const Representation::Serialization& geometry() const { return *_geometry; } - SerializedElement(const BRepElement

& shape_model) - : Element

(shape_model) - , _geometry(new Representation::Serialization(shape_model.geometry())) - {} - virtual ~SerializedElement() { - delete _geometry; - } - private: - SerializedElement(const SerializedElement& other); - SerializedElement& operator=(const SerializedElement& other); - }; -} - -#endif \ No newline at end of file From ea609af3944cf8b77f994a23dcd8f3187498aba5 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Fri, 21 Apr 2017 16:02:13 +0200 Subject: [PATCH 15/36] comments added --- src/ifcgeom/IfcGeomIterator.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index 36e53273b7..8b90046e69 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -574,22 +574,26 @@ namespace IfcGeom { else if (current_serialization) { ret = current_serialization; } else if (current_shape_model) { ret = current_shape_model; } + // If we want to organize the element by floors we need to get the floor of the element if (settings.get(IteratorSettings::SEARCH_FLOOR)) { + // if the element has a parent if (ret->parent_id() != -1) { const IfcGeom::Element

* parent_object = NULL; bool hasParent = true; + + // get the parent try { parent_object = getObject(ret->parent_id()); } catch (std::exception e) { hasParent = false; } + // We need to find an IfcBuildingStorey in the parent while (parent_object != NULL && parent_object->type() != "IfcBuildingStorey" && hasParent) { - try { parent_object = getObject(parent_object->parent_id()); } catch (std::exception e) { From 470e8e772e4352beae4126a45097ffb7181c3d63 Mon Sep 17 00:00:00 2001 From: Tristan Zimpfer Date: Fri, 21 Apr 2017 16:15:41 +0200 Subject: [PATCH 16/36] Comments + conditions for sorting the deferred objects added. --- src/ifcconvert/ColladaSerializer.cpp | 32 ++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 0e8b3d83a6..b87d33ebdd 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -221,11 +221,13 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add( } void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::Element& parent){ - + //we open the visual scene tag if it's not. if (!scene_opened) { openVisualScene(scene_id); scene_opened = true; } + + const std::vector matrix = parent.transformation().matrix().data(); double matrix_array[4][4] = { @@ -235,6 +237,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: { 0, 0, 0, 1 } }; + //adding the offset to the matrix matrix_array[0][3] += serializer->settings().offset[0]; matrix_array[1][3] += serializer->settings().offset[1]; matrix_array[2][3] += serializer->settings().offset[2]; @@ -366,8 +369,14 @@ void ColladaSerializer::ColladaExporter::endDocument() { // In fact due the XML based nature of Collada and its dependency on library nodes, // only at this point all objects are written to the stream. materials.write(); + + std::set geometries_written; - std::sort(deferreds.begin(), deferreds.end()); + + //if the setting USE_ELEMENT_HIERARCHY is in use, we sort the deferreds objects by their parents. + if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY)) { + std::sort(deferreds.begin(), deferreds.end()); + } for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { if (geometries_written.find(it->representation_id) != geometries_written.end()) { continue; @@ -376,26 +385,31 @@ void ColladaSerializer::ColladaExporter::endDocument() { geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials, it->uvs); } geometries.close(); + int parent_id = -1; bool is_parent_empty = true; - for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) - { + for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){ const std::string object_name = it->unique_id; - if (it->parent != NULL && parent_id != it->parent->id()) - { - if (!is_parent_empty) - { + //if the setting USE_ELEMENT_HIERARCHY is in use, we check if the parent changed + if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && it->parent != NULL && parent_id != it->parent->id()){ + + //close the parent tag, if one is already open. + if (!is_parent_empty){ scene.closeParent(); } parent_id = it->parent->id(); scene.addParent(*it->parent); is_parent_empty = false; } + /// @todo redundant information using ID as both ID and Name, maybe omit Name or allow specifying what would be used as the name scene.add(object_name, object_name, it->representation_id, it->material_references, it->matrix); } - if (!is_parent_empty) scene.closeParent(); + //close the last parent tag. + if (!is_parent_empty) { + scene.closeParent(); + }; scene.write(); stream.endDocument(); } From 08e4d16f28f7531e22e22acfa5d72b6467bc1f70 Mon Sep 17 00:00:00 2001 From: Tristan Zimpfer Date: Fri, 21 Apr 2017 18:05:35 +0200 Subject: [PATCH 17/36] Modified the condition checking if the parent had changed so an object without parent isn't placed in a storey. --- src/ifcconvert/ColladaSerializer.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index b87d33ebdd..1512b2836f 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -369,7 +369,6 @@ void ColladaSerializer::ColladaExporter::endDocument() { // In fact due the XML based nature of Collada and its dependency on library nodes, // only at this point all objects are written to the stream. materials.write(); - std::set geometries_written; @@ -391,16 +390,19 @@ void ColladaSerializer::ColladaExporter::endDocument() { for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){ const std::string object_name = it->unique_id; - //if the setting USE_ELEMENT_HIERARCHY is in use, we check if the parent changed - if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && it->parent != NULL && parent_id != it->parent->id()){ + //if the setting USE_ELEMENT_HIERARCHY is in use, we check if the parent has changed + if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && ((it->parent == NULL && parent_id != -1) || (it->parent != NULL && parent_id != it->parent->id()))){ //close the parent tag, if one is already open. if (!is_parent_empty){ scene.closeParent(); } - parent_id = it->parent->id(); - scene.addParent(*it->parent); - is_parent_empty = false; + + if (it->parent != NULL){ + parent_id = it->parent->id(); + scene.addParent(*it->parent); + is_parent_empty = false; + } } /// @todo redundant information using ID as both ID and Name, maybe omit Name or allow specifying what would be used as the name From 7edca081bfd4b9758325e7270317d23cd4a97929 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 25 Apr 2017 10:13:18 +0200 Subject: [PATCH 18/36] Raise an error when the option --use-element-hierarchy is used with a file different of .dae --- src/ifcconvert/IfcConvert.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index f6f45bb143..ca0226852c 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -508,6 +508,14 @@ int main(int argc, char** argv) return EXIT_FAILURE; } + if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && output_extension != ".dae") + { + Logger::Error("--user-element-hierarchy can be used only with .dae output."); + write_log(); + print_usage(); + return EXIT_FAILURE; + } + const bool is_tesselated = serializer->isTesselated(); // isTesselated() doesn't change at run-time if (!is_tesselated) { if (weld_vertices) { From 26a9167eea3b961676af1c21dca3bf2a26e1974b Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 25 Apr 2017 11:55:09 +0200 Subject: [PATCH 19/36] Add coments --- src/ifcconvert/ColladaSerializer.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 1512b2836f..5a555e40fa 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -369,11 +369,12 @@ void ColladaSerializer::ColladaExporter::endDocument() { // In fact due the XML based nature of Collada and its dependency on library nodes, // only at this point all objects are written to the stream. materials.write(); + bool use_hierarchy = serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY); std::set geometries_written; //if the setting USE_ELEMENT_HIERARCHY is in use, we sort the deferreds objects by their parents. - if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY)) { + if (use_hierarchy) { std::sort(deferreds.begin(), deferreds.end()); } for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { @@ -386,22 +387,23 @@ void ColladaSerializer::ColladaExporter::endDocument() { geometries.close(); int parent_id = -1; - bool is_parent_empty = true; + bool is_parent_tag_opened = false; for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){ const std::string object_name = it->unique_id; - //if the setting USE_ELEMENT_HIERARCHY is in use, we check if the parent has changed - if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && ((it->parent == NULL && parent_id != -1) || (it->parent != NULL && parent_id != it->parent->id()))){ - - //close the parent tag, if one is already open. - if (!is_parent_empty){ + // if the setting USE_ELEMENT_HIERARCHY is used + // And if "it" has not parent AND a parent node is opened, OR it has a parent AND another parent node is opened + if (use_hierarchy && ((it->parent == NULL && parent_id != -1) || (it->parent != NULL && parent_id != it->parent->id()))) + { + //close the parent tag if one is already open. + if (is_parent_tag_opened){ scene.closeParent(); } if (it->parent != NULL){ parent_id = it->parent->id(); scene.addParent(*it->parent); - is_parent_empty = false; + is_parent_tag_opened = true; } } @@ -409,7 +411,7 @@ void ColladaSerializer::ColladaExporter::endDocument() { scene.add(object_name, object_name, it->representation_id, it->material_references, it->matrix); } //close the last parent tag. - if (!is_parent_empty) { + if (is_parent_tag_opened) { scene.closeParent(); }; scene.write(); From 1d8f6addf80feb3dde8310268bcafd63faec2e3a Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 25 Apr 2017 16:27:14 +0200 Subject: [PATCH 20/36] Get the information on the IfcSlab (floor or roof..) and put it in the element name. To be cleaned --- src/ifcconvert/ColladaSerializer.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 5a555e40fa..b6d5809c23 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -341,9 +341,20 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o) { const IfcGeom::Representation::Triangulation& mesh = o->geometry(); + + std::string slabSuffix = ""; + if (o->type() == "IfcSlab") + { + IfcSlab* slab = (IfcSlab*)o->product(); + std::cout << "before if \n"; + if (slab->PredefinedType() == IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_ROOF) slabSuffix = " Roof"; + else if (slab->PredefinedType() == IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_FLOOR) slabSuffix = " Floor"; + std::cout << "after if \n"; + } + const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? - o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() : o->unique_id())); + o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + slabSuffix : o->unique_id())); const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); std::vector material_references; foreach(const IfcGeom::Material& material, mesh.materials()) { From 78b904dfeb4af46ddbd0d5c542055e5225d00187 Mon Sep 17 00:00:00 2001 From: Tristan Zimpfer Date: Wed, 26 Apr 2017 10:28:38 +0200 Subject: [PATCH 21/36] Differentiate slab types when option --use-element-types is used. --- src/ifcconvert/ColladaSerializer.cpp | 25 +++++++++++++++++++------ src/ifcconvert/ColladaSerializer.h | 1 + src/ifcconvert/IfcConvert.cpp | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index b6d5809c23..98673ba243 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -345,11 +345,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme std::string slabSuffix = ""; if (o->type() == "IfcSlab") { - IfcSlab* slab = (IfcSlab*)o->product(); - std::cout << "before if \n"; - if (slab->PredefinedType() == IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_ROOF) slabSuffix = " Roof"; - else if (slab->PredefinedType() == IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_FLOOR) slabSuffix = " Floor"; - std::cout << "after if \n"; + slabSuffix = differentiateSlabTypes(o); } const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? @@ -373,7 +369,24 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs())); deferreds.push_back(defered); - +} + +std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement* o) { + IfcSlab* slab = (IfcSlab*)o->product(); + switch (slab->PredefinedType()){ + case (IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_ROOF): + return "_Roof"; + break; + case (IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_LANDING): + return "_Landing"; + break; + case (IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_BASESLAB): + return "_BasesLab"; + break; + default: + return "_Unknown"; + break; + } } void ColladaSerializer::ColladaExporter::endDocument() { diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 82473ec4d6..15bf6f84b8 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -198,6 +198,7 @@ private: COLLADABU::NativeString filename; COLLADASW::StreamWriter stream; ColladaScene scene; + std::string differentiateSlabTypes(const IfcGeom::TriangulationElement* o); public: /// @param double_precision Whether to use "double precision" (up to 16 decimals) or not (6 or 7 decimals). ColladaExporter(const std::string& scene_name, const std::string& fn, ColladaSerializer *_serializer, diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index ca0226852c..05bb2602b5 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -510,7 +510,7 @@ int main(int argc, char** argv) if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && output_extension != ".dae") { - Logger::Error("--user-element-hierarchy can be used only with .dae output."); + Logger::Error("--use-element-hierarchy can be used only with .dae output."); write_log(); print_usage(); return EXIT_FAILURE; From e3e4fba63a89e1c9777e2d8d3fbd20ca311a0d3a Mon Sep 17 00:00:00 2001 From: Tristan Zimpfer Date: Wed, 26 Apr 2017 10:59:07 +0200 Subject: [PATCH 22/36] Clean of the double declaration of IfcSlabTypeEnum. --- src/ifcconvert/ColladaSerializer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 98673ba243..8fea20fa6e 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -374,13 +374,13 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement* o) { IfcSlab* slab = (IfcSlab*)o->product(); switch (slab->PredefinedType()){ - case (IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_ROOF): + case (IfcSlabTypeEnum::IfcSlabType_ROOF): return "_Roof"; break; - case (IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_LANDING): + case (IfcSlabTypeEnum::IfcSlabType_LANDING): return "_Landing"; break; - case (IfcSlabTypeEnum::IfcSlabTypeEnum::IfcSlabType_BASESLAB): + case (IfcSlabTypeEnum::IfcSlabType_BASESLAB): return "_BasesLab"; break; default: From a6ffa7fc4287bc9476bfa6153a17830ec95c1b23 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 9 May 2017 14:40:23 +0200 Subject: [PATCH 23/36] Fix : fill the storey property of an Element with NULL when we don't find any IfcBuildingStorey parent --- src/ifcconvert/ColladaSerializer.cpp | 4 ++-- src/ifcconvert/ColladaSerializer.h | 4 ++-- src/ifcgeom/IfcGeomIterator.h | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 8fea20fa6e..7097b6febd 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -363,8 +363,8 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme material_references.push_back(material_name); } - DeferredObject defered = (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) ? - DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), + DeferredObject defered = (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && o->storey() != NULL ? + DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), *(o->storey())) : DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs())); diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 15bf6f84b8..fe7ac48765 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -132,12 +132,12 @@ private: if (parent1 == NULL || parent2 == NULL) { - bool res = (def_obj1.unique_id < def_obj2.unique_id ? true : false); + bool res = (parent1 == NULL) ? true : false; return res; } else { - bool res = parent1->name() < parent2->name() ? true : false; + bool res = parent1->name().compare(parent2->name()) > 0 ? true : false; return res; } } diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index 8b90046e69..223704bb6a 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -604,6 +604,7 @@ namespace IfcGeom { } if (hasParent) { ret->SetFloor(parent_object); } + else { ret->SetFloor(NULL); } // Set it so null in order to know that we didn't found any IfcBuildingStorey type parent } } From 3c2fbcc4e17aa2b0fb1c85e8c232284d51492019 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 9 May 2017 15:54:21 +0200 Subject: [PATCH 24/36] Feature : Handle every IfcSlabTypeEnum (3 were missing) and sort the floors by elevation --- src/ifcconvert/ColladaSerializer.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index fe7ac48765..60fd39370f 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -127,17 +127,34 @@ private: class DeferredObject { friend bool operator < (const DeferredObject & def_obj1, const DeferredObject & def_obj2) { + // Retrieve the parents of the objects to compare const IfcGeom::Element* parent1 = def_obj1.parent; const IfcGeom::Element* parent2 = def_obj2.parent; + // If a parent is null if (parent1 == NULL || parent2 == NULL) { bool res = (parent1 == NULL) ? true : false; return res; } + // If both parent are not null else { - bool res = parent1->name().compare(parent2->name()) > 0 ? true : false; + // Retrieve the IfcBuildingStorey + Ifc2x3::IfcBuildingStorey* storey1 = (Ifc2x3::IfcBuildingStorey*)parent1->product(); + Ifc2x3::IfcBuildingStorey* storey2 = (Ifc2x3::IfcBuildingStorey*)parent2->product(); + + bool res = true; + + // Check if the storeys both have an elevation value + if (storey1->hasElevation() && storey2->hasElevation()) + { + // Use the elevation in order to sort + res = storey1->Elevation() > storey2->Elevation() ? true : false; + } + // If the evelations are not set, use the names to sort + else { res = parent1->name().compare(parent2->name()) > 0 ? true : false; } + return res; } } From ef0e9d9eb4d1e6c2600bd9b636d341e1008cf6f0 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 9 May 2017 15:55:37 +0200 Subject: [PATCH 25/36] Feature : Handle every IfcSlabTypeEnum (3 were missing) and sort the floors by elevation --- src/ifcconvert/ColladaSerializer.cpp | 38 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 7097b6febd..2015e7791c 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -373,20 +373,30 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement* o) { IfcSlab* slab = (IfcSlab*)o->product(); - switch (slab->PredefinedType()){ - case (IfcSlabTypeEnum::IfcSlabType_ROOF): - return "_Roof"; - break; - case (IfcSlabTypeEnum::IfcSlabType_LANDING): - return "_Landing"; - break; - case (IfcSlabTypeEnum::IfcSlabType_BASESLAB): - return "_BasesLab"; - break; - default: - return "_Unknown"; - break; - } + switch (slab->PredefinedType()) + { + case (IfcSlabTypeEnum::IfcSlabType_FLOOR): + return "_Floor"; + break; + case (IfcSlabTypeEnum::IfcSlabType_ROOF): + return "_Roof"; + break; + case (IfcSlabTypeEnum::IfcSlabType_LANDING): + return "_Landing"; + break; + case (IfcSlabTypeEnum::IfcSlabType_BASESLAB): + return "_BaseSlab"; + break; + case (IfcSlabTypeEnum::IfcSlabType_USERDEFINED): + return "_" + slab->ObjectType(); + break; + case (IfcSlabTypeEnum::IfcSlabType_NOTDEFINED): + return "_NotDefined"; + break; + default: + return "_Unknown"; + break; + } } void ColladaSerializer::ColladaExporter::endDocument() { From 93ece6b3eab27a71e70636081efec0db9fefdca6 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Thu, 11 May 2017 11:49:25 +0200 Subject: [PATCH 26/36] Fix : Add missing include --- src/ifcconvert/ColladaSerializer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 60fd39370f..3eaba5988d 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -44,6 +44,7 @@ #include "../ifcgeom/IfcGeomIterator.h" #include "../ifcconvert/GeometrySerializer.h" +#include "../ifcparse/Ifc2x3.h" class ColladaSerializer : public GeometrySerializer { From 4f6e8a7d56cf9067eed9bdb2235b55437340021b Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Thu, 11 May 2017 13:27:00 +0200 Subject: [PATCH 27/36] Fix : Change wrong namespace --- src/ifcconvert/ColladaSerializer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 60fd39370f..4529a2d6a6 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -141,8 +141,8 @@ private: else { // Retrieve the IfcBuildingStorey - Ifc2x3::IfcBuildingStorey* storey1 = (Ifc2x3::IfcBuildingStorey*)parent1->product(); - Ifc2x3::IfcBuildingStorey* storey2 = (Ifc2x3::IfcBuildingStorey*)parent2->product(); + IfcSchema::IfcBuildingStorey* storey1 = (IfcSchema::IfcBuildingStorey*)parent1->product(); + IfcSchema::IfcBuildingStorey* storey2 = (IfcSchema::IfcBuildingStorey*)parent2->product(); bool res = true; From ff64ce1e0e5573a9e1ed4c807005d1f5b5edfdd9 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Thu, 11 May 2017 14:02:34 +0200 Subject: [PATCH 28/36] Fix : change wrong namespace --- src/ifcconvert/ColladaSerializer.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 3eaba5988d..4529a2d6a6 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -44,7 +44,6 @@ #include "../ifcgeom/IfcGeomIterator.h" #include "../ifcconvert/GeometrySerializer.h" -#include "../ifcparse/Ifc2x3.h" class ColladaSerializer : public GeometrySerializer { @@ -142,8 +141,8 @@ private: else { // Retrieve the IfcBuildingStorey - Ifc2x3::IfcBuildingStorey* storey1 = (Ifc2x3::IfcBuildingStorey*)parent1->product(); - Ifc2x3::IfcBuildingStorey* storey2 = (Ifc2x3::IfcBuildingStorey*)parent2->product(); + IfcSchema::IfcBuildingStorey* storey1 = (IfcSchema::IfcBuildingStorey*)parent1->product(); + IfcSchema::IfcBuildingStorey* storey2 = (IfcSchema::IfcBuildingStorey*)parent2->product(); bool res = true; From be3dbce9f49c51e349974d4e98b97274498e11de Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Mon, 15 May 2017 17:45:05 +0200 Subject: [PATCH 29/36] feature (WIP) : retrieve full hierarchy Bug : the element are not at the right location --- src/ifcconvert/ColladaSerializer.cpp | 286 +++++++++++++++++++++++---- src/ifcconvert/ColladaSerializer.h | 67 ++++--- src/ifcconvert/XmlSerializer.cpp | 1 + src/ifcgeom/IfcGeomElement.h | 29 ++- src/ifcgeom/IfcGeomIterator.h | 46 +++-- 5 files changed, 345 insertions(+), 84 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 2015e7791c..f00b6592ae 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -29,12 +29,19 @@ #include #include -#include - #include #include +#include +#include +#include +#include +#include +#include +#include + using namespace IfcSchema; +using namespace boost::numeric::ublas; static void collada_id(std::string &s) { @@ -181,7 +188,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::close() { void ColladaSerializer::ColladaExporter::ColladaScene::add( const std::string& node_id, const std::string& node_name, const std::string& geom_name, - const std::vector& material_ids, const std::vector& matrix) + const std::vector& material_ids, const std::vector& posmatrix) { if (!scene_opened) { openVisualScene(scene_id); @@ -195,13 +202,42 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add( // The matrix attribute of an entity is basically a 4x3 representation of its ObjectPlacement. // Note that this placement is absolute, ie it is multiplied with all parent placements. + double matrix_array[4][4] = { - { (double)matrix[0], (double)matrix[3], (double)matrix[6], (double)matrix[ 9] }, - { (double)matrix[1], (double)matrix[4], (double)matrix[7], (double)matrix[10] }, - { (double)matrix[2], (double)matrix[5], (double)matrix[8], (double)matrix[11] }, + { (double)posmatrix[0], (double)posmatrix[3], (double)posmatrix[6], (double)posmatrix[ 9] }, + { (double)posmatrix[1], (double)posmatrix[4], (double)posmatrix[7], (double)posmatrix[10] }, + { (double)posmatrix[2], (double)posmatrix[5], (double)posmatrix[8], (double)posmatrix[11] }, { 0, 0, 0, 1 } }; + + // If this is not the first parent, get the relative placement + if (parentNodes.size() > 0) + { + double relative[4][4] = { + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 } + }; + std::cout << "placement de " << node_name << " | utilisation de " << parentNodes.top()->getNodeName() << "\n"; + // Multiplication + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + for (int k = 0; k < 4; ++k) { + relative[i][j] += matrix_array[i][k] * matrixStack.top()(k, j); + } + } + } + // Copy from relative to matrix_array + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + matrix_array[i][j] = relative[i][j]; + } + } + + } + matrix_array[0][3] += serializer->settings().offset[0]; matrix_array[1][3] += serializer->settings().offset[1]; matrix_array[2][3] += serializer->settings().offset[2]; @@ -228,33 +264,180 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: } - const std::vector matrix = parent.transformation().matrix().data(); + const std::vector parentMatrix = parent.transformation().matrix().data(); double matrix_array[4][4] = { - { (double)matrix[0], (double)matrix[3], (double)matrix[6], (double)matrix[9] }, - { (double)matrix[1], (double)matrix[4], (double)matrix[7], (double)matrix[10] }, - { (double)matrix[2], (double)matrix[5], (double)matrix[8], (double)matrix[11] }, + { (double)parentMatrix[0], (double)parentMatrix[3], (double)parentMatrix[6], (double)parentMatrix[9] }, + { (double)parentMatrix[1], (double)parentMatrix[4], (double)parentMatrix[7], (double)parentMatrix[10] }, + { (double)parentMatrix[2], (double)parentMatrix[5], (double)parentMatrix[8], (double)parentMatrix[11] }, { 0, 0, 0, 1 } }; + + // ========= + + // If this is not the first parent, get the relative placement + if (parentNodes.size() > 0) + { + double relative[4][4] = { + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 } + }; + std::cout << "placement de " << parent.name() << "_" << parent.type() << " | utilisation de " << parentNodes.top()->getNodeName() << "\n"; + // Multiplication + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + for (int k = 0; k < 4; ++k) { + relative[i][j] += matrix_array[i][k] * matrixStack.top()(k, j); + } + } + } + // TODO : Handle the case where there was no inverse + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + matrix_array[i][j] = relative[i][j]; + } + } + } + //adding the offset to the matrix - matrix_array[0][3] += serializer->settings().offset[0]; - matrix_array[1][3] += serializer->settings().offset[1]; - matrix_array[2][3] += serializer->settings().offset[2]; + //matrix_array[0][3] += serializer->settings().offset[0]; + //matrix_array[1][3] += serializer->settings().offset[1]; + //matrix_array[2][3] += serializer->settings().offset[2]; const std::string id = "representation-" + boost::lexical_cast(parent.id()); + COLLADASW::Node *current_node; current_node = new COLLADASW::Node(mSW); current_node->setNodeId(id); - current_node->setNodeName(parent.name()); + current_node->setNodeName(parent.type() + " " + parent.name()); current_node->addMatrix(matrix_array); current_node->setType(COLLADASW::Node::NODE); current_node->start(); + + // ==== Inverse the matrix and save it ==== + + double m[4][4] = { + { (double)parentMatrix[0], (double)parentMatrix[3], (double)parentMatrix[6], (double)parentMatrix[9] }, + { (double)parentMatrix[1], (double)parentMatrix[4], (double)parentMatrix[7], (double)parentMatrix[10] }, + { (double)parentMatrix[2], (double)parentMatrix[5], (double)parentMatrix[8], (double)parentMatrix[11] }, + { 0, 0, 0, 1 } + }; + + double det = + m[0][3] * m[1][2] * m[2][1] * m[3][0] - m[0][2] * m[1][3] * m[2][1] * m[3][0] - m[0][3] * m[1][1] * m[2][2] * m[3][0] + m[0][1] * m[1][3] * m[2][2] * m[3][0] + + m[0][2] * m[1][1] * m[2][3] * m[3][0] - m[0][1] * m[1][2] * m[2][3] * m[3][0] - m[0][3] * m[1][2] * m[2][0] * m[3][1] + m[0][2] * m[1][3] * m[2][0] * m[3][1] + + m[0][3] * m[1][0] * m[2][2] * m[3][1] - m[0][0] * m[1][3] * m[2][2] * m[3][1] - m[0][2] * m[1][0] * m[2][3] * m[3][1] + m[0][0] * m[1][2] * m[2][3] * m[3][1] + + m[0][3] * m[1][1] * m[2][0] * m[3][2] - m[0][1] * m[1][3] * m[2][0] * m[3][2] - m[0][3] * m[1][0] * m[2][1] * m[3][2] + m[0][0] * m[1][3] * m[2][1] * m[3][2] + + m[0][1] * m[1][0] * m[2][3] * m[3][2] - m[0][0] * m[1][1] * m[2][3] * m[3][2] - m[0][2] * m[1][1] * m[2][0] * m[3][3] + m[0][1] * m[1][2] * m[2][0] * m[3][3] + + m[0][2] * m[1][0] * m[2][1] * m[3][3] - m[0][0] * m[1][2] * m[2][1] * m[3][3] - m[0][1] * m[1][0] * m[2][2] * m[3][3] + m[0][0] * m[1][1] * m[2][2] * m[3][3]; + + + if (det != 0) + { + double inverse[4][4]; + inverse[0][0] = m[1][2] * m[2][3] * m[3][1] - m[1][3] * m[2][2] * m[3][1] + m[1][3] * m[2][1] * m[3][2] - m[1][1] * m[2][3] * m[3][2] - m[1][2] * m[2][1] * m[3][3] + m[1][1] * m[2][2] * m[3][3]; + inverse[0][1] = m[0][3] * m[2][2] * m[3][1] - m[0][2] * m[2][3] * m[3][1] - m[0][3] * m[2][1] * m[3][2] + m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] - m[0][1] * m[2][2] * m[3][3]; + inverse[0][2] = m[0][2] * m[1][3] * m[3][1] - m[0][3] * m[1][2] * m[3][1] + m[0][3] * m[1][1] * m[3][2] - m[0][1] * m[1][3] * m[3][2] - m[0][2] * m[1][1] * m[3][3] + m[0][1] * m[1][2] * m[3][3]; + inverse[0][3] = m[0][3] * m[1][2] * m[2][1] - m[0][2] * m[1][3] * m[2][1] - m[0][3] * m[1][1] * m[2][2] + m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] - m[0][1] * m[1][2] * m[2][3]; + + inverse[1][0] = m[1][3] * m[2][2] * m[3][0] - m[1][2] * m[2][3] * m[3][0] - m[1][3] * m[2][0] * m[3][2] + m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] - m[1][0] * m[2][2] * m[3][3]; + inverse[1][1] = m[0][2] * m[2][3] * m[3][0] - m[0][3] * m[2][2] * m[3][0] + m[0][3] * m[2][0] * m[3][2] - m[0][0] * m[2][3] * m[3][2] - m[0][2] * m[2][0] * m[3][3] + m[0][0] * m[2][2] * m[3][3]; + inverse[1][2] = m[0][3] * m[1][2] * m[3][0] - m[0][2] * m[1][3] * m[3][0] - m[0][3] * m[1][0] * m[3][2] + m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] - m[0][0] * m[1][2] * m[3][3]; + inverse[1][3] = m[0][2] * m[1][3] * m[2][0] - m[0][3] * m[1][2] * m[2][0] + m[0][3] * m[1][0] * m[2][2] - m[0][0] * m[1][3] * m[2][2] - m[0][2] * m[1][0] * m[2][3] + m[0][0] * m[1][2] * m[2][3]; + + inverse[2][0] = m[1][1] * m[2][3] * m[3][0] - m[1][3] * m[2][1] * m[3][0] + m[1][3] * m[2][0] * m[3][1] - m[1][0] * m[2][3] * m[3][1] - m[1][1] * m[2][0] * m[3][3] + m[1][0] * m[2][1] * m[3][3]; + inverse[2][1] = m[0][3] * m[2][1] * m[3][0] - m[0][1] * m[2][3] * m[3][0] - m[0][3] * m[2][0] * m[3][1] + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] - m[0][0] * m[2][1] * m[3][3]; + inverse[2][2] = m[0][1] * m[1][3] * m[3][0] - m[0][3] * m[1][1] * m[3][0] + m[0][3] * m[1][0] * m[3][1] - m[0][0] * m[1][3] * m[3][1] - m[0][1] * m[1][0] * m[3][3] + m[0][0] * m[1][1] * m[3][3]; + inverse[2][3] = m[0][3] * m[1][1] * m[2][0] - m[0][1] * m[1][3] * m[2][0] - m[0][3] * m[1][0] * m[2][1] + m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] - m[0][0] * m[1][1] * m[2][3]; + + inverse[3][0] = m[1][2] * m[2][1] * m[3][0] - m[1][1] * m[2][2] * m[3][0] - m[1][2] * m[2][0] * m[3][1] + m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - m[1][0] * m[2][1] * m[3][2]; + inverse[3][1] = m[0][1] * m[2][2] * m[3][0] - m[0][2] * m[2][1] * m[3][0] + m[0][2] * m[2][0] * m[3][1] - m[0][0] * m[2][2] * m[3][1] - m[0][1] * m[2][0] * m[3][2] + m[0][0] * m[2][1] * m[3][2]; + inverse[3][2] = m[0][2] * m[1][1] * m[3][0] - m[0][1] * m[1][2] * m[3][0] - m[0][2] * m[1][0] * m[3][1] + m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - m[0][0] * m[1][1] * m[3][2]; + inverse[3][3] = m[0][1] * m[1][2] * m[2][0] - m[0][2] * m[1][1] * m[2][0] + m[0][2] * m[1][0] * m[2][1] - m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2] + m[0][0] * m[1][1] * m[2][2]; + + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + inverse[i][j] /= det; + } + } + + std::cout << " ===== TEST INVERSE " << parent.name() << "===== \n"; + double test[4][4]; + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + test[i][j] = 0; + } + } + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + for (int k = 0; k < 4; ++k) { + if (false) + { + std::cout << "test [" << i << "][" << j << "] += " << m[i][k] << " * " << inverse[k][j] << "\n"; + } + test[i][j] += m[i][k] * inverse[k][j]; + } + } + } + + std::cout << "matrix array : \n"; + std::cout << m[0][0] << " | " << m[0][1] << " | " << m[0][2] << " | " << m[0][3] << " \n "; + std::cout << m[1][0] << " | " << m[1][1] << " | " << m[1][2] << " | " << m[1][3] << " \n "; + std::cout << m[2][0] << " | " << m[2][1] << " | " << m[2][2] << " | " << m[2][3] << " \n "; + std::cout << m[3][0] << " | " << m[3][1] << " | " << m[3][2] << " | " << m[3][3] << " \n "; + + std::cout << "det = " << det << "\n"; + + std::cout << "test array : \n"; + std::cout << test[0][0] << " | " << test[0][1] << " | " << test[0][2] << " | " << test[0][3] << " \n "; + std::cout << test[1][0] << " | " << test[1][1] << " | " << test[1][2] << " | " << test[1][3] << " \n "; + std::cout << test[2][0] << " | " << test[2][1] << " | " << test[2][2] << " | " << test[2][3] << " \n "; + std::cout << test[3][0] << " | " << test[3][1] << " | " << test[3][2] << " | " << test[3][3] << " \n "; + + matrix save(4, 4); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + save(i, j) = inverse[i][j]; + } + } + + matrixStack.push(save); + } + else + { + std::cout << "couldn't inverse the position matrix \n"; + } + + // Add the node to the parent stack + parentNodes.push(current_node); + serializer->parentStackId.push(parent.id()); + } -void ColladaSerializer::ColladaExporter::ColladaScene::closeParent(){ - if (current_node != NULL) { current_node->end(); } +void ColladaSerializer::ColladaExporter::ColladaScene::closeParent() +{ + // Get the top element + COLLADASW::Node *current_node = parentNodes.top(); + + // Close the node + current_node->end(); + + // Remove it from the stack + parentNodes.pop(); + matrixStack.pop(); + serializer->parentStackId.pop(); + + // Free the memory + delete current_node; + current_node = NULL; } void ColladaSerializer::ColladaExporter::ColladaScene::write() { @@ -350,7 +533,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? - o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + slabSuffix : o->unique_id())); + o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + std::to_string(o->id()) + slabSuffix : o->unique_id())); const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); std::vector material_references; foreach(const IfcGeom::Material& material, mesh.materials()) { @@ -363,9 +546,9 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme material_references.push_back(material_name); } - DeferredObject defered = (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) && o->storey() != NULL ? + DeferredObject defered = (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) ? DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), - mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), *(o->storey())) : + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), o->parents()) : DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs())); deferreds.push_back(defered); @@ -408,9 +591,11 @@ void ColladaSerializer::ColladaExporter::endDocument() { std::set geometries_written; //if the setting USE_ELEMENT_HIERARCHY is in use, we sort the deferreds objects by their parents. + if (use_hierarchy) { std::sort(deferreds.begin(), deferreds.end()); } + for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { if (geometries_written.find(it->representation_id) != geometries_written.end()) { continue; @@ -425,29 +610,62 @@ void ColladaSerializer::ColladaExporter::endDocument() { for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){ const std::string object_name = it->unique_id; - // if the setting USE_ELEMENT_HIERARCHY is used - // And if "it" has not parent AND a parent node is opened, OR it has a parent AND another parent node is opened - if (use_hierarchy && ((it->parent == NULL && parent_id != -1) || (it->parent != NULL && parent_id != it->parent->id()))) + /* + std::cout << "******************************\n"; + std::cout << "== " << it->unique_id << " ==\n"; + std::cout << " has " << it->parents.size() << " parents \n"; + for (unsigned i = 0; i < it->parents.size(); i++) { - //close the parent tag if one is already open. - if (is_parent_tag_opened){ - scene.closeParent(); - } + std::cout << "=== " << it->parents.at(i)->name() << " | " << it->parents.at(i)->id() << " ===\n"; + } + */ - if (it->parent != NULL){ - parent_id = it->parent->id(); - scene.addParent(*it->parent); - is_parent_tag_opened = true; + // TODO : handle the case where a representation object has no parent (Can this really happen ?) + if (use_hierarchy) + { + unsigned parentsNumber = it->parents.size(); + bool finished = false; + while (!finished) + { + // If we need to add a parent + if (serializer->parentStackId.size() <= parentsNumber) + { + if (serializer->parentStackId.empty()) { scene.addParent(*(it->parents.at(0))); } + else + { + unsigned diff = parentsNumber - serializer->parentStackId.size(); + + // If we have the wrong parent in the list + if (serializer->parentStackId.top() != it->parents.at(parentsNumber - diff - 1)->id()) + { + scene.closeParent(); + } + // So far we have the right parents, we just need to add the missing ones + else + { + for (unsigned i = parentsNumber - diff; i < parentsNumber; i++) { scene.addParent(*(it->parents.at(i))); } + + // if diff == 0, we can leave the loop. In fact we have the right number of parents, and the last one is ok + if (diff == 0) { finished = true; } + } + } + } + // IF serializer->parentStackId.size() > parentsNumber + else + { + // Close the finished nodes. After this we get the first case (serializer->parentStackId.size() <= parentsNumber) + while (serializer->parentStackId.size() > parentsNumber) { scene.closeParent(); } + } } } /// @todo redundant information using ID as both ID and Name, maybe omit Name or allow specifying what would be used as the name scene.add(object_name, object_name, it->representation_id, it->material_references, it->matrix); } - //close the last parent tag. - if (is_parent_tag_opened) { - scene.closeParent(); - }; + + //close the remaining parent tags. + while (serializer->parentStackId.size() > 0) { scene.closeParent(); } + scene.write(); stream.endDocument(); } diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 4529a2d6a6..df86842f28 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -45,10 +45,16 @@ #include "../ifcconvert/GeometrySerializer.h" +#include +#include + + class ColladaSerializer : public GeometrySerializer { // TODO The vast amount of implement details of ColladaSerializer could be hidden to the cpp file. private: + std::stack parentStackId; + class ColladaExporter { private: @@ -79,7 +85,8 @@ private: const std::string scene_id; bool scene_opened; - COLLADASW::Node *current_node; + std::stack parentNodes; + std::stack> matrixStack; public: ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryVisualScenes(&stream) @@ -91,6 +98,7 @@ private: const std::vector& material_ids, const std::vector& matrix); void addParent(const IfcGeom::Element& parent); void closeParent(); + COLLADASW::Node* GetDirectParent(); void write(); ColladaSerializer *serializer; }; @@ -125,39 +133,37 @@ private: ColladaEffects effects; }; class DeferredObject { + friend bool operator < (const DeferredObject & def_obj1, const DeferredObject & def_obj2) { - // Retrieve the parents of the objects to compare - const IfcGeom::Element* parent1 = def_obj1.parent; - const IfcGeom::Element* parent2 = def_obj2.parent; - - // If a parent is null - if (parent1 == NULL || parent2 == NULL) + /* + std::cout << "*************** COMPARE ***************\n"; + std::cout << "range 1 : " << def_obj1.unique_id << "\n"; + for (unsigned i = 0; i < def_obj1.parents.size(); i++) { - bool res = (parent1 == NULL) ? true : false; - return res; + std::cout << "=== " << def_obj1.parents.at(i)->name() << " | " << def_obj1.parents.at(i)->id() << " ===\n"; } - // If both parent are not null + std::cout << "range 2 : " << def_obj2.unique_id << "\n"; + for (unsigned i = 0; i < def_obj2.parents.size(); i++) + { + std::cout << "=== " << def_obj2.parents.at(i)->name() << " | " << def_obj2.parents.at(i)->id() << " ===\n"; + } + */ + unsigned size = (def_obj1.parents.size() < def_obj2.parents.size() ? def_obj1.parents.size() : def_obj2.parents.size()); + int cpt = 0; + + // Skip the shared parents + while (cpt < size && *(def_obj1.parents.at(cpt)) == *(def_obj2.parents.at(cpt))) { cpt++; } + + // If a parent list container the other one + if (cpt >= size) { return (def_obj1.parents.size() < def_obj2.parents.size() ? true : false); } else { - // Retrieve the IfcBuildingStorey - IfcSchema::IfcBuildingStorey* storey1 = (IfcSchema::IfcBuildingStorey*)parent1->product(); - IfcSchema::IfcBuildingStorey* storey2 = (IfcSchema::IfcBuildingStorey*)parent2->product(); - - bool res = true; - - // Check if the storeys both have an elevation value - if (storey1->hasElevation() && storey2->hasElevation()) - { - // Use the elevation in order to sort - res = storey1->Elevation() > storey2->Elevation() ? true : false; - } - // If the evelations are not set, use the names to sort - else { res = parent1->name().compare(parent2->name()) > 0 ? true : false; } - - return res; + return *(def_obj1.parents.at(cpt)) < *(def_obj2.parents.at(cpt)); } } + + public: std::string unique_id, representation_id, type; std::vector matrix; @@ -169,11 +175,11 @@ private: std::vector materials; std::vector material_references; std::vector uvs; - const IfcGeom::Element* parent; + std::vector*> parents; DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& faces, const std::vector& edges, const std::vector& material_ids, const std::vector& materials, - const std::vector& material_references, const std::vector& uvs, const IfcGeom::Element& _parent) + const std::vector& material_references, const std::vector& uvs, const std::vector*>& parent) : unique_id(unique_id) , representation_id(representation_id) , type(type) @@ -186,7 +192,7 @@ private: , materials(materials) , material_references(material_references) , uvs(uvs) - , parent(&_parent) + , parents(parent) { } @@ -207,9 +213,8 @@ private: , materials(materials) , material_references(material_references) , uvs(uvs) - , parent(NULL) { - + parents.clear(); } }; COLLADABU::NativeString filename; diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp index 94a6dd562f..b0173273f6 100644 --- a/src/ifcconvert/XmlSerializer.cpp +++ b/src/ifcconvert/XmlSerializer.cpp @@ -110,6 +110,7 @@ boost::optional format_attribute(const Argument* argument, IfcUtil: IfcSchema::IfcLocalPlacement* placement = e->as(); gp_Trsf trsf; IfcGeom::Kernel kernel; + if (kernel.convert(placement, trsf)) { std::stringstream stream; for (int i = 1; i < 5; ++i) { diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index c2c65891c8..257a3f39a9 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -81,8 +81,21 @@ namespace IfcGeom { std::string _unique_id; Transformation

_transformation; IfcSchema::IfcProduct* product_; - const Element

* _storey; + std::vector*> _parents; public: + + friend bool operator == (const Element

& element1, const Element

& element2) + { + //std::cout << " //// Compare == " << element1.name() << element1.id() << " | " << element1.type() << " and " << element2.name() << element2.id() << " | " << element2.type() << "\n"; + return element1.id() == element2.id(); + } + + friend bool operator < (const Element

& element1, const Element

& element2) + { + //std::cout << " //// Compare < " << element1.name() << element1.id() << " | " << element1.type() << " and " << element2.name() << element2.id() << " | " << element2.type() << "\n"; + return element1.id() < element2.id(); + } + int id() const { return _id; } int parent_id() const { return _parent_id; } const std::string& name() const { return _name; } @@ -92,16 +105,21 @@ namespace IfcGeom { const std::string& unique_id() const { return _unique_id; } const Transformation

& transformation() const { return _transformation; } IfcSchema::IfcProduct* product() const { return product_; } - const Element

* storey() const { return _storey; } - void SetFloor(const Element

* floor) { _storey = floor; } + const std::vector*> parents() const { return _parents; } + void SetParents(std::vector*> newparents) { _parents = newparents; } Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const std::string& context, const gp_Trsf& trsf, IfcSchema::IfcProduct *product) : _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf) , product_(product) - { + { std::ostringstream oss; - oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); + try { oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); } + catch (std::exception e) + { + oss << "product-cannotfindId"; + } + if (!_context.empty()) { std::string ctx = _context; std::transform(ctx.begin(), ctx.end(), ctx.begin(), ::tolower); @@ -109,7 +127,6 @@ namespace IfcGeom { oss << "-" << ctx; } _unique_id = oss.str(); - } virtual ~Element() {} }; diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index 223704bb6a..2c681bcc2d 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -574,14 +574,17 @@ namespace IfcGeom { else if (current_serialization) { ret = current_serialization; } else if (current_shape_model) { ret = current_shape_model; } - // If we want to organize the element by floors we need to get the floor of the element + // If we want to organize the element considering their hierarchy if (settings.get(IteratorSettings::SEARCH_FLOOR)) { + // We are going to build a vector with the element parents. + // First, create the parent vector + std::vector*> parents; + // if the element has a parent if (ret->parent_id() != -1) { const IfcGeom::Element

* parent_object = NULL; - bool hasParent = true; // get the parent @@ -591,20 +594,28 @@ namespace IfcGeom { hasParent = false; } - // We need to find an IfcBuildingStorey in the parent - while (parent_object != NULL && parent_object->type() != "IfcBuildingStorey" && hasParent) + // Add the previously found parent to the vector + if (hasParent) parents.insert(parents.begin(), parent_object); + + // We need to find all the parents + while (parent_object != NULL && hasParent) { + // Find the next parent try { parent_object = getObject(parent_object->parent_id()); } catch (std::exception e) { + std::cout << e.what(); hasParent = false; } - hasParent = hasParent && parent_object->parent_id() != 1; + // Add the previously found parent to the vector + if (hasParent) parents.insert(parents.begin(), parent_object); + + hasParent = hasParent && parent_object->parent_id() != -1; } - if (hasParent) { ret->SetFloor(parent_object); } - else { ret->SetFloor(NULL); } // Set it so null in order to know that we didn't found any IfcBuildingStorey type parent + // when done push the parent list in the Element object + ret->SetParents(parents); } } @@ -619,38 +630,47 @@ namespace IfcGeom { } const Element

* getObject(int id) { - + //std::cout << "1"; gp_Trsf trsf; int parent_id = -1; std::string instance_type, product_name, product_guid; IfcSchema::IfcProduct* ifc_product = 0; - + //std::cout << "2"; try { const IfcUtil::IfcBaseClass* ifc_entity = ifc_file->entityById(id); instance_type = IfcSchema::Type::ToString(ifc_entity->type()); if ( ifc_entity->is(IfcSchema::Type::IfcProduct) ) { ifc_product = (IfcSchema::IfcProduct*)ifc_entity; - + //std::cout << "3"; product_guid = ifc_product->GlobalId(); product_name = ifc_product->hasName() ? ifc_product->Name() : ""; parent_id = -1; try { + //std::cout << "4"; IfcSchema::IfcObjectDefinition* parent_object = kernel.get_decomposing_entity(ifc_product); if (parent_object) { parent_id = parent_object->entity->id(); } } catch (...) {} - + //std::cout << "5"; try { kernel.convert(ifc_product->ObjectPlacement(), trsf); } catch (...) {} } + //std::cout << "6"; } catch(...) {} - + //std::cout << "7"; ElementSettings element_settings(settings, unit_magnitude, instance_type); + + //std::cout << "8"; + //std::cout << "id " << id << "\n"; + //std::cout << "parent_id " << parent_id << "\n"; + //std::cout << "product_name " << product_name << "\n"; + //std::cout << "instance_type " << instance_type << "\n"; + //std::cout << "product_guid " << product_guid << "\n"; Element

* ifc_object = new Element

(element_settings, id, parent_id, product_name, instance_type, product_guid, "", trsf, ifc_product); - + //std::cout << "9\n"; return ifc_object; } From 45ec08f8408c08f51b81842cd0717e6deb979c0d Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 16 May 2017 11:27:45 +0200 Subject: [PATCH 30/36] feature (WIP) : retrieve the full hierarchy. The placement of several objects still be incorect --- src/ifcconvert/ColladaSerializer.cpp | 46 ++++++++-------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index f00b6592ae..cb610d5005 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -219,7 +219,8 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add( { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; - std::cout << "placement de " << node_name << " | utilisation de " << parentNodes.top()->getNodeName() << "\n"; + std::cout << "-------------------------------------------------------------------------------------------------------------------------------------\n"; + std::cout << "REPRESENTATION : " << node_name << " placement, using " << parentNodes.top()->getNodeName() << " ...\n"; // Multiplication for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { @@ -284,7 +285,8 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; - std::cout << "placement de " << parent.name() << "_" << parent.type() << " | utilisation de " << parentNodes.top()->getNodeName() << "\n"; + std::cout << "-------------------------------------------------------------------------------------------------------------------------------------\n"; + std::cout << "PARENT : " << parent.name() << "_" << parent.type() << " placement, using " << parentNodes.top()->getNodeName() << " ...\n"; // Multiplication for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { @@ -315,9 +317,9 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: current_node = new COLLADASW::Node(mSW); current_node->setNodeId(id); current_node->setNodeName(parent.type() + " " + parent.name()); - current_node->addMatrix(matrix_array); current_node->setType(COLLADASW::Node::NODE); current_node->start(); + current_node->addMatrix(matrix_array); // ==== Inverse the matrix and save it ==== @@ -367,42 +369,20 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: } } - std::cout << " ===== TEST INVERSE " << parent.name() << "===== \n"; - double test[4][4]; - - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - test[i][j] = 0; - } - } - - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - for (int k = 0; k < 4; ++k) { - if (false) - { - std::cout << "test [" << i << "][" << j << "] += " << m[i][k] << " * " << inverse[k][j] << "\n"; - } - test[i][j] += m[i][k] * inverse[k][j]; - } - } - } - + /* std::cout << "matrix array : \n"; std::cout << m[0][0] << " | " << m[0][1] << " | " << m[0][2] << " | " << m[0][3] << " \n "; std::cout << m[1][0] << " | " << m[1][1] << " | " << m[1][2] << " | " << m[1][3] << " \n "; std::cout << m[2][0] << " | " << m[2][1] << " | " << m[2][2] << " | " << m[2][3] << " \n "; std::cout << m[3][0] << " | " << m[3][1] << " | " << m[3][2] << " | " << m[3][3] << " \n "; - - std::cout << "det = " << det << "\n"; - - std::cout << "test array : \n"; - std::cout << test[0][0] << " | " << test[0][1] << " | " << test[0][2] << " | " << test[0][3] << " \n "; - std::cout << test[1][0] << " | " << test[1][1] << " | " << test[1][2] << " | " << test[1][3] << " \n "; - std::cout << test[2][0] << " | " << test[2][1] << " | " << test[2][2] << " | " << test[2][3] << " \n "; - std::cout << test[3][0] << " | " << test[3][1] << " | " << test[3][2] << " | " << test[3][3] << " \n "; - + */ matrix save(4, 4); + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + save(i, j) = 0; + } + } + for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { save(i, j) = inverse[i][j]; From 942d34ee39ac525345397285b6246e89dd4227b5 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 16 May 2017 14:27:36 +0200 Subject: [PATCH 31/36] Feature : Retrieve the full hierarchy. Fix the placement of the objects. Check slab->HasObjectType before using slab->ObjectType --- src/ifcconvert/ColladaSerializer.cpp | 57 +++++++++++----------------- src/ifcgeom/IfcGeomElement.h | 16 +++++++- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index cb610d5005..ae0200b698 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -219,13 +219,12 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add( { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; - std::cout << "-------------------------------------------------------------------------------------------------------------------------------------\n"; - std::cout << "REPRESENTATION : " << node_name << " placement, using " << parentNodes.top()->getNodeName() << " ...\n"; + // Multiplication for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { for (int k = 0; k < 4; ++k) { - relative[i][j] += matrix_array[i][k] * matrixStack.top()(k, j); + relative[i][j] += matrixStack.top()(i, k) * matrix_array[k][j]; } } } @@ -285,13 +284,12 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; - std::cout << "-------------------------------------------------------------------------------------------------------------------------------------\n"; - std::cout << "PARENT : " << parent.name() << "_" << parent.type() << " placement, using " << parentNodes.top()->getNodeName() << " ...\n"; + // Multiplication for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { for (int k = 0; k < 4; ++k) { - relative[i][j] += matrix_array[i][k] * matrixStack.top()(k, j); + relative[i][j] += matrixStack.top()(i, k) * matrix_array[k][j]; } } } @@ -313,10 +311,15 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: const std::string id = "representation-" + boost::lexical_cast(parent.id()); + // Chose a name of the parent object + std::string name = ""; + if (parent.name() == "") { name = parent.type(); } + else { name = parent.name(); } + COLLADASW::Node *current_node; current_node = new COLLADASW::Node(mSW); current_node->setNodeId(id); - current_node->setNodeName(parent.type() + " " + parent.name()); + current_node->setNodeName(name); current_node->setType(COLLADASW::Node::NODE); current_node->start(); current_node->addMatrix(matrix_array); @@ -369,27 +372,25 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: } } - /* - std::cout << "matrix array : \n"; - std::cout << m[0][0] << " | " << m[0][1] << " | " << m[0][2] << " | " << m[0][3] << " \n "; - std::cout << m[1][0] << " | " << m[1][1] << " | " << m[1][2] << " | " << m[1][3] << " \n "; - std::cout << m[2][0] << " | " << m[2][1] << " | " << m[2][2] << " | " << m[2][3] << " \n "; - std::cout << m[3][0] << " | " << m[3][1] << " | " << m[3][2] << " | " << m[3][3] << " \n "; - */ - matrix save(4, 4); + // Create a save matrix to push to the stack + matrix toSave(4, 4); + + // Initialization for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { - save(i, j) = 0; + toSave(i, j) = 0; } } - + + // Copy the inverse matrix for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - save(i, j) = inverse[i][j]; + toSave(i, j) = inverse[i][j]; } } - matrixStack.push(save); + // Save the matrix + matrixStack.push(toSave); } else { @@ -513,7 +514,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme const std::string name = serializer->settings().get(SerializerSettings::USE_ELEMENT_GUIDS) ? o->guid() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_NAMES) ? - o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + std::to_string(o->id()) + slabSuffix : o->unique_id())); + o->name() : (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES) ? o->type() + slabSuffix : o->unique_id())); const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); std::vector material_references; foreach(const IfcGeom::Material& material, mesh.materials()) { @@ -550,14 +551,12 @@ std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const Ifc case (IfcSlabTypeEnum::IfcSlabType_BASESLAB): return "_BaseSlab"; break; - case (IfcSlabTypeEnum::IfcSlabType_USERDEFINED): - return "_" + slab->ObjectType(); - break; case (IfcSlabTypeEnum::IfcSlabType_NOTDEFINED): return "_NotDefined"; break; default: - return "_Unknown"; + if (slab->hasObjectType()) { return "_" + slab->ObjectType(); } + else { return "_Unknown"; } break; } } @@ -590,16 +589,6 @@ void ColladaSerializer::ColladaExporter::endDocument() { for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){ const std::string object_name = it->unique_id; - /* - std::cout << "******************************\n"; - std::cout << "== " << it->unique_id << " ==\n"; - std::cout << " has " << it->parents.size() << " parents \n"; - for (unsigned i = 0; i < it->parents.size(); i++) - { - std::cout << "=== " << it->parents.at(i)->name() << " | " << it->parents.at(i)->id() << " ===\n"; - } - */ - // TODO : handle the case where a representation object has no parent (Can this really happen ?) if (use_hierarchy) { diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index 257a3f39a9..fc25743cfe 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -86,13 +86,25 @@ namespace IfcGeom { friend bool operator == (const Element

& element1, const Element

& element2) { - //std::cout << " //// Compare == " << element1.name() << element1.id() << " | " << element1.type() << " and " << element2.name() << element2.id() << " | " << element2.type() << "\n"; return element1.id() == element2.id(); } + // Use the id to compare, or the elevation is the elements are IfcBuildingStoreys and the elevation is set friend bool operator < (const Element

& element1, const Element

& element2) { - //std::cout << " //// Compare < " << element1.name() << element1.id() << " | " << element1.type() << " and " << element2.name() << element2.id() << " | " << element2.type() << "\n"; + if (element1.type() == "IfcBuildingStorey" && element2.type() == "IfcBuildingStorey") + { + IfcSchema::IfcBuildingStorey* storey1 = NULL; + IfcSchema::IfcBuildingStorey* storey2 = NULL; + + storey1 = (IfcSchema::IfcBuildingStorey*)element1.product(); + storey2 = (IfcSchema::IfcBuildingStorey*)element2.product(); + + if (storey1 != NULL && storey2 != NULL && storey1->hasElevation() && storey2->hasElevation()) + { + return storey1->Elevation() < storey2->Elevation(); + } + } return element1.id() < element2.id(); } From 5c497c8f6cbeb89baa713723f7d9398926f84a1d Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 16 May 2017 15:01:55 +0200 Subject: [PATCH 32/36] Fix : Handle the case where the first representation element has 0 parent --- src/ifcconvert/ColladaSerializer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index ae0200b698..413479140d 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -594,6 +594,10 @@ void ColladaSerializer::ColladaExporter::endDocument() { { unsigned parentsNumber = it->parents.size(); bool finished = false; + + // If we have no parent in the stack and the object has no parent, nothing to do : skip the loop + if (parentsNumber == 0 && serializer->parentStackId.size() == 0) { finished = true; } + while (!finished) { // If we need to add a parent From e02bbefa68e73415c735cc73feebb1686e1c2bb9 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 16 May 2017 15:20:30 +0200 Subject: [PATCH 33/36] Clean : Removed debug logs --- src/ifcconvert/ColladaSerializer.cpp | 1 - src/ifcconvert/ColladaSerializer.h | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 413479140d..45c7be7723 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -589,7 +589,6 @@ void ColladaSerializer::ColladaExporter::endDocument() { for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){ const std::string object_name = it->unique_id; - // TODO : handle the case where a representation object has no parent (Can this really happen ?) if (use_hierarchy) { unsigned parentsNumber = it->parents.size(); diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index df86842f28..82b693120c 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -136,19 +136,6 @@ private: friend bool operator < (const DeferredObject & def_obj1, const DeferredObject & def_obj2) { - /* - std::cout << "*************** COMPARE ***************\n"; - std::cout << "range 1 : " << def_obj1.unique_id << "\n"; - for (unsigned i = 0; i < def_obj1.parents.size(); i++) - { - std::cout << "=== " << def_obj1.parents.at(i)->name() << " | " << def_obj1.parents.at(i)->id() << " ===\n"; - } - std::cout << "range 2 : " << def_obj2.unique_id << "\n"; - for (unsigned i = 0; i < def_obj2.parents.size(); i++) - { - std::cout << "=== " << def_obj2.parents.at(i)->name() << " | " << def_obj2.parents.at(i)->id() << " ===\n"; - } - */ unsigned size = (def_obj1.parents.size() < def_obj2.parents.size() ? def_obj1.parents.size() : def_obj2.parents.size()); int cpt = 0; From be39f3002970210aaf6f3e6c2e9047695db2b44c Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 16 May 2017 15:54:26 +0200 Subject: [PATCH 34/36] Fix : fix build error --- src/ifcconvert/ColladaSerializer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 82b693120c..9d19da0bfc 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -86,7 +86,7 @@ private: const std::string scene_id; bool scene_opened; std::stack parentNodes; - std::stack> matrixStack; + std::stack > matrixStack; public: ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryVisualScenes(&stream) From 4680298beea833e7d2ce90a71b29d81364157b80 Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Tue, 16 May 2017 16:34:50 +0200 Subject: [PATCH 35/36] Clean : Remove debug logs --- src/ifcgeom/IfcGeomIterator.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index 2c681bcc2d..caa0e922a2 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -630,47 +630,33 @@ namespace IfcGeom { } const Element

* getObject(int id) { - //std::cout << "1"; gp_Trsf trsf; int parent_id = -1; std::string instance_type, product_name, product_guid; IfcSchema::IfcProduct* ifc_product = 0; - //std::cout << "2"; try { const IfcUtil::IfcBaseClass* ifc_entity = ifc_file->entityById(id); instance_type = IfcSchema::Type::ToString(ifc_entity->type()); if ( ifc_entity->is(IfcSchema::Type::IfcProduct) ) { ifc_product = (IfcSchema::IfcProduct*)ifc_entity; - //std::cout << "3"; product_guid = ifc_product->GlobalId(); product_name = ifc_product->hasName() ? ifc_product->Name() : ""; parent_id = -1; try { - //std::cout << "4"; IfcSchema::IfcObjectDefinition* parent_object = kernel.get_decomposing_entity(ifc_product); if (parent_object) { parent_id = parent_object->entity->id(); } } catch (...) {} - //std::cout << "5"; try { kernel.convert(ifc_product->ObjectPlacement(), trsf); } catch (...) {} } - //std::cout << "6"; } catch(...) {} - //std::cout << "7"; ElementSettings element_settings(settings, unit_magnitude, instance_type); - //std::cout << "8"; - //std::cout << "id " << id << "\n"; - //std::cout << "parent_id " << parent_id << "\n"; - //std::cout << "product_name " << product_name << "\n"; - //std::cout << "instance_type " << instance_type << "\n"; - //std::cout << "product_guid " << product_guid << "\n"; Element

* ifc_object = new Element

(element_settings, id, parent_id, product_name, instance_type, product_guid, "", trsf, ifc_product); - //std::cout << "9\n"; return ifc_object; } From 834e05a01ccbb6618ebdc8769d0a6e2f134082de Mon Sep 17 00:00:00 2001 From: Balleux Benjamin Date: Thu, 18 May 2017 11:26:19 +0200 Subject: [PATCH 36/36] Feature : For each parent element, include the type in the name if --use-element-types if used --- src/ifcconvert/ColladaSerializer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 45c7be7723..01c337c60f 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -313,8 +313,13 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: // Chose a name of the parent object std::string name = ""; - if (parent.name() == "") { name = parent.type(); } - else { name = parent.name(); } + if (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES)) { name = parent.type() + " " + parent.name(); } + else + { + if (parent.name() == "") { name = "unnamed"; } + else { name = parent.name(); } + } + COLLADASW::Node *current_node; current_node = new COLLADASW::Node(mSW);