Fix tool.Parametric to ship safely on v0.8.0 bim layer

Three corrective fixes folded into one commit. All surface as
addon-load / save-time exceptions on v0.8.0's bim layer because
PR2's tool.Parametric refactor over-committed to the PR4 contract.

1. iter_gizmo_preference_classes — the previous implementation
   returned only the shared GizmoPreferencesFeature class. v0.8.0's
   bim/ui.py declares PointerProperty fields ('door', 'window', ...)
   on GizmoPreferences that point at per-feature
   GizmoPreferences<Name> classes; those must be registered BEFORE
   GizmoPreferences itself. The shared-class-only return broke
   addon registration with:
      'door' PointerProperty could not register (see previous error)
   Restore the v0.8.0 per-feature lookup (iterate EDIT_TYPES, look
   up each GizmoPreferences<Capitalize(name)> on ui_module) and
   keep the shared-class lookup as forward-compat. Tag FIXME(PR5).

2. EDIT_TYPES — drop the array / pipe_segment / duct_segment
   entries from the registry. Their bim.finish_editing_<name>
   operators land with PR4. Registering them in PR2's EDIT_TYPES
   without the operators makes auto-commit-on-save dispatch a
   non-existent finish_op for any object whose
   BIM<Name>Properties.is_editing flag is True, raising:
      RuntimeError: 'bim.finish_editing_array' must be a registered
      tool.Ifc.Operator subclass for undo-safe IFC mutation
   PR4 re-adds the three entries together with their operators.
   Tag FIXME(PR4).

3. tool.Blender.Modifier shim block — upgrade the prose comment to
   a formal FIXME(PR5) marker so the PR5 cleanup sweep finds it via
   grep alongside every other tagged shim site.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Gorgious56
2026-05-27 13:26:21 +02:00
parent 6ec8372378
commit 1c8fad3c13
2 changed files with 28 additions and 13 deletions
+4 -4
View File
@@ -1329,10 +1329,10 @@ class Blender(bonsai.core.tool.Blender):
class Modifier:
# ----------------------------------------------------------------------
# Backward-compat shims for callers still using the pre-refactor API.
# The is_<type> predicates now live on tool.Parametric; the Array helper
# bag now lives on tool.Array. PR4 migrates each caller; these shims
# are removed in PR5's cleanup.
# FIXME(PR5): backward-compat shims for callers still using the
# pre-refactor API. The is_<type> predicates now live on tool.Parametric;
# the Array helper bag now lives on tool.Array. PR4 migrates each caller;
# this whole shim block is removed in PR5's cleanup.
# ----------------------------------------------------------------------
@classmethod
+24 -9
View File
@@ -147,6 +147,11 @@ class Parametric(bonsai.core.tool.Parametric):
self._data.clear()
self._gen = None
# FIXME(PR4): array / pipe_segment / duct_segment land with their
# finish/cancel operators in PR4. Adding them to EDIT_TYPES without those
# operators makes auto-commit-on-save dispatch bim.finish_editing_<name>
# for objects flagged as in-edit, which then raises because the operator
# doesn't exist. PR4 re-adds the three entries together with the operators.
EDIT_TYPES: list[ParametricObject] = [
ParametricObject("door", has_non_editable_path=True, supports_build_edit_lifecycle=True),
ParametricObject("window", has_non_editable_path=True, supports_build_edit_lifecycle=True),
@@ -154,9 +159,6 @@ class Parametric(bonsai.core.tool.Parametric):
ParametricObject("railing", supports_build_edit_lifecycle=True),
ParametricObject("roof", supports_build_edit_lifecycle=True),
ParametricObject("wall"),
ParametricObject("array", supports_build_edit_lifecycle=True),
ParametricObject("pipe_segment", has_non_editable_path=True, supports_build_edit_lifecycle=True),
ParametricObject("duct_segment", has_non_editable_path=True, supports_build_edit_lifecycle=True),
]
# Annotations for the uppercase constants populated from ``EDIT_TYPES`` by
@@ -168,9 +170,6 @@ class Parametric(bonsai.core.tool.Parametric):
RAILING: ClassVar[ParametricObject]
ROOF: ClassVar[ParametricObject]
WALL: ClassVar[ParametricObject]
ARRAY: ClassVar[ParametricObject]
PIPE_SEGMENT: ClassVar[ParametricObject]
DUCT_SEGMENT: ClassVar[ParametricObject]
_geom_generation: int = 0
@@ -389,10 +388,26 @@ class Parametric(bonsai.core.tool.Parametric):
@classmethod
def iter_gizmo_preference_classes(cls, ui_module) -> list[type]:
"""Shared ``GizmoPreferencesFeature`` class as a one-element list, or
empty if absent. Must register before ``GizmoPreferences``."""
"""``GizmoPreferences<Name>`` classes that exist on ``ui_module`` for
every registry entry, plus the shared ``GizmoPreferencesFeature`` if
present. Order matches ``EDIT_TYPES``. Used by ``bim/__init__.py`` to
inject the per-type ``GizmoPreferences<X>`` classes at the correct
point before ``ui.GizmoPreferences``, which references them via
``PointerProperty``."""
# FIXME(PR5): drop the per-feature loop once PR4 consolidates
# bim/ui.py to use a single shared GizmoPreferencesFeature class
# and rewrites GizmoPreferences accordingly. The shared-class
# branch is the forward-compat path; the per-feature loop keeps
# v0.8.0's bim/ui.py working until then.
out: list[type] = []
for feature in cls.EDIT_TYPES:
gpref = getattr(ui_module, f"GizmoPreferences{feature.name.capitalize()}", None)
if gpref is not None:
out.append(gpref)
shared = getattr(ui_module, "GizmoPreferencesFeature", None)
return [shared] if shared is not None else []
if shared is not None:
out.append(shared)
return out
# --- Feature-kind predicates ------------------------------------------------
# One predicate per registered parametric type. Each is total: accepts any