Ignore site placement also for site geometry - add queue #7654

This commit is contained in:
Thomas Krijnen
2026-02-09 21:37:21 +01:00
parent a4d5d4e19a
commit a46cdbb907
+26 -4
View File
@@ -21,17 +21,39 @@
#define mapping POSTFIX_SCHEMA(mapping) #define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry; using namespace ifcopenshell::geometry;
#include <deque>
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) { taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) {
if (placement_rel_to_type_ || placement_rel_to_instance_) { if (placement_rel_to_type_ || placement_rel_to_instance_) {
// @nb this is not a full solution because we only look for the direct PlacesObject relationships of the current placement, using QueueItem = std::pair<const IfcUtil::IfcBaseEntity*, int>;
// a more complete solution should track whether this element sits above the element of which the placement is being ignored. std::deque<QueueItem> q = {{inst, 0}};
auto self_places = inst->PlacesObject(); while (!q.empty()) {
auto [placement_entity, depth] = q.front();
q.pop_front();
auto placement = placement_entity->as<typename IfcSchema::IfcObjectPlacement>();
if (!placement) {
continue;
}
auto self_places = placement->PlacesObject();
inst->ReferencedByPlacements();
for (auto iter = self_places->begin(); iter != self_places->end(); ++iter) { for (auto iter = self_places->begin(); iter != self_places->end(); ++iter) {
if ((placement_rel_to_type_ && (*iter)->declaration().is(*placement_rel_to_type_)) || if ((placement_rel_to_type_ && (*iter)->declaration().is(*placement_rel_to_type_)) ||
(placement_rel_to_instance_ && (*iter)->as<IfcUtil::IfcBaseEntity>() == placement_rel_to_instance_)){ (placement_rel_to_instance_ && (*iter)->as<IfcUtil::IfcBaseEntity>() == placement_rel_to_instance_)) {
return taxonomy::make<taxonomy::matrix4>(); return taxonomy::make<taxonomy::matrix4>();
} }
} }
// Look for two levels deep, we want to know if we're at or *above* the
// element we're ignoring, but we don't want to traverse the entire model.
if (depth < 2) {
auto refs = placement->ReferencedByPlacements();
for (auto& ref : *refs) {
q.emplace_back(ref, depth + 1);
}
}
}
} }
const IfcSchema::IfcObjectPlacement* relative_to = nullptr; const IfcSchema::IfcObjectPlacement* relative_to = nullptr;