@@ -1016,13 +1016,18 @@ IfcEntityInstanceData::IfcEntityInstanceData(const IfcEntityInstanceData& e) {
10161016 }
10171017}
10181018
1019+ static IfcParse::NullArgument static_null_attribute;
10191020
10201021Argument* IfcEntityInstanceData::getArgument (unsigned int i) const {
10211022 if (attributes_ == 0 ) {
10221023 load ();
10231024 }
10241025 if (i < getArgumentCount ()) {
1025- return attributes_[i];
1026+ if (attributes_[i] == nullptr ) {
1027+ return &static_null_attribute;
1028+ } else {
1029+ return attributes_[i];
1030+ }
10261031 } else {
10271032 throw IfcParse::IfcException (" Attribute index out of range" );
10281033 }
@@ -1284,8 +1289,8 @@ IfcFile::IfcFile(IfcParse::IfcSpfStream* s) {
12841289}
12851290
12861291IfcFile::IfcFile (const IfcParse::schema_definition* schema)
1287- : parsing_complete_ (false )
1288- , good_ (false )
1292+ : parsing_complete_ (true )
1293+ , good_ (true )
12891294 , schema_ (schema)
12901295 , ifcroot_type_ (schema_->declaration_by_name (" IfcRoot" ))
12911296 , MaxId (0 )
@@ -1521,18 +1526,20 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
15211526
15221527 // Obtain all forward references by a depth-first
15231528 // traversal and add them to the file.
1524- try {
1525- IfcEntityList::ptr entity_attributes = traverse (entity, 1 );
1526- for (IfcEntityList::it it = entity_attributes->begin (); it != entity_attributes->end (); ++it) {
1527- if (*it != entity) {
1528- entity_entity_map_t ::iterator mit2 = entity_file_map.find (*it);
1529- if (mit2 == entity_file_map.end ()) {
1530- entity_file_map.insert (entity_entity_map_t::value_type (*it, addEntity (*it)));
1529+ if (parsing_complete_) {
1530+ try {
1531+ IfcEntityList::ptr entity_attributes = traverse (entity, 1 );
1532+ for (IfcEntityList::it it = entity_attributes->begin (); it != entity_attributes->end (); ++it) {
1533+ if (*it != entity) {
1534+ entity_entity_map_t ::iterator mit2 = entity_file_map.find (*it);
1535+ if (mit2 == entity_file_map.end ()) {
1536+ entity_file_map.insert (entity_entity_map_t::value_type (*it, addEntity (*it)));
1537+ }
15311538 }
15321539 }
1540+ } catch (...) {
1541+ Logger::Message (Logger::LOG_ERROR, " Failed to visit forward references of" , entity);
15331542 }
1534- } catch (...) {
1535- Logger::Message (Logger::LOG_ERROR, " Failed to visit forward references of" , entity);
15361543 }
15371544
15381545 // See whether the instance is already part of a file
@@ -1642,6 +1649,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
16421649 we->set_id (FreshId ());
16431650 }
16441651
1652+ // @todo entity_file_map: use weak_ptr
16451653 entity_file_map.insert (entity_entity_map_t::value_type (entity, new_entity));
16461654 }
16471655
@@ -1709,27 +1717,8 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
17091717 byid[new_id] = new_entity;
17101718 }
17111719
1712- if (ty->as_entity ()) {
1713- // The mapping by reference is updated.
1714- IfcEntityList::ptr entity_attributes (new IfcEntityList);
1715- try {
1716- entity_attributes = traverse (new_entity, 1 );
1717- } catch (const std::exception& e) {
1718- Logger::Error (e);
1719- }
1720-
1721- for (IfcEntityList::it it = entity_attributes->begin (); it != entity_attributes->end (); ++it) {
1722- IfcUtil::IfcBaseClass* entity_attribute = *it;
1723- if (*it == new_entity) continue ;
1724- try {
1725- if (entity_attribute->declaration ().as_entity ()) {
1726- unsigned entity_attribute_id = entity_attribute->data ().id ();
1727- byref[entity_attribute_id].push_back (new_entity->data ().id ());
1728- }
1729- } catch (const std::exception& e) {
1730- Logger::Error (e);
1731- }
1732- }
1720+ if (parsing_complete_ && ty->as_entity ()) {
1721+ build_inverses_ (new_entity);
17331722 }
17341723
17351724 return new_entity;
@@ -2097,3 +2086,31 @@ std::pair<IfcUtil::IfcBaseClass*, double> IfcFile::getUnit(const std::string& un
20972086
20982087 return return_value;
20992088}
2089+
2090+ void IfcParse::IfcFile::build_inverses_ (IfcUtil::IfcBaseClass* inst) {
2091+ IfcEntityList::ptr entity_attributes (new IfcEntityList);
2092+ try {
2093+ entity_attributes = traverse (inst, 1 );
2094+ } catch (const std::exception& e) {
2095+ Logger::Error (e);
2096+ }
2097+
2098+ for (IfcEntityList::it it = entity_attributes->begin (); it != entity_attributes->end (); ++it) {
2099+ IfcUtil::IfcBaseClass* entity_attribute = *it;
2100+ if (*it == inst) continue ;
2101+ try {
2102+ if (entity_attribute->declaration ().as_entity ()) {
2103+ unsigned entity_attribute_id = entity_attribute->data ().id ();
2104+ byref[entity_attribute_id].push_back (inst->data ().id ());
2105+ }
2106+ } catch (const std::exception& e) {
2107+ Logger::Error (e);
2108+ }
2109+ }
2110+ }
2111+
2112+ void IfcParse::IfcFile::build_inverses () {
2113+ for (auto & pair : *this ) {
2114+ build_inverses_ (pair.second );
2115+ }
2116+ }
0 commit comments