mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-31 08:56:34 +00:00
38e0e0e297
entity_instance.file is a property backed by a fresh SWIG wrapper on every access, and ifcopenshell::file had no __eq__, so `self.file != other.file` in entity_instance.__eq__ compared two throwaway wrappers and was always true - even for an instance against itself. Every entity comparison therefore took the deep get_info() branch, making distinct but structurally identical instances compare equal and leaving the final `return False` unreachable. Bonsai's TestAddRepresentationItemToShapeAspect showed this as two separate IfcShapeAspects being treated as one, so the stale aspect was never removed. Restore the file_pointer() pair that was commented out on both ifcopenshell::file and express::Base - IfcParseWrapper.i already described it as the way to "trace file ownership of instances on the python side" - and give file the __eq__/__hash__ it was missing. The express::Base one needs $self->file() now that file_ lives on instance_data. This also repairs rocksdb_lazy_instance.__eq__, which already called file_pointer(). EXPRESS `=` is value comparison and `:=:` is instance comparison, but rule_compiler emits `==` for both (see the @todo on process_rel_op), and derived attributes build their operands in the shared global file, so rules compare same-file instances and need value semantics. Restore those for the duration of rule execution with settings.compare_instances_by_value, alongside the existing unpack_non_aggregate_inverses. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
IfcOpenShell express schema parser and code generator
This folder contains Python code to generate C++ type information based on an Express schema. In particular is has only been tested using recent version of the IFC schema and will most likely fail on any other Express schema.
The code can be invoked in the following way and results in several code outputs
named according to the schema name in the Express file. A python 3 interpreter
with the pyparsing (pip install pyparsing) library is required.
note: Keep in mind that Express is not very suitable for this kind of usage. In the end, (as far as I can tell) no tool is able to read your model, because it doesn't understand the schema as it has no notion of the core part vs the addition.
Command line usage for code generation
The usage for C++ project.
# bootstrap.py express.bnf in ifcopenshell-python.ifcopenshell.express.
>>> python3 bootstrap.py express.bnf > express_parser.py
>>> python3 express_parser.py IFC2X3_TC1.exp header implementation schema_class definitions
The usage for python project.
# code rule generation
# generating 'ifcopenshell.express.rules.IFC2X3_TC1' in ifcopenshell-python.ifcopenshell.express.rules.
# rule_compiler in ifcopenshell-python.ifcopenshell.express.
>>> python -m rule_compiler IFC2X3_TC1.exp
Programmatic usage
import ifcopenshell
import ifcopenshell.express
schema = ifcopenshell.express.parse('IFC.exp')
ifcopenshell.register_schema(schema)
f = ifcopenshell.file(schema=schema.schema.name())
f.createIfcProject(ifcopenshell.guid.new())