bim.assign_class - use blender operators in a more safe way

Use temp_override or modify selection not to modify some object by accident, because this operator can also be called not from UI but by providing `object` argument.
This commit is contained in:
Andrej730
2025-04-09 17:43:56 +05:00
parent 4d50dce16d
commit 5b15de50b6
2 changed files with 26 additions and 7 deletions
+20 -7
View File
@@ -211,7 +211,11 @@ class AssignClass(bpy.types.Operator, tool.Ifc.Operator):
ifc_context = int(props.contexts or "0") or None
if ifc_context:
ifc_context = tool.Ifc.get().by_id(ifc_context)
active_object = context.active_object
# Manage selection as operator can be called not from UI but using `object` argument.
current_selection = tool.Blender.get_objects_selection(context)
tool.Blender.clear_objects_selection()
for obj in objects:
if obj.mode != "OBJECT":
self.report({"ERROR"}, "Object must be in OBJECT mode to assign class")
@@ -227,14 +231,23 @@ class AssignClass(bpy.types.Operator, tool.Ifc.Operator):
continue
if self.should_add_representation and isinstance(obj.data, bpy.types.Mesh) and obj.data.polygons:
def ensure_single_user_mesh(mesh: bpy.types.Mesh) -> None:
if mesh.users == 1:
return
obj.select_set(True)
# temp_override is not supported.
bpy.ops.object.make_single_user(
object=True, obdata=True, material=False, animation=False, obdata_animation=False
)
obj.select_set(False)
# Apply scale.
if obj.scale != (1, 1, 1):
if obj.data.users > 1:
bpy.ops.object.make_single_user(
object=True, obdata=True, material=False, animation=False, obdata_animation=False
)
ensure_single_user_mesh(obj.data)
is_negative = obj.matrix_world.is_negative
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True, properties=False)
with context.temp_override(selected_editable_objects=[obj]):
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True, properties=False)
# object.transform_apply is losing normals.
if is_negative:
for polygon in obj.data.polygons:
@@ -279,7 +292,7 @@ class AssignClass(bpy.types.Operator, tool.Ifc.Operator):
ifc_representation_class=self.ifc_representation_class,
)
context.view_layer.objects.active = active_object
tool.Blender.set_objects_selection(*current_selection)
class UnlinkObject(bpy.types.Operator, tool.Ifc.Operator):
+6
View File
@@ -655,6 +655,12 @@ class Blender(bonsai.core.tool.Blender):
if active_object:
active_object.select_set(True)
@classmethod
def clear_objects_selection(cls) -> None:
"""Clear objects selection and active object."""
bpy.ops.object.select_all(action="DESELECT")
cls.clear_active_object()
@classmethod
def get_enum_safe(cls, props: bpy.types.PropertyGroup, prop_name: str) -> Union[str, None]:
"""method created for readibility and to avoid console warnings like