mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 05:46:51 +00:00
Fixes for IfcEntityInstanceData copy construction
This commit is contained in:
+34
-17
@@ -975,10 +975,13 @@ void IfcEntityInstanceData::load() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IfcEntityInstanceData::IfcEntityInstanceData(const IfcEntityInstanceData& e) {
|
IfcEntityInstanceData::IfcEntityInstanceData(const IfcEntityInstanceData& e) {
|
||||||
file = e.file;
|
file = 0;
|
||||||
type_ = e.type_;
|
type_ = e.type_;
|
||||||
id_ = 0;
|
id_ = 0;
|
||||||
|
|
||||||
|
// In order not to have the instance read from file
|
||||||
|
initialized_ = true;
|
||||||
|
|
||||||
const unsigned int count = e.getArgumentCount();
|
const unsigned int count = e.getArgumentCount();
|
||||||
for (unsigned int i = 0; i < count; ++i) {
|
for (unsigned int i = 0; i < count; ++i) {
|
||||||
this->setArgument(i, e.getArgument(i));
|
this->setArgument(i, e.getArgument(i));
|
||||||
@@ -1185,6 +1188,7 @@ void IfcEntityInstanceData::setArgument(unsigned int i, Argument* a, IfcUtil::Ar
|
|||||||
case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE: {
|
case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE: {
|
||||||
IfcUtil::ArgumentType t2 = IfcSchema::Type::GetAttributeType(type(), (unsigned char)i);
|
IfcUtil::ArgumentType t2 = IfcSchema::Type::GetAttributeType(type(), (unsigned char)i);
|
||||||
delete copy;
|
delete copy;
|
||||||
|
copy = 0;
|
||||||
setArgument(i, a, t2);
|
setArgument(i, a, t2);
|
||||||
break; }
|
break; }
|
||||||
default:
|
default:
|
||||||
@@ -1193,6 +1197,10 @@ void IfcEntityInstanceData::setArgument(unsigned int i, Argument* a, IfcUtil::Ar
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!copy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (i < attributes_.size()) {
|
if (i < attributes_.size()) {
|
||||||
Argument* current_attribute = attributes_[i];
|
Argument* current_attribute = attributes_[i];
|
||||||
if (this->file) {
|
if (this->file) {
|
||||||
@@ -1422,13 +1430,18 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
return mit->second;
|
return mit->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IfcUtil::IfcBaseClass* new_entity = entity;
|
||||||
|
|
||||||
// Obtain all forward references by a depth-first
|
// Obtain all forward references by a depth-first
|
||||||
// traversal and add them to the file.
|
// traversal and add them to the file.
|
||||||
try {
|
try {
|
||||||
IfcEntityList::ptr entity_attributes = traverse(entity, 1);
|
IfcEntityList::ptr entity_attributes = traverse(entity, 1);
|
||||||
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
|
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
|
||||||
if (*it != entity) {
|
if (*it != entity) {
|
||||||
entity_file_map.insert(entity_entity_map_t::value_type(*it, addEntity(*it)));
|
entity_entity_map_t::iterator mit2 = entity_file_map.find(*it);
|
||||||
|
if (mit2 == entity_file_map.end()) {
|
||||||
|
entity_file_map.insert(entity_entity_map_t::value_type(*it, addEntity(*it)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -1448,7 +1461,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
// need to be updated to point to instances in this file.
|
// need to be updated to point to instances in this file.
|
||||||
IfcFile* other_file = entity->entity->file;
|
IfcFile* other_file = entity->entity->file;
|
||||||
IfcEntityInstanceData* we = new IfcEntityInstanceData(*entity->entity);
|
IfcEntityInstanceData* we = new IfcEntityInstanceData(*entity->entity);
|
||||||
entity = IfcSchema::SchemaEntity(we);
|
new_entity = IfcSchema::SchemaEntity(we);
|
||||||
|
|
||||||
// In case an entity is added that contains geometry, the unit
|
// In case an entity is added that contains geometry, the unit
|
||||||
// information needs to be accounted for for IfcLengthMeasures.
|
// information needs to be accounted for for IfcLengthMeasures.
|
||||||
@@ -1523,12 +1536,16 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
// A new entity instance name is generated and
|
// A new entity instance name is generated and
|
||||||
// the instance is pointed to this file.
|
// the instance is pointed to this file.
|
||||||
we->file = this;
|
we->file = this;
|
||||||
we->set_id(FreshId());
|
if (!IfcSchema::Type::IsSimple(we->type())) {
|
||||||
|
we->set_id(FreshId());
|
||||||
|
}
|
||||||
|
|
||||||
|
entity_file_map.insert(entity_entity_map_t::value_type(entity, new_entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
// For subtypes of IfcRoot, the GUID mapping needs to be updated.
|
// For subtypes of IfcRoot, the GUID mapping needs to be updated.
|
||||||
if (entity->is(IfcSchema::Type::IfcRoot)) {
|
if (new_entity->is(IfcSchema::Type::IfcRoot)) {
|
||||||
IfcSchema::IfcRoot* ifc_root = (IfcSchema::IfcRoot*) entity;
|
IfcSchema::IfcRoot* ifc_root = (IfcSchema::IfcRoot*) new_entity;
|
||||||
try {
|
try {
|
||||||
const std::string guid = ifc_root->GlobalId();
|
const std::string guid = ifc_root->GlobalId();
|
||||||
if ( byguid.find(guid) != byguid.end() ) {
|
if ( byguid.find(guid) != byguid.end() ) {
|
||||||
@@ -1543,14 +1560,14 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The mapping by entity type is updated.
|
// The mapping by entity type is updated.
|
||||||
IfcSchema::Type::Enum ty = entity->type();
|
IfcSchema::Type::Enum ty = new_entity->type();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
IfcEntityList::ptr instances_by_type = entitiesByType(ty);
|
IfcEntityList::ptr instances_by_type = entitiesByType(ty);
|
||||||
if (!instances_by_type) {
|
if (!instances_by_type) {
|
||||||
instances_by_type = IfcEntityList::ptr(new IfcEntityList());
|
instances_by_type = IfcEntityList::ptr(new IfcEntityList());
|
||||||
bytype[ty] = instances_by_type;
|
bytype[ty] = instances_by_type;
|
||||||
}
|
}
|
||||||
instances_by_type->push(entity);
|
instances_by_type->push(new_entity);
|
||||||
boost::optional<IfcSchema::Type::Enum> pt = IfcSchema::Type::Parent(ty);
|
boost::optional<IfcSchema::Type::Enum> pt = IfcSchema::Type::Parent(ty);
|
||||||
if (pt) {
|
if (pt) {
|
||||||
ty = *pt;
|
ty = *pt;
|
||||||
@@ -1561,12 +1578,12 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int new_id = -1;
|
int new_id = -1;
|
||||||
if (!entity->entity->file) {
|
if (!new_entity->entity->file) {
|
||||||
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
|
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
|
||||||
entity->entity->file = this;
|
new_entity->entity->file = this;
|
||||||
new_id = entity->entity->set_id();
|
new_id = new_entity->entity->set_id();
|
||||||
} else {
|
} else {
|
||||||
new_id = entity->entity->id();
|
new_id = new_entity->entity->id();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byid.find(new_id) != byid.end()) {
|
if (byid.find(new_id) != byid.end()) {
|
||||||
@@ -1577,30 +1594,30 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The mapping by entity instance name is updated.
|
// The mapping by entity instance name is updated.
|
||||||
byid[new_id] = entity;
|
byid[new_id] = new_entity;
|
||||||
|
|
||||||
// The mapping by reference is updated.
|
// The mapping by reference is updated.
|
||||||
IfcEntityList::ptr entity_attributes(new IfcEntityList);
|
IfcEntityList::ptr entity_attributes(new IfcEntityList);
|
||||||
try {
|
try {
|
||||||
entity_attributes = traverse(entity, 1);
|
entity_attributes = traverse(new_entity, 1);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
Logger::Error(e);
|
Logger::Error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
|
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
|
||||||
IfcUtil::IfcBaseClass* entity_attribute = *it;
|
IfcUtil::IfcBaseClass* entity_attribute = *it;
|
||||||
if (*it == entity) continue;
|
if (*it == new_entity) continue;
|
||||||
try {
|
try {
|
||||||
if (!IfcSchema::Type::IsSimple(entity_attribute->type())) {
|
if (!IfcSchema::Type::IsSimple(entity_attribute->type())) {
|
||||||
unsigned entity_attribute_id = entity_attribute->entity->id();
|
unsigned entity_attribute_id = entity_attribute->entity->id();
|
||||||
byref[entity_attribute_id].push_back(entity->entity->id());
|
byref[entity_attribute_id].push_back(new_entity->entity->id());
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
Logger::Error(e);
|
Logger::Error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entity;
|
return new_entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
|
void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
|
||||||
|
|||||||
Reference in New Issue
Block a user