mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 01:00:56 +00:00
Fix recursion in traverse()
This commit is contained in:
@@ -1361,6 +1361,24 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class traversal_visitor {
|
||||||
|
private:
|
||||||
|
std::set<IfcUtil::IfcBaseClass*>& visited_;
|
||||||
|
IfcEntityList::ptr& list_;
|
||||||
|
int level_;
|
||||||
|
int max_level_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
traversal_visitor(std::set<IfcUtil::IfcBaseClass*>& visited, IfcEntityList::ptr& list, int level, int max_level)
|
||||||
|
: visited_(visited)
|
||||||
|
, list_(list)
|
||||||
|
, level_(level)
|
||||||
|
, max_level_(max_level)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(IfcUtil::IfcBaseClass* inst);
|
||||||
|
};
|
||||||
|
|
||||||
void traverse_(IfcUtil::IfcBaseClass* instance, std::set<IfcUtil::IfcBaseClass*>& visited, IfcEntityList::ptr list, int level, int max_level) {
|
void traverse_(IfcUtil::IfcBaseClass* instance, std::set<IfcUtil::IfcBaseClass*>& visited, IfcEntityList::ptr list, int level, int max_level) {
|
||||||
if (visited.find(instance) != visited.end()) {
|
if (visited.find(instance) != visited.end()) {
|
||||||
return;
|
return;
|
||||||
@@ -1370,10 +1388,14 @@ void traverse_(IfcUtil::IfcBaseClass* instance, std::set<IfcUtil::IfcBaseClass*>
|
|||||||
|
|
||||||
if (level >= max_level && max_level > 0) return;
|
if (level >= max_level && max_level > 0) return;
|
||||||
|
|
||||||
add_to_instance_list_visitor visit(list);
|
traversal_visitor visit(visited, list, level + 1, max_level);
|
||||||
apply_individual_instance_visitor(instance->entity).apply(visit);
|
apply_individual_instance_visitor(instance->entity).apply(visit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void traversal_visitor::operator()(IfcUtil::IfcBaseClass* inst) {
|
||||||
|
traverse_(inst, visited_, list_, level_, max_level_);
|
||||||
|
}
|
||||||
|
|
||||||
IfcEntityList::ptr IfcParse::traverse(IfcUtil::IfcBaseClass* instance, int max_level) {
|
IfcEntityList::ptr IfcParse::traverse(IfcUtil::IfcBaseClass* instance, int max_level) {
|
||||||
std::set<IfcUtil::IfcBaseClass*> visited;
|
std::set<IfcUtil::IfcBaseClass*> visited;
|
||||||
IfcEntityList::ptr return_value(new IfcEntityList);
|
IfcEntityList::ptr return_value(new IfcEntityList);
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ assert f.by_guid("28pa2ppDf1IA$BaQrvAf48").is_a("IfcProject")
|
|||||||
assert f.createIfcCartesianPoint((0., 0., 0.)).is_a("IfcCartesianPoint")
|
assert f.createIfcCartesianPoint((0., 0., 0.)).is_a("IfcCartesianPoint")
|
||||||
assert f.by_type("IfcProject")[0].is_a("IfcProject")
|
assert f.by_type("IfcProject")[0].is_a("IfcProject")
|
||||||
assert f.traverse(f[16])[-1].is_a("IFCSIUNIT")
|
assert f.traverse(f[16])[-1].is_a("IFCSIUNIT")
|
||||||
|
assert len(f.traverse(f[35], 1)) == 2
|
||||||
|
assert len(f.traverse(f[35])) == 3
|
||||||
assert f[16] in f.get_inverse(f[15])
|
assert f[16] in f.get_inverse(f[15])
|
||||||
assert f[16].UnitComponent is not None
|
assert f[16].UnitComponent is not None
|
||||||
f.remove(f[15])
|
f.remove(f[15])
|
||||||
|
|||||||
Reference in New Issue
Block a user