diff --git a/src/ifcgeom_schema_agnostic/IfcGeomFilter.h b/src/ifcgeom_schema_agnostic/IfcGeomFilter.h index 8d4a1192e3..e98e54d972 100644 --- a/src/ifcgeom_schema_agnostic/IfcGeomFilter.h +++ b/src/ifcgeom_schema_agnostic/IfcGeomFilter.h @@ -230,6 +230,32 @@ namespace IfcGeom { description = ss.str(); } }; + + struct instance_id_filter : public filter { + std::set instance_ids_; + + instance_id_filter() {} + instance_id_filter(bool include, bool traverse, const std::set& instance_ids) + : filter(include, traverse) + , instance_ids_(instance_ids) {} + + bool match(IfcUtil::IfcBaseEntity* prod) const { + return instance_ids_.find(prod->data().id()) != instance_ids_.end(); + } + + bool operator()(IfcUtil::IfcBaseEntity* prod) const { + return filter::match(prod, std::bind(&instance_id_filter::match, this, std::placeholders::_1)); + } + + void update_description() { + std::stringstream ss; + ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " ids"; + for (auto& id : instance_ids_) { + ss << " " << id; + } + description = ss.str(); + } + }; } #endif diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py index 49f4274e55..f5cffbe269 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/main.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py @@ -97,10 +97,9 @@ class iterator(ifcopenshell_wrapper.Iterator): if not all(inst.is_a("IfcProduct") for inst in include_or_exclude): raise ValueError("include and exclude need to be an aggregate of IfcProduct") - initializer = ifcopenshell_wrapper.construct_iterator_with_include_exclude_globalid + initializer = ifcopenshell_wrapper.construct_iterator_with_include_exclude_id - decode_unicode = lambda x: x.encode("ascii") if x.__class__.__name__ == "unicode" else x - include_or_exclude = list(map(decode_unicode, map(operator.attrgetter("GlobalId"), include_or_exclude))) + include_or_exclude = [i.id() for i in include_or_exclude] else: initializer = ifcopenshell_wrapper.construct_iterator_with_include_exclude diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i index 815faf49b6..98824e262d 100644 --- a/src/ifcwrap/IfcGeomWrapper.i +++ b/src/ifcwrap/IfcGeomWrapper.i @@ -214,10 +214,17 @@ struct ShapeRTTI : public boost::static_visitor af.include = include; return new IfcGeom::Iterator(settings, file, {af}, num_threads); } + + IfcGeom::Iterator* construct_iterator_with_include_exclude_id(IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector elems, bool include, int num_threads) { + std::set elems_set(elems.begin(), elems.end()); + IfcGeom::instance_id_filter af(include, false, elems_set); + return new IfcGeom::Iterator(settings, file, {af}, num_threads); + } %} %newobject construct_iterator_with_include_exclude; %newobject construct_iterator_with_include_exclude_globalid; +%newobject construct_iterator_with_include_exclude_id; %extend IfcGeom::Representation::Triangulation { %pythoncode %{