From e0cde05e26f576afa78de95bff9df63cf3b0092d Mon Sep 17 00:00:00 2001 From: Stinkfist0 Date: Thu, 7 Jun 2018 14:34:25 +0300 Subject: [PATCH] Unify GeometrySerializers' object ID logic. Fixes #397. --- src/ifcconvert/ColladaSerializer.cpp | 76 ++++++++--------------- src/ifcconvert/ColladaSerializer.h | 6 +- src/ifcconvert/GeometrySerializer.h | 8 +++ src/ifcconvert/SvgSerializer.cpp | 4 +- src/ifcconvert/WavefrontObjSerializer.cpp | 5 +- 5 files changed, 41 insertions(+), 58 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 827ee924c4..99004d5e50 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -263,20 +263,13 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: { 0, 0, 0, 1 } }; - // Chose a name of the parent object - std::string name = ""; - if (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES)) { - name = parent.type() + " " + parent.name(); - } else { - name = parent.unique_id(); - } + std::string name = serializer->object_id(&parent); collada_id(name); - const std::string& id = name; - COLLADASW::Node *current_node; current_node = new COLLADASW::Node(mSW); - current_node->setNodeId(id); + current_node->setNodeId(name); + /// @todo redundant information using ID as both ID and Name, maybe omit Name or allow specifying what would be used as the name current_node->setNodeName(name); current_node->setType(COLLADASW::Node::NODE); current_node->start(); @@ -391,19 +384,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme { const IfcGeom::Representation::Triangulation& mesh = o->geometry(); - std::string slabSuffix = ""; - if (o->type() == "IfcSlab") - { - slabSuffix = differentiateSlabTypes(o); - } - - 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())); + std::string name = serializer->object_id(o); collada_id(name); std::string representation_id = "representation-" + o->geometry().id(); @@ -430,33 +411,28 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme deferreds.push_back(deferred); } -std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement* o) { - IfcSlab* slab = (IfcSlab*)o->product(); - std::string result; - switch (slab->PredefinedType()) - { - case (IfcSlabTypeEnum::IfcSlabType_FLOOR): - result = "_Floor"; - break; - case (IfcSlabTypeEnum::IfcSlabType_ROOF): - result = "_Roof"; - break; - case (IfcSlabTypeEnum::IfcSlabType_LANDING): - result = "_Landing"; - break; - case (IfcSlabTypeEnum::IfcSlabType_BASESLAB): - result = "_BaseSlab"; - break; - case (IfcSlabTypeEnum::IfcSlabType_NOTDEFINED): - result = "_NotDefined"; - break; - default: - if (slab->hasObjectType()) { result = "_" + slab->ObjectType(); } - else { result = "_Unknown"; } - break; - } - collada_id(result); - return result; +std::string ColladaSerializer::differentiateSlabTypes(const IfcSchema::IfcSlab* slab) +{ + switch (slab->PredefinedType()) + { + case IfcSlabTypeEnum::IfcSlabType_FLOOR: return "_Floor"; + case IfcSlabTypeEnum::IfcSlabType_ROOF: return "_Roof"; + case IfcSlabTypeEnum::IfcSlabType_LANDING: return "_Landing"; + case IfcSlabTypeEnum::IfcSlabType_BASESLAB: return "_BaseSlab"; + case IfcSlabTypeEnum::IfcSlabType_NOTDEFINED: return "_NotDefined"; + default: return slab->hasObjectType() ? "_" + slab->ObjectType() : "_Unknown"; + } +} + +std::string ColladaSerializer::object_id(const IfcGeom::Element* o) /*override*/ +{ + if (settings_.get(SerializerSettings::USE_ELEMENT_TYPES)) { + const std::string slabSuffix = (o->product() && o->product()->is(IfcSchema::IfcSlab::Class())) + ? differentiateSlabTypes(o->product()->as()) + : ""; + return o->type() + slabSuffix; + } + return GeometrySerializer::object_id(o); } void ColladaSerializer::ColladaExporter::endDocument() { diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 3acf29ee8b..a0ca6325c2 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -189,7 +189,6 @@ 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, @@ -235,6 +234,11 @@ public: unit_magnitude = magnitude; } void setFile(IfcParse::IfcFile*) {} + + std::string object_id(const IfcGeom::Element* o) /*override*/; + +private: + static std::string differentiateSlabTypes(const IfcSchema::IfcSlab *slab); }; #endif diff --git a/src/ifcconvert/GeometrySerializer.h b/src/ifcconvert/GeometrySerializer.h index 8543c468cb..98e1f6404c 100644 --- a/src/ifcconvert/GeometrySerializer.h +++ b/src/ifcconvert/GeometrySerializer.h @@ -82,6 +82,14 @@ public: const SerializerSettings& settings() const { return settings_; } SerializerSettings& settings() { return settings_; } + /// Returns ID for the object depending on the used setting. + virtual std::string object_id(const IfcGeom::Element* o) + { + if (settings_.get(SerializerSettings::USE_ELEMENT_GUIDS)) return o->guid(); + if (settings_.get(SerializerSettings::USE_ELEMENT_NAMES)) return o->name(); + return o->unique_id(); + } + protected: SerializerSettings settings_; }; diff --git a/src/ifcconvert/SvgSerializer.cpp b/src/ifcconvert/SvgSerializer.cpp index 0a895ff29d..804851c402 100644 --- a/src/ifcconvert/SvgSerializer.cpp +++ b/src/ifcconvert/SvgSerializer.cpp @@ -466,9 +466,7 @@ std::string SvgSerializer::nameElement(const IfcGeom::Element* elem) { std::ostringstream oss; const std::string type = "product"; - const std::string name = (settings().get(SerializerSettings::USE_ELEMENT_GUIDS) - ? elem->guid() : (settings().get(SerializerSettings::USE_ELEMENT_NAMES) - ? elem->name() : elem->unique_id())); + const std::string name = object_id(elem); oss << "id=\"" << type << "-" << name<< "\""; return oss.str(); } diff --git a/src/ifcconvert/WavefrontObjSerializer.cpp b/src/ifcconvert/WavefrontObjSerializer.cpp index 26b8b39306..80f92c1574 100644 --- a/src/ifcconvert/WavefrontObjSerializer.cpp +++ b/src/ifcconvert/WavefrontObjSerializer.cpp @@ -73,10 +73,7 @@ void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style) void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o) { - const std::string name = (settings().get(SerializerSettings::USE_ELEMENT_GUIDS) - ? o->guid() : (settings().get(SerializerSettings::USE_ELEMENT_NAMES) - ? o->name() : o->unique_id())); - obj_stream << "g " << name << "\n"; + obj_stream << "g " << object_id(o) << "\n"; obj_stream << "s 1" << "\n"; const IfcGeom::Representation::Triangulation& mesh = o->geometry();