diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp
index bd9dadb7d6..c276a2e8e6 100644
--- a/src/ifcconvert/IfcConvert.cpp
+++ b/src/ifcconvert/IfcConvert.cpp
@@ -30,6 +30,7 @@
#include "../serializers/IgesSerializer.h"
#include "../serializers/StepSerializer.h"
#include "../serializers/WavefrontObjSerializer.h"
+#include "../serializers/XmlSerializer.h"
#include "../serializers/SvgSerializer.h"
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
@@ -69,6 +70,7 @@ 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";
@@ -442,6 +444,24 @@ int main(int argc, char** argv)
IfcParse::IfcFile* ifc_file = 0;
+ if (output_extension == ".xml") {
+ int exit_code = EXIT_FAILURE;
+ try {
+ if (init_input_file(input_filename, ifc_file, no_progress, mmap)) {
+ XmlSerializer s(ifc_file, output_temp_filename);
+ 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);
@@ -922,4 +942,4 @@ std::vector setup_filters(const std::vector& fil
return filter_funcs;
}
-*/
\ No newline at end of file
+*/
diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h
index 8e61220064..52c8a185a0 100644
--- a/src/ifcgeom/IfcGeom.h
+++ b/src/ifcgeom/IfcGeom.h
@@ -46,6 +46,7 @@ inline static bool ALMOST_THE_SAME(const T& a, const T& b, double tolerance=ALMO
#include
#include
+#include "../ifcparse/macros.h"
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcBaseClass.h"
@@ -75,14 +76,8 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
#endif
-#define MAKE_TYPE_NAME__(a, b) a ## b
-#define MAKE_TYPE_NAME_(a, b) MAKE_TYPE_NAME__(a, b)
-#define MAKE_TYPE_NAME(t) MAKE_TYPE_NAME_(t, IfcSchema)
-
-#define STRINGIFY_(x) #x
-#define STRINGIFY(x) STRINGIFY_(x)
-#define INCLUDE(x) STRINGIFY(../ifcparse/x.h)
-#include INCLUDE(IfcSchema)
+#define INCLUDE_PARENT_DIR(x) STRINGIFY(../ifcparse/x.h)
+#include INCLUDE_PARENT_DIR(IfcSchema)
namespace IfcGeom {
diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp
index bcff087646..1918c39b47 100644
--- a/src/ifcgeom/IfcGeomFunctions.cpp
+++ b/src/ifcgeom/IfcGeomFunctions.cpp
@@ -133,6 +133,7 @@
#include
+#include "../ifcparse/macros.h"
#include "../ifcparse/IfcSIPrefix.h"
#include "../ifcparse/IfcFile.h"
#include "../ifcgeom/IfcGeom.h"
@@ -145,11 +146,6 @@
#endif
#endif
-
-#define MAKE_INIT_FN__(a, b) init_ ## a ## b
-#define MAKE_INIT_FN_(a, b) MAKE_INIT_FN__(a, b)
-#define MAKE_INIT_FN(t) MAKE_INIT_FN_(t, IfcSchema)
-
namespace {
struct factory_t {
IfcGeom::Kernel* operator()(IfcParse::IfcFile* file) const {
diff --git a/src/ifcparse/macros.h b/src/ifcparse/macros.h
new file mode 100644
index 0000000000..8db482967b
--- /dev/null
+++ b/src/ifcparse/macros.h
@@ -0,0 +1,34 @@
+/********************************************************************************
+* *
+* 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 IFCOPENSHELL_MACROS_H
+#define IFCOPENSHELL_MACROS_H
+
+#define MAKE_TYPE_NAME__(a, b) a ## b
+#define MAKE_TYPE_NAME_(a, b) MAKE_TYPE_NAME__(a, b)
+#define MAKE_TYPE_NAME(t) MAKE_TYPE_NAME_(t, IfcSchema)
+
+#define STRINGIFY_(x) #x
+#define STRINGIFY(x) STRINGIFY_(x)
+
+#define MAKE_INIT_FN__(a, b) init_ ## a ## b
+#define MAKE_INIT_FN_(a, b) MAKE_INIT_FN__(a, b)
+#define MAKE_INIT_FN(t) MAKE_INIT_FN_(t, IfcSchema)
+
+#endif
\ No newline at end of file
diff --git a/src/serializers/XmlSerializer.cpp b/src/serializers/XmlSerializer.cpp
new file mode 100644
index 0000000000..5f42e05751
--- /dev/null
+++ b/src/serializers/XmlSerializer.cpp
@@ -0,0 +1,35 @@
+#include "XmlSerializer.h"
+
+extern void init_XmlSerializerIfc2x3(XmlSerializerFactory::Factory*);
+extern void init_XmlSerializerIfc4(XmlSerializerFactory::Factory*);
+
+XmlSerializerFactory::Factory::Factory() {
+ init_XmlSerializerIfc2x3(this);
+ init_XmlSerializerIfc4(this);
+}
+
+void XmlSerializerFactory::Factory::bind(const std::string& schema_name, fn f) {
+ const std::string schema_name_lower = boost::to_lower_copy(schema_name);
+ this->insert(std::make_pair(schema_name_lower, f));
+}
+
+XmlSerializer* XmlSerializerFactory::Factory::construct(const std::string& schema_name, IfcParse::IfcFile* file, std::string xml_filename) {
+ const std::string schema_name_lower = boost::to_lower_copy(schema_name);
+ typename std::map::const_iterator it;
+ it = this->find(schema_name_lower);
+ if (it == this->end()) {
+ throw IfcParse::IfcException("No XML serializer registered for " + schema_name);
+ }
+ return it->second(file, xml_filename);
+}
+
+XmlSerializer::XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename) {
+ if (file != nullptr) {
+ implementation_ = XmlSerializerFactory::implementations().construct(file->schema()->name(), file, xml_filename);
+ }
+}
+
+XmlSerializerFactory::Factory& XmlSerializerFactory::implementations() {
+ static XmlSerializerFactory::Factory impl;
+ return impl;
+}
diff --git a/src/serializers/XmlSerializer.h b/src/serializers/XmlSerializer.h
index 9c45a1a2c0..fbf128491b 100644
--- a/src/serializers/XmlSerializer.h
+++ b/src/serializers/XmlSerializer.h
@@ -1,29 +1,40 @@
#define SCHEMA_METHOD
+#include "../serializers/Serializer.h"
#include "../ifcparse/IfcFile.h"
#include
#include