mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 11:24:19 +00:00
Add an XML serializer (NB: Not ifcXML / 10303-28) that describes property set data, decomposition relations and SPF header fields
This commit is contained in:
@@ -160,11 +160,12 @@ TARGET_LINK_LIBRARIES(IfcGeom IfcParse)
|
||||
|
||||
LINK_DIRECTORIES (${LINK_DIRECTORIES} ${IfcOpenShell_BINARY_DIR} ${OCC_LIBRARY_DIR} ${OPENCOLLADA_LIBRARY_DIR} /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 ${ICU_LIBRARY_DIR} ${Boost_LIBRARY_DIRS})
|
||||
|
||||
ADD_EXECUTABLE(IfcConvert
|
||||
ADD_EXECUTABLE(IfcConvert
|
||||
../src/ifcconvert/ColladaSerializer.cpp
|
||||
../src/ifcconvert/IfcConvert.cpp
|
||||
../src/ifcconvert/OpenCascadeBasedSerializer.cpp
|
||||
../src/ifcconvert/WavefrontObjSerializer.cpp
|
||||
../src/ifcconvert/WavefrontObjSerializer.cpp
|
||||
../src/ifcconvert/XmlSerializer.cpp
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES (IfcConvert IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKSTEP TKSTEPBase TKSTEPAttr TKXSBase TKSTEP209 TKIGES TKOffset ${Boost_LIBRARIES} ${OPENCOLLADA_LIBRARIES})
|
||||
|
||||
@@ -157,6 +157,7 @@ public:
|
||||
unit_name = name;
|
||||
unit_magnitude = magnitude;
|
||||
}
|
||||
void setFile(IfcParse::IfcFile*) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,15 +20,14 @@
|
||||
#ifndef GEOMETRYSERIALIZER_H
|
||||
#define GEOMETRYSERIALIZER_H
|
||||
|
||||
#include "../ifcconvert/Serializer.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
class GeometrySerializer {
|
||||
class GeometrySerializer : public Serializer {
|
||||
public:
|
||||
virtual bool ready() = 0;
|
||||
virtual void writeHeader() = 0;
|
||||
virtual void finalize() = 0;
|
||||
virtual bool isTesselated() const = 0;
|
||||
virtual ~GeometrySerializer() {}
|
||||
|
||||
virtual bool isTesselated() const = 0;
|
||||
virtual void write(const IfcGeom::TriangulationElement<double>* o) = 0;
|
||||
virtual void write(const IfcGeom::BRepElement<double>* o) = 0;
|
||||
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "../ifcconvert/IgesSerializer.h"
|
||||
#include "../ifcconvert/StepSerializer.h"
|
||||
#include "../ifcconvert/WavefrontObjSerializer.h"
|
||||
#include "../ifcconvert/XmlSerializer.h"
|
||||
|
||||
void printVersion() {
|
||||
std::cerr << "IfcOpenShell IfcConvert " << IFCOPENSHELL_VERSION << std::endl;
|
||||
@@ -55,6 +56,7 @@ void printUsage(const boost::program_options::options_description& generic_optio
|
||||
#endif
|
||||
std::cerr << " .stp STEP Standard for the Exchange of Product Data" << std::endl
|
||||
<< " .igs IGES Initial Graphics Exchange Specification" << std::endl
|
||||
<< " .xml XML Property definitions and decomposition tree" << std::endl
|
||||
<< std::endl
|
||||
<< "Command line options" << std::endl << generic_options << std::endl
|
||||
<< "Advanced options" << std::endl << geom_options << std::endl;
|
||||
@@ -196,6 +198,31 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string output_extension = output_filename.substr(output_filename.size()-4);
|
||||
for (std::string::iterator c = output_extension.begin(); c != output_extension.end(); ++c) {
|
||||
*c = tolower(*c);
|
||||
}
|
||||
|
||||
Logger::SetOutput(&std::cout, &log_stream);
|
||||
Logger::Verbosity(verbose ? Logger::LOG_NOTICE : Logger::LOG_ERROR);
|
||||
|
||||
if (output_extension == ".xml") {
|
||||
int exit_code = 1;
|
||||
try {
|
||||
XmlSerializer s(output_filename);
|
||||
IfcParse::IfcFile f;
|
||||
if (!f.Init(input_filename)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unable to parse .ifc file");
|
||||
} else {
|
||||
s.setFile(&f);
|
||||
s.finalize();
|
||||
exit_code = 0;
|
||||
}
|
||||
} catch (...) {}
|
||||
write_log();
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
IfcGeom::IteratorSettings settings;
|
||||
|
||||
settings.set(IfcGeom::IteratorSettings::APPLY_DEFAULT_MATERIALS, true);
|
||||
@@ -207,14 +234,6 @@ int main(int argc, char** argv) {
|
||||
settings.set(IfcGeom::IteratorSettings::FORCE_CCW_FACE_ORIENTATION, force_ccw_face_orientation);
|
||||
settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, disable_opening_subtractions);
|
||||
|
||||
std::string output_extension = output_filename.substr(output_filename.size()-4);
|
||||
for (std::string::iterator c = output_extension.begin(); c != output_extension.end(); ++c) {
|
||||
*c = tolower(*c);
|
||||
}
|
||||
|
||||
Logger::SetOutput(&std::cout, &log_stream);
|
||||
Logger::Verbosity(verbose ? Logger::LOG_NOTICE : Logger::LOG_ERROR);
|
||||
|
||||
GeometrySerializer* serializer;
|
||||
if (output_extension == ".obj") {
|
||||
const std::string mtl_filename = output_filename.substr(0,output_filename.size()-3) + "mtl";
|
||||
@@ -288,9 +307,16 @@ int main(int argc, char** argv) {
|
||||
int old_progress = -1;
|
||||
Logger::Status("Creating geometry...");
|
||||
|
||||
// The functions IfcGeomObjects::Get() and IfcGeomObjects::Next() wrap an iterator of all geometrical entities in the Ifc file.
|
||||
// IfcGeomObjects::Get() returns an IfcGeom::TriangulationElement (see IfcGeomIterator.h for definition)
|
||||
// IfcGeomObjects::Next() is used to poll whether more geometrical entities are available
|
||||
// The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next()
|
||||
// wrap an iterator of all geometrical products in the Ifc file.
|
||||
// IfcGeom::Iterator::get() returns an IfcGeom::TriangulationElement or
|
||||
// -BRepElement pointer, based on current settings. (see IfcGeomIterator.h
|
||||
// for definition) IfcGeom::Iterator::next() is used to poll whether more
|
||||
// geometrical entities are available. None of these functions throw
|
||||
// exceptions, neither for parsing errors or geometrical errors. Upon
|
||||
// calling next() the entity to be returned has already been processed, a
|
||||
// true return value guarantees that a successfully processed product is
|
||||
// available.
|
||||
do {
|
||||
const IfcGeom::Element<double>* geom_object = context_iterator.get();
|
||||
|
||||
@@ -316,6 +342,8 @@ int main(int argc, char** argv) {
|
||||
time(&end);
|
||||
int dif = (int) difftime (end,start);
|
||||
printf ("\nConversion took %d seconds\n", dif );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void write_log() {
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
void write(const IfcGeom::TriangulationElement<double>* o) {}
|
||||
void write(const IfcGeom::BRepElement<double>* o);
|
||||
bool isTesselated() const { return false; }
|
||||
void setFile(IfcParse::IfcFile*) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef SERIALIZER_H
|
||||
#define SERIALIZER_H
|
||||
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
class Serializer {
|
||||
public:
|
||||
virtual ~Serializer() {}
|
||||
|
||||
virtual bool ready() = 0;
|
||||
virtual void writeHeader() = 0;
|
||||
virtual void finalize() = 0;
|
||||
virtual void setFile(IfcParse::IfcFile*) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
void finalize() {}
|
||||
bool isTesselated() const { return true; }
|
||||
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {}
|
||||
void setFile(IfcParse::IfcFile*) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,252 @@
|
||||
#include <map>
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "XmlSerializer.h"
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
using namespace IfcSchema;
|
||||
|
||||
static std::map<std::string, std::string> 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<std::string> format_attribute(const Argument* argument, IfcUtil::ArgumentType argument_type) {
|
||||
boost::optional<std::string> 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<std::string>(*argument);
|
||||
break; }
|
||||
case IfcUtil::Argument_INT: {
|
||||
const int v = *argument;
|
||||
std::stringstream stream;
|
||||
stream << v;
|
||||
value = stream.str();
|
||||
break; }
|
||||
case IfcUtil::Argument_ENTITY: {
|
||||
IfcUtil::IfcBaseClass* e = *argument;
|
||||
if (Type::IsSimple(e->type())) {
|
||||
IfcUtil::IfcBaseType* f = (IfcUtil::IfcBaseType*) e;
|
||||
value = format_attribute(f->getArgument(0), f->getArgumentType(0));
|
||||
} else if (e->is(IfcSchema::Type::IfcSIUnit) || e->is(IfcSchema::Type::IfcConversionBasedUnit)) {
|
||||
// Some string concatenation to have a unit name as a XML attribute.
|
||||
|
||||
std::string unit_name;
|
||||
|
||||
if (e->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();
|
||||
}
|
||||
|
||||
for (std::string::iterator c = unit_name.begin(); c != unit_name.end(); ++c) *c = tolower(*c);
|
||||
|
||||
value = unit_name;
|
||||
}
|
||||
break; }
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// 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;
|
||||
const unsigned n = instance->getArgumentCount();
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
const Argument* argument = instance->getArgument(i);
|
||||
if (argument->isNull()) continue;
|
||||
|
||||
std::string argument_name = instance->getArgumentName(i);
|
||||
std::map<std::string, std::string>::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->getArgumentType(i);
|
||||
|
||||
boost::optional<std::string> value;
|
||||
try {
|
||||
value = format_attribute(argument, argument_type);
|
||||
} catch (...) {}
|
||||
|
||||
if (value) {
|
||||
if (as_link) {
|
||||
if (argument_name == "id") {
|
||||
child.put("<xmlattr>.xlink:href", std::string("#") + *value);
|
||||
}
|
||||
} else {
|
||||
std::stringstream stream;
|
||||
stream << "<xmlattr>." << argument_name;
|
||||
child.put(stream.str(), *value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tree.add_child(Type::ToString(instance->type()), child);
|
||||
}
|
||||
|
||||
// A function to be called recursively. Template specialization is used
|
||||
// to descend into decomposition, containment and property relationships.
|
||||
template <typename A>
|
||||
void descend(A* instance, ptree& tree) {
|
||||
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 T, typename U, typename V, typename F, typename G>
|
||||
typename V::list::ptr get_related(T* t, F f, G g) {
|
||||
typename U::list::ptr li = (*t.*f)()->as<U>();
|
||||
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)());
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
// Descends into the tree by recursing into IfcRelContainedInSpatialStructure,
|
||||
// IfcRelDecomposes and IfcRelDefinesByProperties relations.
|
||||
template <>
|
||||
void descend(IfcProduct* 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
|
||||
<IfcSpatialStructureElement, IfcRelContainedInSpatialStructure, IfcProduct>
|
||||
(structure, &IfcSpatialStructureElement::ContainsElements, &IfcRelContainedInSpatialStructure::RelatedElements);
|
||||
|
||||
for (IfcProduct::list::it it = elements->begin(); it != elements->end(); ++it) {
|
||||
descend(*it, child);
|
||||
}
|
||||
}
|
||||
|
||||
IfcObjectDefinition::list::ptr structures = get_related
|
||||
<IfcProduct, IfcRelDecomposes, IfcObjectDefinition>
|
||||
(product, &IfcProduct::IsDecomposedBy, &IfcRelDecomposes::RelatedObjects);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
IfcPropertySetDefinition::list::ptr property_sets = get_related
|
||||
<IfcProduct, IfcRelDefinesByProperties, IfcPropertySetDefinition>
|
||||
(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);
|
||||
|
||||
IfcObjectDefinition::list::ptr structures = get_related
|
||||
<IfcProject, IfcRelDecomposes, IfcObjectDefinition>
|
||||
(project, &IfcProject::IsDecomposedBy, &IfcRelDecomposes::RelatedObjects);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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->is(Type::IfcComplexProperty)) {
|
||||
IfcComplexProperty* complex = (IfcComplexProperty*) p;
|
||||
format_properties(complex->HasProperties(), node);
|
||||
} else {
|
||||
format_entity_instance(p, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XmlSerializer::finalize() {
|
||||
argument_name_map.insert(std::make_pair("GlobalId", "id"));
|
||||
|
||||
IfcProject::list::ptr projects = file->EntitiesByType<IfcProject>();
|
||||
if (projects->size() != 1) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Expected a single IfcProject");
|
||||
return;
|
||||
}
|
||||
IfcProject* project = *projects->begin();
|
||||
|
||||
ptree root, header, decomposition, properties;
|
||||
|
||||
// Write the SPF header as XML nodes.
|
||||
BOOST_FOREACH(const std::string& s, file->header().file_description().description()) {
|
||||
header.add_child("file_description.description", ptree(s));
|
||||
}
|
||||
BOOST_FOREACH(const std::string& s, file->header().file_name().author()) {
|
||||
header.add_child("file_name.author", ptree(s));
|
||||
}
|
||||
BOOST_FOREACH(const std::string& s, file->header().file_name().organization()) {
|
||||
header.add_child("file_name.organization", ptree(s));
|
||||
}
|
||||
BOOST_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<IfcPropertySet>();
|
||||
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);
|
||||
}
|
||||
|
||||
root.add_child("ifc.header", header);
|
||||
root.add_child("ifc.properties", properties);
|
||||
root.add_child("ifc.decomposition", decomposition);
|
||||
|
||||
root.put("ifc.<xmlattr>.xmlns:xlink", "http://www.w3.org/1999/xlink");
|
||||
|
||||
boost::property_tree::xml_writer_settings<char> settings('\t', 1);
|
||||
boost::property_tree::write_xml(xml_filename, root, std::locale(), settings);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#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
|
||||
@@ -183,6 +183,10 @@
|
||||
RelativePath="..\src\ifcconvert\WavefrontObjSerializer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\ifcconvert\XmlSerializer.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
@@ -209,6 +213,10 @@
|
||||
RelativePath="..\src\ifcconvert\StepSerializer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\ifcconvert\Serializer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\ifcconvert\SurfaceStyle.h"
|
||||
>
|
||||
@@ -217,6 +225,10 @@
|
||||
RelativePath="..\src\ifcconvert\WavefrontObjSerializer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\ifcconvert\XmlSerializer.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
||||
Reference in New Issue
Block a user