From ac1a8f6d167000c8222f69a130be0afdc53bfc4d Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Thu, 1 Sep 2016 11:59:43 +0200 Subject: [PATCH] Add types and placement to XML output --- src/ifcconvert/XmlSerializer.cpp | 123 ++++++++++++++++++------------- 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp index 3936fc9d22..eaef85f82e 100644 --- a/src/ifcconvert/XmlSerializer.cpp +++ b/src/ifcconvert/XmlSerializer.cpp @@ -28,6 +28,7 @@ #include #include "../ifcparse/IfcSIPrefix.h" +#include "../ifcgeom/IfcGeom.h" using boost::property_tree::ptree; using namespace IfcSchema; @@ -81,6 +82,21 @@ boost::optional format_attribute(const Argument* argument, IfcUtil: } value = unit_name; + } else if (e->is(IfcSchema::Type::IfcLocalPlacement)) { + 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) { + for (int j = 1; j < 4; ++j) { + const double trsf_value = trsf.Value(j, i); + stream << trsf_value << " "; + } + stream << ((i == 4) ? "1" : "0 "); + } + value = stream.str(); + } } break; } default: @@ -129,8 +145,12 @@ ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& tree, boo // A function to be called recursively. Template specialization is used // to descend into decomposition, containment and property relationships. template -void descend(A* instance, ptree& tree) { - format_entity_instance(instance, tree); +ptree& descend(A* instance, ptree& tree) { + if (instance->is(IfcSchema::Type::IfcObjectDefinition)) { + return descend(instance->as(), tree); + } else { + return format_entity_instance(instance, tree); + } } // Returns related entity instances using IFC's objectified relationship @@ -147,19 +167,19 @@ typename V::list::ptr get_related(T* t, F f, G g) { } // Descends into the tree by recursing into IfcRelContainedInSpatialStructure, -// IfcRelDecomposes and IfcRelDefinesByProperties relations. +// IfcRelDecomposes, IfcRelDefinesByType, IfcRelDefinesByProperties relations. template <> -void descend(IfcProduct* product, ptree& tree) { +ptree& descend(IfcObjectDefinition* product, ptree& tree) { ptree& child = format_entity_instance(product, tree); if (product->is(Type::IfcSpatialStructureElement)) { IfcSpatialStructureElement* structure = (IfcSpatialStructureElement*) product; - IfcProduct::list::ptr elements = get_related - + IfcObjectDefinition::list::ptr elements = get_related + (structure, &IfcSpatialStructureElement::ContainsElements, &IfcRelContainedInSpatialStructure::RelatedElements); - for (IfcProduct::list::it it = elements->begin(); it != elements->end(); ++it) { + for (IfcObjectDefinition::list::it it = elements->begin(); it != elements->end(); ++it) { descend(*it, child); } } @@ -176,58 +196,44 @@ void descend(IfcProduct* product, ptree& tree) { #ifndef USE_IFC4 IfcObjectDefinition::list::ptr structures = get_related - - (product, &IfcProduct::IsDecomposedBy, &IfcRelDecomposes::RelatedObjects); + + (product, &IfcObjectDefinition::IsDecomposedBy, &IfcRelDecomposes::RelatedObjects); #else IfcObjectDefinition::list::ptr structures = get_related - + (product, &IfcProduct::IsDecomposedBy, &IfcRelAggregates::RelatedObjects); #endif for (IfcObjectDefinition::list::it it = structures->begin(); it != structures->end(); ++it) { IfcObjectDefinition* ob = *it; - if (ob->is(Type::IfcSpatialStructureElement)) { - descend((IfcProduct*)ob, child); - } else { - descend(ob, child); + descend(ob, child); + } + + if (product->is(IfcSchema::Type::IfcObject)) { + IfcSchema::IfcObject* object = product->as(); + + IfcPropertySetDefinition::list::ptr property_sets = get_related + + (object, &IfcObject::IsDefinedBy, &IfcRelDefinesByProperties::RelatingPropertyDefinition); + + for (IfcPropertySetDefinition::list::it it = property_sets->begin(); it != property_sets->end(); ++it) { + IfcPropertySetDefinition* pset = *it; + if (pset->is(Type::IfcPropertySet)) { + format_entity_instance(pset, child, true); + } + } + + IfcTypeObject::list::ptr types = get_related + + (object, &IfcObject::IsDefinedBy, &IfcRelDefinesByType::RelatingType); + + for (IfcTypeObject::list::it it = types->begin(); it != types->end(); ++it) { + IfcTypeObject* type = *it; + format_entity_instance(type, child, true); } } - IfcPropertySetDefinition::list::ptr property_sets = get_related - - (product, &IfcProduct::IsDefinedBy, &IfcRelDefinesByProperties::RelatingPropertyDefinition); - - for (IfcPropertySetDefinition::list::it it = property_sets->begin(); it != property_sets->end(); ++it) { - IfcPropertySetDefinition* pset = *it; - if (pset->is(Type::IfcPropertySet)) { - format_entity_instance(pset, child, true); - } - } -} - -// Descends into the tree by recursing into IfcRelDecomposes relations. -template <> -void descend(IfcProject* project, ptree& tree) { - ptree& child = format_entity_instance(project, tree); - -#ifndef USE_IFC4 - IfcObjectDefinition::list::ptr structures = get_related - - (project, &IfcProject::IsDecomposedBy, &IfcRelDecomposes::RelatedObjects); -#else - IfcObjectDefinition::list::ptr structures = get_related - - (project, &IfcProduct::IsDecomposedBy, &IfcRelAggregates::RelatedObjects); -#endif - - for (IfcObjectDefinition::list::it it = structures->begin(); it != structures->end(); ++it) { - IfcObjectDefinition* ob = *it; - if (ob->is(Type::IfcSpatialStructureElement)) { - descend((IfcProduct*)ob, child); - } else { - descend(ob, child); - } - } + return child; } // Format IfcProperty instances and insert into the DOM. IfcComplexProperties are flattened out. @@ -253,7 +259,7 @@ void XmlSerializer::finalize() { } IfcProject* project = *projects->begin(); - ptree root, header, units, decomposition, properties; + ptree root, header, units, decomposition, properties, types; // Write the SPF header as XML nodes. foreach(const std::string& s, file->header().file_description().description()) { @@ -286,6 +292,22 @@ void XmlSerializer::finalize() { format_properties(pset->HasProperties(), node); } + // Write all type objects as XML nodes. + IfcTypeObject::list::ptr type_objects = file->entitiesByType(); + for (IfcTypeObject::list::it it = type_objects->begin(); it != type_objects->end(); ++it) { + IfcTypeObject* type_object = *it; + ptree& node = descend(type_object, types); + // ptree& node = format_entity_instance(type_object, types); + + IfcPropertySetDefinition::list::ptr property_sets = type_object->HasPropertySets(); + for (IfcPropertySetDefinition::list::it jt = property_sets->begin(); jt != property_sets->end(); ++jt) { + IfcPropertySetDefinition* pset = *jt; + if (pset->is(Type::IfcPropertySet)) { + format_entity_instance(pset, node, true); + } + } + } + // Write all assigned units as XML nodes. IfcEntityList::ptr unit_assignments = project->UnitsInContext()->Units(); for (IfcEntityList::it it = unit_assignments->begin(); it != unit_assignments->end(); ++it) { @@ -301,6 +323,7 @@ void XmlSerializer::finalize() { root.add_child("ifc.header", header); root.add_child("ifc.units", units); root.add_child("ifc.properties", properties); + root.add_child("ifc.types", types); root.add_child("ifc.decomposition", decomposition); root.put("ifc..xmlns:xlink", "http://www.w3.org/1999/xlink");