Two new UX features in the IFC Patch panel, both backed by helpers on
bonsai.tool.Patch.
Lossy-downgrade confirmation popup. When the user picks the Migrate
recipe with a target schema older than the source's (IFC4 -> IFC2X3,
IFC4X3 -> IFC2X3), ExecuteIfcPatch.invoke shows a properties dialog
listing what's preserved vs lost: IfcIndexedPolyCurve flattened with
arcs approximated, IfcPolygonalFaceSet / IfcTriangulatedFaceSet
converted to IfcFacetedBrep, IFC4-only IfcElement subclasses (IfcLamp,
IfcPipeSegment, IfcGeographicElement, ...) demoted to
IfcBuildingElementProxy with the original class + PredefinedType
encoded into ObjectType, and PredefinedType enum values absent from
IFC2X3 dropped. The user explicitly approves before the recipe runs.
The popup is gated on tool.Patch.migration_is_lossy_downgrade() which
resolves the source schema via header-only parsing
(tool.Patch._patch_source_schema reads the first ~2KB and matches a
FILE_SCHEMA regex, then normalises via ifcopenshell.util.schema.
get_fallback_schema). Avoids a full ifcopenshell.open() on every
Execute click — multi-second saving on large files. The target schema
is looked up by argument name rather than position so it survives
recipe-parameter reordering.
Per-recipe preset menu. New BIM_MT_ifc_patch_presets + AddIfcPatchPreset
wire Blender's standard preset system into the panel. Each recipe gets
its own preset subdirectory (bonsai/ifc_patch/<RecipeName>/), so a
preset saved for ExtractElements does not pollute the Migrate preset
list. The preset operator uses Attribute.get_value_name() (single
source of truth for data_type -> storage-field mapping) to build the
preset_values list dynamically per recipe.
The recipe-change callback resets
BIM_MT_ifc_patch_presets.bl_label to the canonical title — Blender's
script.execute_preset mutates the menu's bl_label to the loaded
preset's name as a "currently-selected" indicator, and without an
explicit reset the previous recipe's preset name would falsely advertise
itself in the new recipe's menu.
tool.Patch gains get_preset_subdir, migration_is_lossy_downgrade,
_patch_source_schema as cross-cutting helpers. _SCHEMA_AGE module
constant provides the ordering used by the downgrade-detection
predicate.
Test coverage: 12 bim-lane tests under test/bim/module/patch/. The
truth table for migration_is_lossy_downgrade covers IFC4/IFC4X3 source
x downgrade/upgrade/same-schema target x Migrate/non-Migrate recipe.
The schema-sniffing tests write a real IFC4X3_ADD2 file to disk and
assert the helper resolves it to IFC4X3 (regression for the original
startswith iteration-order bug). An end-to-end test drives
bpy.ops.bim.execute_ifc_patch with an in-memory IfcLamp source and
verifies the on-disk IFC2X3 file contains a single
IfcBuildingElementProxy with ObjectType "IfcLamp/COMPACTFLUORESCENT"
and the original GlobalId preserved.
Generated with the assistance of an AI coding tool.
Demo - https://imgchest.com/p/xny8qvox5yb
You can also now reuse 'bpy.data.texts['globalid-filter-3UvnD5Ml95zBDEcwAkAUIp']' kind of queries from Search in ExtractElements query.
- The patch was failed when executed from Bonsai since self.src wasn't provided, fixed now.
- Added a temporary hack to diplsay file selector for this patch.
- small refactor.