From 6e525662c3d9b18a360209585641d2caaa1e4c9f Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 20 Dec 2017 12:41:39 +0100 Subject: [PATCH] Disable XML serializer for the time being --- src/ifcconvert/IfcConvert.cpp | 21 -- src/ifcconvert/XmlSerializer.cpp | 456 ------------------------------- src/ifcconvert/XmlSerializer.h | 41 --- 3 files changed, 518 deletions(-) delete mode 100644 src/ifcconvert/XmlSerializer.cpp delete mode 100644 src/ifcconvert/XmlSerializer.h diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index e0d962d889..d0f9e46f6a 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -30,7 +30,6 @@ #include "../ifcconvert/IgesSerializer.h" #include "../ifcconvert/StepSerializer.h" #include "../ifcconvert/WavefrontObjSerializer.h" -#include "../ifcconvert/XmlSerializer.h" #include "../ifcconvert/SvgSerializer.h" #include "../iterator/IfcGeomIterator.h" @@ -70,7 +69,6 @@ void print_usage(bool suggest_help = true) #endif << " .stp STEP Standard for the Exchange of Product Data\n" << " .igs IGES Initial Graphics Exchange Specification\n" - << " .xml XML Property definitions and decomposition tree\n" << " .svg SVG Scalable Vector Graphics (2D floor plan)\n" << "\n" << "If no output filename given, ." + DEFAULT_EXTENSION + " will be used as the output file.\n"; @@ -444,25 +442,6 @@ int main(int argc, char** argv) IfcParse::IfcFile ifc_file; - if (output_extension == ".xml") { - int exit_code = EXIT_FAILURE; - try { - if (init_input_file(input_filename, ifc_file, no_progress, mmap)) { - XmlSerializer s(output_temp_filename); - s.setFile(&ifc_file); - Logger::Status("Writing XML output..."); - s.finalize(); - Logger::Status("Done!"); - rename_file(output_temp_filename, output_filename); - exit_code = EXIT_SUCCESS; - } - } catch (const std::exception& e) { - Logger::Error(e); - } - write_log(); - return exit_code; - } - /* if (!filter_filename.empty()) { size_t num_filters = read_filters_from_file(filter_filename, include_filter, include_traverse_filter, exclude_filter, exclude_traverse_filter); diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp deleted file mode 100644 index 20ff2f1320..0000000000 --- a/src/ifcconvert/XmlSerializer.cpp +++ /dev/null @@ -1,456 +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 . * -* * -********************************************************************************/ - -#include - -#include -#include -#include - -#include "XmlSerializer.h" - -#include - -#include "../ifcparse/IfcSIPrefix.h" -// #include "../ifcgeom/IfcGeom.h" - -using boost::property_tree::ptree; - -// using namespace IfcSchema; - -namespace { - -std::map argument_name_map; - -// Format an IFC attribute and maybe returns as string. Only literal scalar -// values are converted. Things like entity instances and lists are omitted. -boost::optional format_attribute(const Argument* argument, IfcUtil::ArgumentType argument_type, const std::string& argument_name) { - boost::optional value; - - // Hard-code lat-lon as it represents an array - // of integers best emitted as a single decimal - if (argument_name == "IfcSite.RefLatitude" || - argument_name == "IfcSite.RefLongitude") - { - std::vector angle = *argument; - double deg; - if (angle.size() >= 3) { - deg = angle[0] + angle[1] / 60. + angle[2] / 3600.; - int prec = 8; - if (angle.size() == 4) { - deg += angle[3] / (1000000. * 3600.); - prec = 14; - } - std::stringstream stream; - stream << std::setprecision(prec) << deg; - value = stream.str(); - } - return value; - } - - switch(argument_type) { - case IfcUtil::Argument_BOOL: { - const bool b = *argument; - value = b ? "true" : "false"; - break; } - case IfcUtil::Argument_DOUBLE: { - const double d = *argument; - std::stringstream stream; - stream << d; - value = stream.str(); - break; } - case IfcUtil::Argument_STRING: - case IfcUtil::Argument_ENUMERATION: { - value = static_cast(*argument); - break; } - case IfcUtil::Argument_INT: { - const int v = *argument; - std::stringstream stream; - stream << v; - value = stream.str(); - break; } - case IfcUtil::Argument_ENTITY_INSTANCE: { - IfcUtil::IfcBaseClass* e = *argument; - if (Type::IsSimple(e->declaration().type())) { - IfcUtil::IfcBaseType* f = (IfcUtil::IfcBaseType*) e; - value = format_attribute(f->data().getArgument(0), f->data().getArgument(0)->type(), argument_name); - } else if (e->declaration().is(IfcSchema::Type::IfcSIUnit) || e->declaration().is(IfcSchema::Type::IfcConversionBasedUnit)) { - // Some string concatenation to have a unit name as a XML attribute. - - std::string unit_name; - - if (e->declaration().is(IfcSchema::Type::IfcSIUnit)) { - IfcSchema::IfcSIUnit* unit = (IfcSchema::IfcSIUnit*) e; - unit_name = IfcSchema::IfcSIUnitName::ToString(unit->Name()); - if (unit->hasPrefix()) { - unit_name = IfcSchema::IfcSIPrefix::ToString(unit->Prefix()) + unit_name; - } - } else { - IfcSchema::IfcConversionBasedUnit* unit = (IfcSchema::IfcConversionBasedUnit*) e; - unit_name = unit->Name(); - } - - value = unit_name; - } else if (e->declaration().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: - break; - } - return value; -} - -// Appends to a node with possibly existing attributes -ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& child, ptree& tree, bool as_link = false) { - const unsigned n = instance->data().getArgumentCount(); - for (unsigned i = 0; i < n; ++i) { - const Argument* argument = instance->data().getArgument(i); - if (argument->isNull()) continue; - - std::string argument_name = instance->declaration().all_attributes()[i]->name(); - std::map::const_iterator argument_name_it; - argument_name_it = argument_name_map.find(argument_name); - if (argument_name_it != argument_name_map.end()) { - argument_name = argument_name_it->second; - } - const IfcUtil::ArgumentType argument_type = instance->data().getArgument(i)->type(); - - const std::string qualified_name = IfcSchema::Type::ToString(instance->declaration().type()) + "." + argument_name; - boost::optional value; - try { - value = format_attribute(argument, argument_type, qualified_name); - } catch (const std::exception& e) { - Logger::Error(e); - } - - if (value) { - if (as_link) { - if (argument_name == "id") { - child.put(".xlink:href", std::string("#") + *value); - } - } else { - std::stringstream stream; - stream << "." << argument_name; - child.put(stream.str(), *value); - } - } - } - return tree.add_child(Type::ToString(instance->declaration().type()), child); -} - -// Formats an entity instances as a ptree node, and insert into the DOM. Recurses -// over the entity attributes and writes them as xml attributes of the node. -ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& tree, bool as_link = false) { - ptree child; - return format_entity_instance(instance, child, tree, as_link); -} - -std::string qualify_unrooted_instance(IfcUtil::IfcBaseClass* inst) { - return IfcSchema::Type::ToString(inst->declaration().type()) + "_" + boost::lexical_cast(inst->data().id()); -} - -// A function to be called recursively. Template specialization is used -// to descend into decomposition, containment and property relationships. -template -ptree& descend(A* instance, ptree& tree) { - if (instance->declaration().is(IfcSchema::Type::IfcObjectDefinition)) { - return descend(instance->template as(), tree); - } else { - return format_entity_instance(instance, tree); - } -} - -// Returns related entity instances using IFC's objectified relationship -// model. The second and third argument require a member function pointer. -template -typename V::list::ptr get_related(T* t, F f, G g) { - typename U::list::ptr li = (*t.*f)()->template as(); - typename V::list::ptr acc(new typename V::list); - for (typename U::list::it it = li->begin(); it != li->end(); ++it) { - U* u = *it; - acc->push((*u.*g)()->template as()); - } - return acc; -} - -// Descends into the tree by recursing into IfcRelContainedInSpatialStructure, -// IfcRelDecomposes, IfcRelDefinesByType, IfcRelDefinesByProperties relations. -template <> -ptree& descend(IfcObjectDefinition* product, ptree& tree) { - ptree& child = format_entity_instance(product, tree); - - if (product->declaration().is(Type::IfcSpatialStructureElement)) { - IfcSpatialStructureElement* structure = (IfcSpatialStructureElement*) product; - - IfcObjectDefinition::list::ptr elements = get_related - - (structure, &IfcSpatialStructureElement::ContainsElements, &IfcRelContainedInSpatialStructure::RelatedElements); - - for (IfcObjectDefinition::list::it it = elements->begin(); it != elements->end(); ++it) { - descend(*it, child); - } - } - - if (product->declaration().is(Type::IfcElement)) { - IfcElement* element = static_cast(product); - IfcOpeningElement::list::ptr openings = get_related( - element, &IfcElement::HasOpenings, &IfcRelVoidsElement::RelatedOpeningElement); - - for (IfcOpeningElement::list::it it = openings->begin(); it != openings->end(); ++it) { - descend(*it, child); - } - } - -#ifndef USE_IFC4 - IfcObjectDefinition::list::ptr structures = get_related - - (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; - descend(ob, child); - } - - if (product->declaration().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->declaration().is(Type::IfcPropertySet)) { - format_entity_instance(pset, child, true); - } - } - -#ifdef USE_IFC4 - IfcTypeObject::list::ptr types = get_related - - (object, &IfcObject::IsTypedBy, &IfcRelDefinesByType::RelatingType); -#else - IfcTypeObject::list::ptr types = get_related - - (object, &IfcObject::IsDefinedBy, &IfcRelDefinesByType::RelatingType); -#endif - - for (IfcTypeObject::list::it it = types->begin(); it != types->end(); ++it) { - IfcTypeObject* type = *it; - format_entity_instance(type, child, true); - } - } - - if (product->declaration().is(Type::IfcProduct)) { - std::map layers = IfcGeom::Kernel::get_layers(product->as()); - for (std::map::const_iterator it = layers.begin(); it != layers.end(); ++it) { - // IfcPresentationLayerAssignments don't have GUIDs (only optional Identifier) so use name as the ID. - // Note that the IfcPresentationLayerAssignment passed here doesn't really matter as as_link is true - // for the format_entity_instance() call. - ptree node; - node.put(".xlink:href", "#" + it->first); - format_entity_instance(it->second, node, child, true); - } - - IfcRelAssociates::list::ptr associations = product->HasAssociations(); - for (IfcRelAssociates::list::it it = associations->begin(); it != associations->end(); ++it) { - if ((*it)->as()) { - IfcMaterialSelect* mat = (*it)->as()->RelatingMaterial(); - ptree node; - node.put(".xlink:href", "#" + qualify_unrooted_instance(mat)); - format_entity_instance((IfcUtil::IfcBaseEntity*) mat, node, child, true); - } - } - } - - return child; -} - -// Format IfcProperty instances and insert into the DOM. IfcComplexProperties are flattened out. -void format_properties(IfcProperty::list::ptr properties, ptree& node) { - for (IfcProperty::list::it it = properties->begin(); it != properties->end(); ++it) { - IfcProperty* p = *it; - if (p->declaration().is(Type::IfcComplexProperty)) { - IfcComplexProperty* complex = (IfcComplexProperty*) p; - format_properties(complex->HasProperties(), node); - } else { - format_entity_instance(p, node); - } - } -} - -} // ~unnamed namespace - -void XmlSerializer::finalize() { - argument_name_map.insert(std::make_pair("GlobalId", "id")); - - IfcProject::list::ptr projects = file->entitiesByType(); - if (projects->size() != 1) { - Logger::Message(Logger::LOG_ERROR, "Expected a single IfcProject"); - return; - } - IfcProject* project = *projects->begin(); - - ptree root, header, units, decomposition, properties, types, layers, materials; - - // Write the SPF header as XML nodes. - foreach(const std::string& s, file->header().file_description().description()) { - header.add_child("file_description.description", ptree(s)); - } - foreach(const std::string& s, file->header().file_name().author()) { - header.add_child("file_name.author", ptree(s)); - } - foreach(const std::string& s, file->header().file_name().organization()) { - header.add_child("file_name.organization", ptree(s)); - } - foreach(const std::string& s, file->header().file_schema().schema_identifiers()) { - header.add_child("file_schema.schema_identifiers", ptree(s)); - } - header.put("file_description.implementation_level", file->header().file_description().implementation_level()); - header.put("file_name.name", file->header().file_name().name()); - header.put("file_name.time_stamp", file->header().file_name().time_stamp()); - header.put("file_name.preprocessor_version", file->header().file_name().preprocessor_version()); - header.put("file_name.originating_system", file->header().file_name().originating_system()); - header.put("file_name.authorization", file->header().file_name().authorization()); - - // Descend into the decomposition structure of the IFC file. - descend(project, decomposition); - - // Write all property sets and values as XML nodes. - IfcPropertySet::list::ptr psets = file->entitiesByType(); - for (IfcPropertySet::list::it it = psets->begin(); it != psets->end(); ++it) { - IfcPropertySet* pset = *it; - ptree& node = format_entity_instance(pset, properties); - 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); - - if (type_object->hasHasPropertySets()) { - 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->declaration().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) { - if ((*it)->declaration().is(IfcSchema::Type::IfcNamedUnit)) { - IfcSchema::IfcNamedUnit* named_unit = (*it)->as(); - ptree& node = format_entity_instance(named_unit, units); - node.put(".SI_equivalent", IfcParse::get_SI_equivalent(named_unit)); - } else if ((*it)->declaration().is(IfcSchema::Type::IfcMonetaryUnit)) { - format_entity_instance((*it)->as(), units); - } - } - - // Layer assignments. IfcPresentationLayerAssignments don't have GUIDs (only optional Identifier) - // so use names as the IDs and only insert those with unique names. In case of possible duplicate names/IDs - // the first IfcPresentationLayerAssignment occurence takes precedence. - std::set layer_names; - IfcPresentationLayerAssignment::list::ptr layer_assignments = file->entitiesByType(); - for (IfcPresentationLayerAssignment::list::it it = layer_assignments->begin(); it != layer_assignments->end(); ++it) { - const std::string& name = (*it)->Name(); - if (layer_names.find(name) == layer_names.end()) { - layer_names.insert(name); - ptree node; - node.put(".id", name); - format_entity_instance(*it, node, layers); - } - } - - IfcRelAssociatesMaterial::list::ptr materal_associations = file->entitiesByType(); - std::set emitted_materials; - for (IfcRelAssociatesMaterial::list::it it = materal_associations->begin(); it != materal_associations->end(); ++it) { - IfcMaterialSelect* mat = (**it).RelatingMaterial(); - if (emitted_materials.find(mat) == emitted_materials.end()) { - emitted_materials.insert(mat); - ptree node; - node.put(".id", qualify_unrooted_instance(mat)); - if (mat->as()) { - IfcMaterialLayerSet* layerset = mat->as()->ForLayerSet(); - if (layerset->hasLayerSetName()) { - node.put(".LayerSetName", layerset->LayerSetName()); - } - IfcMaterialLayer::list::ptr ls = layerset->MaterialLayers(); - for (IfcMaterialLayer::list::it jt = ls->begin(); jt != ls->end(); ++jt) { - ptree subnode; - if ((*jt)->hasMaterial()) { - subnode.put(".Name", (*jt)->Material()->Name()); - } - format_entity_instance(*jt, subnode, node); - } - } else if (mat->as()) { - IfcMaterial::list::ptr mats = mat->as()->Materials(); - for (IfcMaterial::list::it jt = mats->begin(); jt != mats->end(); ++jt) { - ptree subnode; - format_entity_instance(*jt, subnode, node); - } - } - format_entity_instance((IfcUtil::IfcBaseEntity*) mat, node, materials); - } - } - - 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.layers", layers); - root.add_child("ifc.materials", materials); - root.add_child("ifc.decomposition", decomposition); - - root.put("ifc..xmlns:xlink", "http://www.w3.org/1999/xlink"); - -#if BOOST_VERSION >= 105600 - boost::property_tree::xml_writer_settings settings = boost::property_tree::xml_writer_make_settings('\t', 1); -#else - boost::property_tree::xml_writer_settings settings('\t', 1); -#endif - boost::property_tree::write_xml(xml_filename, root, std::locale(), settings); -} diff --git a/src/ifcconvert/XmlSerializer.h b/src/ifcconvert/XmlSerializer.h deleted file mode 100644 index bd8b856f8f..0000000000 --- a/src/ifcconvert/XmlSerializer.h +++ /dev/null @@ -1,41 +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 XMLSERIALIZER_H -#define XMLSERIALIZER_H - -#include "../ifcconvert/Serializer.h" - -class XmlSerializer : public Serializer { -private: - IfcParse::IfcFile* file; - std::string xml_filename; -public: - XmlSerializer(const std::string& xml_filename) - : Serializer() - , xml_filename(xml_filename) - {} - - bool ready() { return true; } - void writeHeader() {} - void finalize(); - void setFile(IfcParse::IfcFile* f) { file = f; } -}; - -#endif \ No newline at end of file