mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 06:48:30 +00:00
Migrate Modifier shim callers + drop the shim block
Completes the PR4/PR5 cleanup the FIXME at tool/blender.py
flagged: every is_<type> / Array.<helper> shim on
tool.Blender.Modifier delegated one-for-one to tool.Parametric /
tool.Array. Callers now reach the canonical home directly, and the
shim block — seven is_<type> classmethods plus the inner class Array
— comes out.
Renames (no semantic change):
* tool.Blender.Modifier.is_<door|railing|roof|stair|wall|window>
→ tool.Parametric.is_<x>
13 sites across tool/loader.py, bim/import_ifc.py,
bim/module/geometry/{data,operator}.py, bim/module/model/{door,
railing,roof,stair,ui,wall,window}.py.
* tool.Blender.Modifier.Array.<helper> → tool.Array.<helper>
4 sites across tool/root.py, bim/import_ifc.py,
bim/module/geometry/operator.py.
* test_parametric_registry.py: the two getattr probes that hunt
predicates by name now look on tool.Parametric. Docstring + the
test function name (test_every_entry_has_modifier_predicate →
test_every_entry_has_parametric_predicate) follow the move.
Kept on tool.Blender.Modifier (non-shim, no equivalent on
tool.Parametric): try_applying_edit_mode,
try_canceling_editing_modifier_parameters_or_path,
is_eligible_for_<x>_modifier (×5), is_array_child, is_slab.
Verified: 109 model-lane tests + 8 parametric-registry tests pass
(the one pre-existing failure in test_wall_header_refresh.py is
unrelated — it patches handler.update_bim_tool_props which has been
renamed). git grep for tool\.Blender\.Modifier\.(is_<type>|Array\.)
returns empty. black + ruff clean on every touched file.
Generated with the assistance of an AI coding tool.
This commit is contained in:
committed by
Thomas Krijnen
parent
0c8b6e93c6
commit
d71856d884
@@ -1215,8 +1215,8 @@ class IfcImporter:
|
|||||||
if element not in elements_to_import:
|
if element not in elements_to_import:
|
||||||
continue
|
continue
|
||||||
for i in range(len(data)):
|
for i in range(len(data)):
|
||||||
tool.Blender.Modifier.Array.set_children_lock_state(element, i, True)
|
tool.Array.set_children_lock_state(element, i, True)
|
||||||
tool.Blender.Modifier.Array.constrain_children_to_parent(element)
|
tool.Array.constrain_children_to_parent(element)
|
||||||
|
|
||||||
def update_linked_aggregates(self):
|
def update_linked_aggregates(self):
|
||||||
# TODO Remove this after a while. See commit 17d6b8a
|
# TODO Remove this after a while. See commit 17d6b8a
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ class ViewportData:
|
|||||||
modes.append(edit_mode)
|
modes.append(edit_mode)
|
||||||
elif element.is_a("IfcGridAxis"):
|
elif element.is_a("IfcGridAxis"):
|
||||||
modes.append(edit_mode)
|
modes.append(edit_mode)
|
||||||
elif tool.Blender.Modifier.is_roof(element):
|
elif tool.Parametric.is_roof(element):
|
||||||
modes.append(edit_mode)
|
modes.append(edit_mode)
|
||||||
elif tool.Blender.Modifier.is_railing(element):
|
elif tool.Parametric.is_railing(element):
|
||||||
modes.append(edit_mode)
|
modes.append(edit_mode)
|
||||||
elif item_mode not in modes:
|
elif item_mode not in modes:
|
||||||
modes.append(item_mode)
|
modes.append(item_mode)
|
||||||
|
|||||||
@@ -1024,10 +1024,10 @@ class OverrideDelete(bpy.types.Operator):
|
|||||||
|
|
||||||
for array_parent in array_parents:
|
for array_parent in array_parents:
|
||||||
array_parent_obj = tool.Ifc.get_object(array_parent)
|
array_parent_obj = tool.Ifc.get_object(array_parent)
|
||||||
data = [(i, data) for i, data in enumerate(tool.Blender.Modifier.Array.get_modifiers_data(array_parent))]
|
data = [(i, data) for i, data in enumerate(tool.Array.get_modifiers_data(array_parent))]
|
||||||
# NOTE: there is a way to remove arrays more precisely but it's more complex
|
# NOTE: there is a way to remove arrays more precisely but it's more complex
|
||||||
for i, modifier_data in reversed(data):
|
for i, modifier_data in reversed(data):
|
||||||
children = set(tool.Blender.Modifier.Array.get_children_objects(modifier_data))
|
children = set(tool.Array.get_children_objects(modifier_data))
|
||||||
if children.issubset(selected_objects):
|
if children.issubset(selected_objects):
|
||||||
with context.temp_override(active_object=array_parent_obj):
|
with context.temp_override(active_object=array_parent_obj):
|
||||||
bpy.ops.bim.remove_array(item=i)
|
bpy.ops.bim.remove_array(item=i)
|
||||||
@@ -2494,9 +2494,9 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
profile = tool.Ifc.get().by_id(profile_id)
|
profile = tool.Ifc.get().by_id(profile_id)
|
||||||
if tool.Ifc.get_object(profile): # We are editing an arbitrary profile
|
if tool.Ifc.get_object(profile): # We are editing an arbitrary profile
|
||||||
bpy.ops.bim.edit_arbitrary_profile()
|
bpy.ops.bim.edit_arbitrary_profile()
|
||||||
elif tool.Blender.Modifier.is_railing(element):
|
elif tool.Parametric.is_railing(element):
|
||||||
bpy.ops.bim.finish_editing_railing_path()
|
bpy.ops.bim.finish_editing_railing_path()
|
||||||
elif tool.Blender.Modifier.is_roof(element):
|
elif tool.Parametric.is_roof(element):
|
||||||
bpy.ops.bim.finish_editing_roof_path()
|
bpy.ops.bim.finish_editing_roof_path()
|
||||||
elif tool.Model.get_usage_type(element) == "PROFILE":
|
elif tool.Model.get_usage_type(element) == "PROFILE":
|
||||||
bpy.ops.bim.edit_extrusion_axis()
|
bpy.ops.bim.edit_extrusion_axis()
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ class _DoorEditMixin(FeatureModifierEditMixin):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _is_element_type(cls, element):
|
def _is_element_type(cls, element):
|
||||||
return tool.Blender.Modifier.is_door(element)
|
return tool.Parametric.is_door(element)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_props(cls, obj: bpy.types.Object):
|
def _get_props(cls, obj: bpy.types.Object):
|
||||||
@@ -629,7 +629,7 @@ class RemoveDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
def remove_door_on_object(self, obj: bpy.types.Object) -> None:
|
def remove_door_on_object(self, obj: bpy.types.Object) -> None:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
assert element
|
assert element
|
||||||
if not tool.Blender.Modifier.is_door(element):
|
if not tool.Parametric.is_door(element):
|
||||||
return
|
return
|
||||||
props = tool.Model.get_door_props(obj)
|
props = tool.Model.get_door_props(obj)
|
||||||
props.is_editing = False
|
props.is_editing = False
|
||||||
@@ -691,7 +691,7 @@ class ToggleDoorSwing(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
if not element:
|
if not element:
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
is_door = tool.Blender.Modifier.is_door(element)
|
is_door = tool.Parametric.is_door(element)
|
||||||
|
|
||||||
if self.flip_geometry:
|
if self.flip_geometry:
|
||||||
tool.Geometry.flip_object(obj, self.flip_local_axes)
|
tool.Geometry.flip_object(obj, self.flip_local_axes)
|
||||||
@@ -874,7 +874,7 @@ class GizmoDoorEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_element_type(cls, element: ifcopenshell.entity_instance) -> bool:
|
def is_element_type(cls, element: ifcopenshell.entity_instance) -> bool:
|
||||||
return tool.Blender.Modifier.is_door(element)
|
return tool.Parametric.is_door(element)
|
||||||
|
|
||||||
def get_icon_y_extent(self, props: "BIMDoorProperties") -> tuple[float, float]:
|
def get_icon_y_extent(self, props: "BIMDoorProperties") -> tuple[float, float]:
|
||||||
"""Get Y extents for door icon positioning.
|
"""Get Y extents for door icon positioning.
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ class _RailingEditMixin(PathPreservingEditMixin):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _is_element_type(cls, element):
|
def _is_element_type(cls, element):
|
||||||
return tool.Blender.Modifier.is_railing(element)
|
return tool.Parametric.is_railing(element)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_props(cls, obj: bpy.types.Object):
|
def _get_props(cls, obj: bpy.types.Object):
|
||||||
|
|||||||
@@ -631,7 +631,7 @@ class _RoofEditMixin(PathPreservingEditMixin):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _is_element_type(cls, element):
|
def _is_element_type(cls, element):
|
||||||
return tool.Blender.Modifier.is_roof(element)
|
return tool.Parametric.is_roof(element)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_props(cls, obj: bpy.types.Object):
|
def _get_props(cls, obj: bpy.types.Object):
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ class GizmoStairEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_element_type(cls, element: ifcopenshell.entity_instance) -> bool:
|
def is_element_type(cls, element: ifcopenshell.entity_instance) -> bool:
|
||||||
return tool.Blender.Modifier.is_stair(element)
|
return tool.Parametric.is_stair(element)
|
||||||
|
|
||||||
def setup_element_specific_gizmos(self, context: bpy.types.Context) -> None:
|
def setup_element_specific_gizmos(self, context: bpy.types.Context) -> None:
|
||||||
"""Create the total-length lock as an open/closed pair plus the
|
"""Create the total-length lock as an open/closed pair plus the
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ class BIM_PT_wall(bpy.types.Panel):
|
|||||||
if not obj:
|
if not obj:
|
||||||
return False
|
return False
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
return bool(element) and tool.Blender.Modifier.is_wall(element)
|
return bool(element) and tool.Parametric.is_wall(element)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
|
|||||||
@@ -1939,7 +1939,7 @@ class GizmoWallEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_element_type(cls, element: ifcopenshell.entity_instance) -> bool:
|
def is_element_type(cls, element: ifcopenshell.entity_instance) -> bool:
|
||||||
return tool.Blender.Modifier.is_wall(element)
|
return tool.Parametric.is_wall(element)
|
||||||
|
|
||||||
def get_icon_y_extent(self, props: "BIMWallProperties") -> tuple[float, float]:
|
def get_icon_y_extent(self, props: "BIMWallProperties") -> tuple[float, float]:
|
||||||
far = props.offset + props.thickness + 2 * self.GIZMO_OFFSET
|
far = props.offset + props.thickness + 2 * self.GIZMO_OFFSET
|
||||||
@@ -3416,7 +3416,7 @@ class GizmoWallJoinIntersection(bpy.types.GizmoGroup, _WallGeomCachedBillboardin
|
|||||||
return False
|
return False
|
||||||
for o in selected:
|
for o in selected:
|
||||||
element = tool.Ifc.get_entity(o)
|
element = tool.Ifc.get_entity(o)
|
||||||
if not element or not tool.Blender.Modifier.is_wall(element):
|
if not element or not tool.Parametric.is_wall(element):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ class _WindowEditMixin(FeatureModifierEditMixin):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _is_element_type(cls, element):
|
def _is_element_type(cls, element):
|
||||||
return tool.Blender.Modifier.is_window(element)
|
return tool.Parametric.is_window(element)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_props(cls, obj: bpy.types.Object):
|
def _get_props(cls, obj: bpy.types.Object):
|
||||||
@@ -750,7 +750,7 @@ class GizmoWindowEdition(bpy.types.GizmoGroup, gizmo.BaseParametricGizmoGroup):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_element_type(cls, element: ifcopenshell.entity_instance) -> bool:
|
def is_element_type(cls, element: ifcopenshell.entity_instance) -> bool:
|
||||||
return tool.Blender.Modifier.is_window(element)
|
return tool.Parametric.is_window(element)
|
||||||
|
|
||||||
def get_icon_y_extent(self, props: "BIMWindowProperties") -> tuple[float, float]:
|
def get_icon_y_extent(self, props: "BIMWindowProperties") -> tuple[float, float]:
|
||||||
"""Get Y extents for window icon positioning.
|
"""Get Y extents for window icon positioning.
|
||||||
|
|||||||
@@ -1332,78 +1332,6 @@ class Blender(bonsai.core.tool.Blender):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
class Modifier:
|
class Modifier:
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# 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
|
|
||||||
def is_door(cls, element: entity_instance) -> bool:
|
|
||||||
return tool.Parametric.is_door(element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_railing(cls, element: entity_instance) -> bool:
|
|
||||||
return tool.Parametric.is_railing(element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_roof(cls, element: entity_instance) -> bool:
|
|
||||||
return tool.Parametric.is_roof(element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_stair(cls, element: entity_instance) -> bool:
|
|
||||||
return tool.Parametric.is_stair(element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_wall(cls, element: entity_instance) -> bool:
|
|
||||||
return tool.Parametric.is_wall(element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_window(cls, element: entity_instance) -> bool:
|
|
||||||
return tool.Parametric.is_window(element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_array(cls, element: entity_instance) -> bool:
|
|
||||||
return tool.Parametric.is_array(element)
|
|
||||||
|
|
||||||
class Array:
|
|
||||||
@classmethod
|
|
||||||
def bake_children_transform(cls, parent_element: ifcopenshell.entity_instance, item: int) -> None:
|
|
||||||
tool.Array.bake_children_transform(parent_element, item)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def constrain_children_to_parent(cls, parent_element: ifcopenshell.entity_instance) -> None:
|
|
||||||
tool.Array.constrain_children_to_parent(parent_element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_all_children_objects(cls, parent_element: ifcopenshell.entity_instance) -> list:
|
|
||||||
return tool.Array.get_all_children_objects(parent_element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_all_objects(cls, parent_element: ifcopenshell.entity_instance) -> list:
|
|
||||||
return tool.Array.get_all_objects(parent_element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_children_objects(cls, modifier_data: dict) -> list:
|
|
||||||
return tool.Array.get_children_objects(modifier_data)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_modifiers_data(cls, parent_element: ifcopenshell.entity_instance):
|
|
||||||
return tool.Array.get_modifiers_data(parent_element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def remove_constraints(cls, parent_element: ifcopenshell.entity_instance) -> None:
|
|
||||||
tool.Array.remove_constraints(parent_element)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def set_children_lock_state(
|
|
||||||
cls, parent_element: ifcopenshell.entity_instance, item: int, lock: bool
|
|
||||||
) -> None:
|
|
||||||
tool.Array.set_children_lock_state(parent_element, item, lock)
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def try_applying_edit_mode(cls, obj: bpy.types.Object, element: entity_instance) -> bool:
|
def try_applying_edit_mode(cls, obj: bpy.types.Object, element: entity_instance) -> bool:
|
||||||
"""Tries to validate the current BIM modifier parameters for the active object
|
"""Tries to validate the current BIM modifier parameters for the active object
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ class Root(bonsai.core.tool.Root):
|
|||||||
# Make sure that the array children also get reassigned to the correct aggregate
|
# Make sure that the array children also get reassigned to the correct aggregate
|
||||||
pset = ifcopenshell.util.element.get_pset(new[0], "BBIM_Array")
|
pset = ifcopenshell.util.element.get_pset(new[0], "BBIM_Array")
|
||||||
if pset:
|
if pset:
|
||||||
array_children = tool.Blender.Modifier.Array.get_all_children_objects(new[0])
|
array_children = tool.Array.get_all_children_objects(new[0])
|
||||||
for obj in array_children:
|
for obj in array_children:
|
||||||
bonsai.core.aggregate.assign_object(
|
bonsai.core.aggregate.assign_object(
|
||||||
tool.Ifc,
|
tool.Ifc,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ will ship.
|
|||||||
These tests pin the registry-to-runtime contract: for every entry the operator
|
These tests pin the registry-to-runtime contract: for every entry the operator
|
||||||
``bl_idname``s resolve to registered ``bpy.ops.bim.*`` callables, the
|
``bl_idname``s resolve to registered ``bpy.ops.bim.*`` callables, the
|
||||||
``PropertyGroup`` class is attached to ``bpy.types.Object``, and the per-type
|
``PropertyGroup`` class is attached to ``bpy.types.Object``, and the per-type
|
||||||
predicate exists on `tool.Blender.Modifier`."""
|
predicate exists on `tool.Parametric`."""
|
||||||
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
@@ -82,11 +82,11 @@ def test_every_entry_has_property_group_attached(registry):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_every_entry_has_modifier_predicate(registry):
|
def test_every_entry_has_parametric_predicate(registry):
|
||||||
from bonsai import tool
|
from bonsai import tool
|
||||||
|
|
||||||
missing = [e.name for e in registry if getattr(tool.Blender.Modifier, f"is_{e.name}", None) is None]
|
missing = [e.name for e in registry if getattr(tool.Parametric, f"is_{e.name}", None) is None]
|
||||||
assert not missing, f"tool.Blender.Modifier missing is_<name> predicates: {missing}"
|
assert not missing, f"tool.Parametric missing is_<name> predicates: {missing}"
|
||||||
|
|
||||||
|
|
||||||
def test_every_predicate_does_not_raise_on_non_matching_element(registry):
|
def test_every_predicate_does_not_raise_on_non_matching_element(registry):
|
||||||
@@ -109,7 +109,7 @@ def test_every_predicate_does_not_raise_on_non_matching_element(registry):
|
|||||||
|
|
||||||
raised = []
|
raised = []
|
||||||
for feature in registry:
|
for feature in registry:
|
||||||
predicate = getattr(tool.Blender.Modifier, f"is_{feature.name}", None)
|
predicate = getattr(tool.Parametric, f"is_{feature.name}", None)
|
||||||
if predicate is None:
|
if predicate is None:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user