mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 05:46:51 +00:00
Add layer information (IfcPresentationLayerAssignment) to IfcConvert's XML output. Closes #141 (#149)
Add layer information (IfcPresentationLayerAssignment) to IfcConvert's XML output. Closes #141
This commit is contained in:
committed by
Thomas Krijnen
parent
ea514e9528
commit
f0c4ce5753
@@ -33,7 +33,9 @@
|
|||||||
using boost::property_tree::ptree;
|
using boost::property_tree::ptree;
|
||||||
using namespace IfcSchema;
|
using namespace IfcSchema;
|
||||||
|
|
||||||
static std::map<std::string, std::string> argument_name_map;
|
namespace {
|
||||||
|
|
||||||
|
std::map<std::string, std::string> argument_name_map;
|
||||||
|
|
||||||
// Format an IFC attribute and maybe returns as string. Only literal scalar
|
// Format an IFC attribute and maybe returns as string. Only literal scalar
|
||||||
// values are converted. Things like entity instances and lists are omitted.
|
// values are converted. Things like entity instances and lists are omitted.
|
||||||
@@ -105,10 +107,8 @@ boost::optional<std::string> format_attribute(const Argument* argument, IfcUtil:
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formats an entity instances as a ptree node, and insert into the DOM. Recurses
|
// Appends to a node with possibly existing attributes
|
||||||
// over the entity attributes and writes them as xml attributes of the node.
|
ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& child, ptree& tree, bool as_link = false) {
|
||||||
ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& tree, bool as_link = false) {
|
|
||||||
ptree child;
|
|
||||||
const unsigned n = instance->getArgumentCount();
|
const unsigned n = instance->getArgumentCount();
|
||||||
for (unsigned i = 0; i < n; ++i) {
|
for (unsigned i = 0; i < n; ++i) {
|
||||||
const Argument* argument = instance->getArgument(i);
|
const Argument* argument = instance->getArgument(i);
|
||||||
@@ -142,6 +142,13 @@ ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& tree, boo
|
|||||||
return tree.add_child(Type::ToString(instance->type()), child);
|
return tree.add_child(Type::ToString(instance->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);
|
||||||
|
}
|
||||||
|
|
||||||
// A function to be called recursively. Template specialization is used
|
// A function to be called recursively. Template specialization is used
|
||||||
// to descend into decomposition, containment and property relationships.
|
// to descend into decomposition, containment and property relationships.
|
||||||
template <typename A>
|
template <typename A>
|
||||||
@@ -239,6 +246,39 @@ ptree& descend(IfcObjectDefinition* product, ptree& tree) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (product->is(Type::IfcProduct)) {
|
||||||
|
IfcProduct* prod = product->as<IfcProduct>();
|
||||||
|
if (prod->hasRepresentation()) {
|
||||||
|
IfcEntityList::ptr r = prod->entity->file->traverse(prod->Representation());
|
||||||
|
|
||||||
|
std::map<std::string, IfcPresentationLayerAssignment*> layers;
|
||||||
|
IfcRepresentation::list::ptr representations = r->as<IfcRepresentation>();
|
||||||
|
for (IfcRepresentation::list::it it = representations->begin(); it != representations->end(); ++it) {
|
||||||
|
IfcPresentationLayerAssignment::list::ptr a = (*it)->LayerAssignments();
|
||||||
|
for (IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
|
||||||
|
layers[(*jt)->Name()] = *jt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcRepresentationItem::list::ptr items = r->as<IfcRepresentationItem>();
|
||||||
|
for (IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) {
|
||||||
|
IfcPresentationLayerAssignment::list::ptr a = (*it)->LayerAssignments();
|
||||||
|
for (IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
|
||||||
|
layers[(*jt)->Name()] = *jt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<std::string, IfcPresentationLayerAssignment*>::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("<xmlattr>.xlink:href", "#" + it->first);
|
||||||
|
format_entity_instance(it->second, node, child, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +295,8 @@ void format_properties(IfcProperty::list::ptr properties, ptree& node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // ~unnamed namespace
|
||||||
|
|
||||||
void XmlSerializer::finalize() {
|
void XmlSerializer::finalize() {
|
||||||
argument_name_map.insert(std::make_pair("GlobalId", "id"));
|
argument_name_map.insert(std::make_pair("GlobalId", "id"));
|
||||||
|
|
||||||
@@ -265,7 +307,7 @@ void XmlSerializer::finalize() {
|
|||||||
}
|
}
|
||||||
IfcProject* project = *projects->begin();
|
IfcProject* project = *projects->begin();
|
||||||
|
|
||||||
ptree root, header, units, decomposition, properties, types;
|
ptree root, header, units, decomposition, properties, types, layers;
|
||||||
|
|
||||||
// Write the SPF header as XML nodes.
|
// Write the SPF header as XML nodes.
|
||||||
foreach(const std::string& s, file->header().file_description().description()) {
|
foreach(const std::string& s, file->header().file_description().description()) {
|
||||||
@@ -328,10 +370,26 @@ void XmlSerializer::finalize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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<std::string> layer_names;
|
||||||
|
IfcPresentationLayerAssignment::list::ptr layer_assignments = file->entitiesByType<IfcPresentationLayerAssignment>();
|
||||||
|
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("<xmlattr>.id", name);
|
||||||
|
format_entity_instance(*it, node, layers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
root.add_child("ifc.header", header);
|
root.add_child("ifc.header", header);
|
||||||
root.add_child("ifc.units", units);
|
root.add_child("ifc.units", units);
|
||||||
root.add_child("ifc.properties", properties);
|
root.add_child("ifc.properties", properties);
|
||||||
root.add_child("ifc.types", types);
|
root.add_child("ifc.types", types);
|
||||||
|
root.add_child("ifc.layers", layers);
|
||||||
root.add_child("ifc.decomposition", decomposition);
|
root.add_child("ifc.decomposition", decomposition);
|
||||||
|
|
||||||
root.put("ifc.<xmlattr>.xmlns:xlink", "http://www.w3.org/1999/xlink");
|
root.put("ifc.<xmlattr>.xmlns:xlink", "http://www.w3.org/1999/xlink");
|
||||||
|
|||||||
Reference in New Issue
Block a user