mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 02:07:36 +00:00
Fixes crash when initializing an object with the initialize function when some of the attributes are empty, {}, or omitted, std::nullopt
This commit is contained in:
+29
-17
@@ -1651,26 +1651,38 @@ express::base::set_attribute_value(size_t i, const T& t) {
|
|||||||
apply_individual_instance_visitor(current_attribute, (int)i).apply(visitor);
|
apply_individual_instance_visitor(current_attribute, (int)i).apply(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
data()->set_attribute_value(i, t);
|
// A null/empty single instance attribute (e.g. an omitted optional like
|
||||||
auto new_attribute = get_attribute_value(i);
|
// OwnerHistory, ObjectPlacement or Representation) must not be persisted
|
||||||
|
// as a "set" attribute: doing so leaves isNull() false for it afterwards,
|
||||||
// Register inverse indices in file
|
// so generated getters proceed to as<T>() and dereference a null instance.
|
||||||
if constexpr (std::is_same_v<T, express::base> || std::is_same_v<T, std::vector<express::base>> || std::is_same_v<T, std::vector<std::vector<express::base>>>) {
|
// Skip the assignment entirely in that case, same as leaving it unset.
|
||||||
register_inverse_visitor visitor(*file(), *this);
|
bool should_set = true;
|
||||||
apply_individual_instance_visitor(new_attribute, (int)i).apply(visitor);
|
if constexpr (std::is_same_v<T, express::base>) {
|
||||||
|
should_set = static_cast<bool>(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register new attribute guid in guid map
|
if (should_set) {
|
||||||
if (i == 0 && (file()->ifcroot_type() != nullptr) && this->declaration().is(*file()->ifcroot_type())) {
|
data()->set_attribute_value(i, t);
|
||||||
try {
|
auto new_attribute = get_attribute_value(i);
|
||||||
auto guid = (std::string) new_attribute;
|
|
||||||
auto it = file()->internal_guid_map().find(guid);
|
// Register inverse indices in file
|
||||||
if (it != file()->internal_guid_map().end()) {
|
if constexpr (std::is_same_v<T, express::base> || std::is_same_v<T, std::vector<express::base>> || std::is_same_v<T, std::vector<std::vector<express::base>>>) {
|
||||||
file()->logger().warning("Duplicate guid " + guid);
|
register_inverse_visitor visitor(*file(), *this);
|
||||||
|
apply_individual_instance_visitor(new_attribute, (int)i).apply(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register new attribute guid in guid map
|
||||||
|
if (i == 0 && (file()->ifcroot_type() != nullptr) && this->declaration().is(*file()->ifcroot_type())) {
|
||||||
|
try {
|
||||||
|
auto guid = (std::string) new_attribute;
|
||||||
|
auto it = file()->internal_guid_map().find(guid);
|
||||||
|
if (it != file()->internal_guid_map().end()) {
|
||||||
|
file()->logger().warning("Duplicate guid " + guid);
|
||||||
|
}
|
||||||
|
file()->internal_guid_map().insert({guid, *this});
|
||||||
|
} catch (ifcopenshell::exception& e) {
|
||||||
|
file()->logger().error(e);
|
||||||
}
|
}
|
||||||
file()->internal_guid_map().insert({guid, *this});
|
|
||||||
} catch (ifcopenshell::exception& e) {
|
|
||||||
file()->logger().error(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user