diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 37599498fd..797d7dbe88 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -200,8 +200,8 @@ int main(int argc, char** argv) "geometrical output. The name patterns are handled case-sensitively. Cannot be placed right before input file argument. " "Only single option supported for now.") ("exclude", po::value(&exclude_filter)->multitoken(), - "Specifies that the 'entities', 'names', or 'guids' provided are to be excluded. Defaults to IfcOpeningElement and IfcSpace " - "to be excluded. See --include for syntax and more details.") + "Specifies that the 'entities', 'names', 'guids', or 'layers' provided are to be excluded. " + "The default value is '--exclude=entities IfcOpeningElement IfcSpace'. See --include for syntax and more details.") ("no-normals", "Disables computation of normals. Saves time and file size and is useful " "in instances where you're going to recompute normals for the exported " @@ -647,8 +647,8 @@ void validate(boost::any& v, const std::vector& values, inclusion_f filter.type = geom_filter::ENTITY_NAME; } else if (type == "guids") { filter.type = geom_filter::ENTITY_GUID; - //} else if (type == "layers") { - // filter.type = geom_filter::LAYER_NAME; + } else if (type == "layers") { + filter.type = geom_filter::LAYER_NAME; } else { throw po::validation_error(po::validation_error::invalid_option_value); } @@ -671,8 +671,8 @@ void validate(boost::any& v, const std::vector& values, exclusion_f filter.type = geom_filter::ENTITY_NAME; } else if (type == "guids") { filter.type = geom_filter::ENTITY_GUID; - //} else if (type == "layers") { - // filter.type = geom_filter::LAYER_NAME; + } else if (type == "layers") { + filter.type = geom_filter::LAYER_NAME; } else { throw po::validation_error(po::validation_error::invalid_option_value); } diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp index a3dbaafc87..94a6dd562f 100644 --- a/src/ifcconvert/XmlSerializer.cpp +++ b/src/ifcconvert/XmlSerializer.cpp @@ -270,41 +270,14 @@ ptree& descend(IfcObjectDefinition* product, ptree& tree) { } if (product->is(Type::IfcProduct)) { - IfcProduct* prod = product->as(); - if (prod->hasRepresentation()) { - IfcEntityList::ptr r = prod->entity->file->traverse(prod->Representation()); - - std::map layers; - IfcRepresentation::list::ptr representations = r->as(); - 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(); - for (IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) { - IfcPresentationLayerAssignment::list::ptr a = (*it)-> - // LayerAssignments renamed from plural to singular, LayerAssignment, so work around that -#ifdef USE_IFC4 - LayerAssignment(); -#else - LayerAssignments(); -#endif - for (IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) { - layers[(*jt)->Name()] = *jt; - } - } - - 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); - } + 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); } } diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index c14cb0bd00..db4c2a4e51 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -241,6 +241,8 @@ public: IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*); + static std::map get_layers(IfcSchema::IfcProduct* prod); + template IfcGeom::BRepElement

* create_brep_for_representation_and_product( const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*); diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 0614fad66a..956bcedc72 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -1275,6 +1275,37 @@ IfcSchema::IfcObjectDefinition* IfcGeom::Kernel::get_decomposing_entity(IfcSchem return parent; } +std::map IfcGeom::Kernel::get_layers(IfcSchema::IfcProduct* prod) +{ + using namespace IfcSchema; + std::map layers; + if (prod->hasRepresentation()) { + IfcEntityList::ptr r = prod->entity->file->traverse(prod->Representation()); + IfcRepresentation::list::ptr representations = r->as(); + 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(); + for (IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) { + IfcPresentationLayerAssignment::list::ptr a = (*it)-> + // LayerAssignments renamed from plural to singular, LayerAssignment, so work around that +#ifdef USE_IFC4 + LayerAssignment(); +#else + LayerAssignments(); +#endif + for (IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) { + layers[(*jt)->Name()] = *jt; + } + } + } + return layers; +} + template IFC_GEOM_API IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_representation_and_product( const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product); template IFC_GEOM_API IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_representation_and_product( diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index 77963095ba..88da0d6afb 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -583,83 +583,127 @@ namespace IfcGeom { const bool traverse = settings.get(IteratorSettings::TRAVERSE); for (IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt) { IfcSchema::IfcProduct* prod = *jt; + /// @todo Horrible copy-pasta, refactor. bool type_found = false; - // The set is iterated over to able to filter on subtypes. - foreach(IfcSchema::Type::Enum type, entity_filter_.values) { - if (prod->is(type)) { - type_found = true; - break; - } - } - - if (type_found != entity_filter_.include && traverse) { + if (!entity_filter_.values.empty()) { + // The set is iterated over to able to filter on subtypes. foreach(IfcSchema::Type::Enum type, entity_filter_.values) { - IfcSchema::IfcProduct* parent, * current = prod; - while ((parent = static_cast(kernel.get_decomposing_entity(current))) != 0) { - if (parent->is(type)) { - type_found = true; + if (prod->is(type)) { + type_found = true; + break; + } + } + + if (type_found != entity_filter_.include && traverse) { + foreach(IfcSchema::Type::Enum type, entity_filter_.values) { + IfcSchema::IfcProduct* parent, *current = prod; + while ((parent = static_cast(kernel.get_decomposing_entity(current))) != 0) { + if (parent->is(type)) { + type_found = true; + break; + } + current = parent; + } + if (type_found) { break; } - current = parent; - } - if (type_found) { - break; } } } bool name_found = false; - foreach(const boost::regex& r, name_filter_.values) { - if (prod->hasName() && boost::regex_match(prod->Name(), r)) { - name_found = true; - break; - } - } - - if (name_found != name_filter_.include && traverse) { + if (!name_filter_.values.empty()) { foreach(const boost::regex& r, name_filter_.values) { - IfcSchema::IfcProduct* parent, *current = prod; - while ((parent = static_cast(kernel.get_decomposing_entity(current))) != 0) { - if (parent->hasName() && boost::regex_match(parent->Name(), r)) { - name_found = true; + if (prod->hasName() && boost::regex_match(prod->Name(), r)) { + name_found = true; + break; + } + } + + if (name_found != name_filter_.include && traverse) { + foreach(const boost::regex& r, name_filter_.values) { + IfcSchema::IfcProduct* parent, *current = prod; + while ((parent = static_cast(kernel.get_decomposing_entity(current))) != 0) { + if (parent->hasName() && boost::regex_match(parent->Name(), r)) { + name_found = true; + break; + } + current = parent; + } + if (name_found) { break; } - current = parent; - } - if (name_found) { - break; } } } bool guid_found = false; - foreach(const boost::regex& r, guid_filter_.values) { - if (boost::regex_match(prod->GlobalId(), r)) { - guid_found = true; - break; - } - } - - if (guid_found != guid_filter_.include && traverse) { + if (!guid_filter_.values.empty()) { foreach(const boost::regex& r, guid_filter_.values) { - IfcSchema::IfcProduct* parent, *current = prod; - while ((parent = static_cast(kernel.get_decomposing_entity(current))) != 0) { - if (boost::regex_match(parent->GlobalId(), r)) { - guid_found = true; - break; - } - current = parent; - } - if (guid_found) { + if (boost::regex_match(prod->GlobalId(), r)) { + std::cout << prod->GlobalId() << std::endl; + guid_found = true; break; } } + + if (guid_found != guid_filter_.include && traverse) { + foreach(const boost::regex& r, guid_filter_.values) { + IfcSchema::IfcProduct* parent, *current = prod; + while ((parent = static_cast(kernel.get_decomposing_entity(current))) != 0) { + if (boost::regex_match(parent->GlobalId(), r)) { + guid_found = true; + break; + } + current = parent; + } + if (guid_found) { + break; + } + } + } } - if (type_found == entity_filter_.include && name_found == name_filter_.include && guid_found == guid_filter_.include) { + bool layer_found = false; + if (!layer_filter_.values.empty()) { + std::map layers = IfcGeom::Kernel::get_layers(prod); + std::map::const_iterator lit; + foreach(const boost::regex& r, layer_filter_.values) { + for (lit = layers.begin(); lit != layers.end(); ++lit) { + if (boost::regex_match(lit->first, r)) { + layer_found = true; + break; + } + } + if (layer_found) { + break; + } + } + + if (layer_found != layer_filter_.include && traverse) { + foreach(const boost::regex& r, layer_filter_.values) { + for (lit = layers.begin(); lit != layers.end(); ++lit) { + IfcSchema::IfcProduct* parent, *current = prod; + while ((parent = static_cast(kernel.get_decomposing_entity(current))) != 0) { + if (boost::regex_match(lit->first, r)) { + layer_found = true; + break; + } + current = parent; + } + if (layer_found) { + break; + } + } + } + } + } + + if (type_found == entity_filter_.include && name_found == name_filter_.include && + guid_found == guid_filter_.include && layer_found == layer_filter_.include) { ifcproducts->push(prod); } - } + } ifcproduct_iterator = ifcproducts->begin(); }