mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
Ignore site placement also for site geometry - add queue #7654
This commit is contained in:
@@ -21,15 +21,37 @@
|
|||||||
#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()) {
|
||||||
for (auto iter = self_places->begin(); iter != self_places->end(); ++iter) {
|
auto [placement_entity, depth] = q.front();
|
||||||
if ((placement_rel_to_type_ && (*iter)->declaration().is(*placement_rel_to_type_)) ||
|
q.pop_front();
|
||||||
(placement_rel_to_instance_ && (*iter)->as<IfcUtil::IfcBaseEntity>() == placement_rel_to_instance_)){
|
|
||||||
return taxonomy::make<taxonomy::matrix4>();
|
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) {
|
||||||
|
if ((placement_rel_to_type_ && (*iter)->declaration().is(*placement_rel_to_type_)) ||
|
||||||
|
(placement_rel_to_instance_ && (*iter)->as<IfcUtil::IfcBaseEntity>() == placement_rel_to_instance_)) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user