From aa9b2d7428f2b48b7f229c3c2179d54b87b2c22e Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 7 Oct 2024 20:41:34 +0200 Subject: [PATCH] populate_derived() upon instance creation, don't only rely on serialization 'hack' #5364 --- .../ifcopenshell/express/templates.py | 2 +- src/ifcparse/IfcBaseClass.h | 4 +++- src/ifcparse/IfcUtil.cpp | 17 +++++++++++++---- src/ifcwrap/IfcParseWrapper.i | 6 +++++- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/express/templates.py b/src/ifcopenshell-python/ifcopenshell/express/templates.py index c6f8c1096d..031921468d 100644 --- a/src/ifcopenshell-python/ifcopenshell/express/templates.py +++ b/src/ifcopenshell-python/ifcopenshell/express/templates.py @@ -210,7 +210,7 @@ entity_implementation = """// Function implementations for %(name)s const IfcParse::entity& %(schema_name)s::%(name)s::declaration() const { return *((IfcParse::entity*)%(schema_name_upper)s_types[%(index_in_schema)d]); } const IfcParse::entity& %(schema_name)s::%(name)s::Class() { return *((IfcParse::entity*)%(schema_name_upper)s_types[%(index_in_schema)d]); } %(schema_name)s::%(name)s::%(name)s(IfcEntityInstanceData&& e) : %(superclass)s { } -%(schema_name)s::%(name)s::%(name)s(%(constructor_arguments)s) : %(superclass_num_attrs)s { %(constructor_implementation)s } +%(schema_name)s::%(name)s::%(name)s(%(constructor_arguments)s) : %(superclass_num_attrs)s { %(constructor_implementation)s; populate_derived(); } """ # data_ = e; diff --git a/src/ifcparse/IfcBaseClass.h b/src/ifcparse/IfcBaseClass.h index 16ed5d0efe..0226147638 100644 --- a/src/ifcparse/IfcBaseClass.h +++ b/src/ifcparse/IfcBaseClass.h @@ -139,7 +139,7 @@ class IFC_PARSE_API IfcLateBoundEntity : public IfcBaseClass { class IFC_PARSE_API IfcBaseEntity : public IfcBaseClass { public: - IfcBaseEntity(IfcEntityInstanceData&& data) : IfcBaseClass(std::move(data)) {} + IfcBaseEntity(IfcEntityInstanceData&& data); IfcBaseEntity(size_t n) : IfcBaseClass(IfcEntityInstanceData(storage_t(n))) @@ -158,6 +158,8 @@ class IFC_PARSE_API IfcBaseEntity : public IfcBaseClass { boost::shared_ptr get_inverse(const std::string& name) const; unsigned set_id(const boost::optional& i); + + void populate_derived(); }; // TODO: Investigate whether these should be template classes instead diff --git a/src/ifcparse/IfcUtil.cpp b/src/ifcparse/IfcUtil.cpp index 90382b7a69..87f951ae2c 100644 --- a/src/ifcparse/IfcUtil.cpp +++ b/src/ifcparse/IfcUtil.cpp @@ -202,11 +202,20 @@ void IfcUtil::unescape_xml(std::string& str) { boost::replace_all(str, ">", ">"); } -/* -Argument* IfcUtil::IfcBaseEntity::get(const std::string& name) const { - return data().getArgument(declaration().attribute_index(name)); +IfcUtil::IfcBaseEntity::IfcBaseEntity(IfcEntityInstanceData&& data) + : IfcBaseClass(std::move(data)) +{} + +void IfcUtil::IfcBaseEntity::populate_derived() { + for (auto it = declaration().derived().begin(); it != declaration().derived().end(); ++it) { + if (*it) { + this->data().storage_.set( + std::distance(declaration().derived().begin(), it), + Derived{} + ); + } + } } -*/ AttributeValue IfcUtil::IfcBaseEntity::get(const std::string& name) const { diff --git a/src/ifcwrap/IfcParseWrapper.i b/src/ifcwrap/IfcParseWrapper.i index 6252c3af5c..b7af4036bf 100644 --- a/src/ifcwrap/IfcParseWrapper.i +++ b/src/ifcwrap/IfcParseWrapper.i @@ -596,7 +596,11 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas const IfcParse::schema_definition* schema = IfcParse::schema_by_name(schema_identifier); const IfcParse::declaration* decl = schema->declaration_by_name(name); IfcEntityInstanceData data(storage_t(decl->as_entity() ? decl->as_entity()->attribute_count() : 1)); - return schema->instantiate(decl, std::move(data)); + auto inst = schema->instantiate(decl, std::move(data)); + if (auto entinst = inst->as()) { + entinst->populate_derived(); + } + return inst; } %}