@@ -1506,15 +1506,52 @@ void IfcFile::recalculate_id_counter() {
15061506 MaxId = (unsigned int )k;
15071507}
15081508
1509+ class traversal_recorder {
1510+ IfcEntityList::ptr list_;
1511+ std::map<int , IfcEntityList::ptr> instances_by_level_;
1512+ int mode_;
1513+
1514+ public:
1515+ traversal_recorder (int mode) : mode_(mode) {
1516+ if (mode == 0 ) {
1517+ list_.reset (new IfcEntityList);
1518+ }
1519+ };
1520+
1521+ void push_back (int level, IfcUtil::IfcBaseClass* instance) {
1522+ if (mode_ == 0 ) {
1523+ list_->push (instance);
1524+ } else {
1525+ auto & l = instances_by_level_[level];
1526+ if (!l) {
1527+ l.reset (new IfcEntityList);
1528+ }
1529+ l->push (instance);
1530+ }
1531+ }
1532+
1533+ IfcEntityList::ptr get_list () const {
1534+ if (mode_ == 0 ) {
1535+ return list_;
1536+ } else {
1537+ IfcEntityList::ptr l (new IfcEntityList);
1538+ for (auto & p : instances_by_level_) {
1539+ l->push (p.second );
1540+ }
1541+ return l;
1542+ }
1543+ }
1544+ };
1545+
15091546class traversal_visitor {
15101547private:
15111548 std::set<IfcUtil::IfcBaseClass*>& visited_;
1512- IfcEntityList::ptr & list_;
1549+ traversal_recorder & list_;
15131550 int level_;
15141551 int max_level_;
15151552
15161553public:
1517- traversal_visitor (std::set<IfcUtil::IfcBaseClass*>& visited, IfcEntityList::ptr & list, int level, int max_level)
1554+ traversal_visitor (std::set<IfcUtil::IfcBaseClass*>& visited, traversal_recorder & list, int level, int max_level)
15181555 : visited_(visited)
15191556 , list_(list)
15201557 , level_(level)
@@ -1524,12 +1561,12 @@ class traversal_visitor {
15241561 void operator ()(IfcUtil::IfcBaseClass* inst);
15251562};
15261563
1527- void traverse_ (IfcUtil::IfcBaseClass* instance, std::set<IfcUtil::IfcBaseClass*>& visited, IfcEntityList::ptr list, int level, int max_level) {
1564+ void traverse_ (IfcUtil::IfcBaseClass* instance, std::set<IfcUtil::IfcBaseClass*>& visited, traversal_recorder& list, int level, int max_level) {
15281565 if (visited.find (instance) != visited.end ()) {
15291566 return ;
15301567 }
15311568 visited.insert (instance);
1532- list-> push ( instance);
1569+ list. push_back (level, instance);
15331570
15341571 if (level >= max_level && max_level > 0 ) return ;
15351572
@@ -1543,16 +1580,30 @@ void traversal_visitor::operator()(IfcUtil::IfcBaseClass* inst) {
15431580
15441581IfcEntityList::ptr IfcParse::traverse (IfcUtil::IfcBaseClass* instance, int max_level) {
15451582 std::set<IfcUtil::IfcBaseClass*> visited;
1546- IfcEntityList::ptr return_value (new IfcEntityList);
1547- traverse_ (instance, visited, return_value, 0 , max_level);
1548- return return_value;
1583+ traversal_recorder r (0 );
1584+ traverse_ (instance, visited, r, 0 , max_level);
1585+ return r.get_list ();
1586+ }
1587+
1588+ // I'm cheating this isn't breadth-first, but rather we record visited instances
1589+ // keeping track of their rank and return a list ordered by rank. Is this equivalent?
1590+ IfcEntityList::ptr IfcParse::traverse_breadth_first (IfcUtil::IfcBaseClass* instance, int max_level) {
1591+ std::set<IfcUtil::IfcBaseClass*> visited;
1592+ traversal_recorder r (1 );
1593+ traverse_ (instance, visited, r, 0 , max_level);
1594+ return r.get_list ();
15491595}
15501596
15511597// / @note: for backwards compatibility
15521598IfcEntityList::ptr IfcFile::traverse (IfcUtil::IfcBaseClass* instance, int max_level) {
15531599 return IfcParse::traverse (instance, max_level);
15541600}
15551601
1602+ // / @note: for backwards compatibility
1603+ IfcEntityList::ptr IfcFile::traverse_breadth_first (IfcUtil::IfcBaseClass* instance, int max_level) {
1604+ return IfcParse::traverse_breadth_first (instance, max_level);
1605+ }
1606+
15561607void IfcFile::mark_entity_as_modified (int /* id*/ )
15571608{
15581609 by_ref_cached_.clear ();
@@ -1825,7 +1876,7 @@ void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
18251876 throw IfcParse::IfcException (" Instance not part of this file" );
18261877 }
18271878
1828- batch_deletion_ids_.insert (id);
1879+ batch_deletion_ids_.push_back (id);
18291880
18301881 if (!batch_mode_) {
18311882 process_deletion_ ();
@@ -1834,7 +1885,7 @@ void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
18341885
18351886void IfcFile::process_deletion_ () {
18361887
1837- for (auto & id : batch_deletion_ids_) {
1888+ for (auto & id : batch_deletion_ids_. get < 0 >() ) {
18381889 auto entity = instance_by_id (id);
18391890
18401891 IfcEntityList::ptr references = instances_by_reference (id);
@@ -1980,10 +2031,10 @@ void IfcFile::process_deletion_() {
19802031
19812032 if (batch_mode_) {
19822033 for (auto it = byref.begin (); it != byref.end ();) {
1983- bool do_delete = batch_deletion_ids_.find (it->first ) != batch_deletion_ids_.end ();
2034+ bool do_delete = batch_deletion_ids_.get < 1 >(). find (it->first ) != batch_deletion_ids_. get < 1 >() .end ();
19842035 if (!do_delete) {
19852036 it->second .erase (std::remove_if (it->second .begin (), it->second .end (), [this ](int x) {
1986- return batch_deletion_ids_.find (x) != batch_deletion_ids_.end ();
2037+ return batch_deletion_ids_.get < 1 >(). find (x) != batch_deletion_ids_. get < 1 >() .end ();
19872038 }), it->second .end ());
19882039 do_delete = it->second .empty ();
19892040 }
0 commit comments