mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Door modifier operators now apply to all elligible selected objects. This makes it way easier to modify a single attribute in several unrelated parametric doors thanks to the ALT + input feature from vanilla Blender. This allows for mass-removing, mass-removing, mass-editing, mass-validating, and mass-cancelling edition of door modifiers.
Also allow UNDO for some door operators which seems like they should support it And Fix #5937 : minor typo
This commit is contained in:
@@ -155,7 +155,7 @@ class AddMaterial(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
class DuplicateMaterial(bpy.types.Operator, tool.Ifc.Operator):
|
class DuplicateMaterial(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.duplicate_material"
|
bl_idname = "bim.duplicate_material"
|
||||||
bl_label = "Diplicate Material"
|
bl_label = "Duplicate Material"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
material: bpy.props.IntProperty(name="Material ID")
|
material: bpy.props.IntProperty(name="Material ID")
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ import collections
|
|||||||
V_ = tool.Blender.V_
|
V_ = tool.Blender.V_
|
||||||
|
|
||||||
|
|
||||||
def update_door_modifier_representation(context: bpy.types.Context) -> None:
|
def update_door_modifier_representation(obj: bpy.types.Object) -> None:
|
||||||
obj = context.active_object
|
|
||||||
props = obj.BIMDoorProperties
|
props = obj.BIMDoorProperties
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
@@ -546,11 +545,10 @@ class BIM_OT_add_door(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
class AddDoor(bpy.types.Operator, tool.Ifc.Operator):
|
class AddDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.add_door"
|
bl_idname = "bim.add_door"
|
||||||
bl_label = "Add Door"
|
bl_label = "Add Door"
|
||||||
bl_description = "Add Bonsai parametric door to the active IFC element"
|
bl_description = "Add a Parametric Door to the Selected IFC Door Elements"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def add_door_on_object(self, obj):
|
||||||
obj = context.active_object
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
props = obj.BIMDoorProperties
|
props = obj.BIMDoorProperties
|
||||||
|
|
||||||
@@ -571,18 +569,25 @@ class AddDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
pset=pset,
|
pset=pset,
|
||||||
properties={"Data": tool.Ifc.get().createIfcText(json.dumps(door_data, default=list))},
|
properties={"Data": tool.Ifc.get().createIfcText(json.dumps(door_data, default=list))},
|
||||||
)
|
)
|
||||||
update_door_modifier_representation(context)
|
update_door_modifier_representation(obj)
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
for obj in context.selected_objects:
|
||||||
|
if not tool.Blender.Modifier.is_eligible_for_door_modifier(obj):
|
||||||
|
continue
|
||||||
|
self.add_door_on_object(obj)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class CancelEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
class CancelEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.cancel_editing_door"
|
bl_idname = "bim.cancel_editing_door"
|
||||||
bl_label = "Cancel Editing Door"
|
bl_label = "Cancel Editing Door on Selected Objects"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def cancel_editing_door_on_object(self, obj, element):
|
||||||
obj = context.active_object
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if not tool.Blender.Modifier.is_door(element):
|
||||||
|
return
|
||||||
props = obj.BIMDoorProperties
|
props = obj.BIMDoorProperties
|
||||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
||||||
data.update(data.pop("lining_properties"))
|
data.update(data.pop("lining_properties"))
|
||||||
@@ -603,17 +608,22 @@ class CancelEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
)
|
)
|
||||||
|
|
||||||
props.is_editing = False
|
props.is_editing = False
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
for obj in context.selected_objects:
|
||||||
|
self.cancel_editing_door_on_object(obj)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class FinishEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
class FinishEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.finish_editing_door"
|
bl_idname = "bim.finish_editing_door"
|
||||||
bl_label = "Finish Editing Door"
|
bl_label = "Finish Editing Door on Selected Objects"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def finish_editing_door_on_object(self, obj):
|
||||||
obj = context.active_object
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if not tool.Blender.Modifier.is_door(element):
|
||||||
|
return
|
||||||
props = obj.BIMDoorProperties
|
props = obj.BIMDoorProperties
|
||||||
|
|
||||||
door_data = props.get_general_kwargs(convert_to_project_units=True)
|
door_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||||
@@ -625,45 +635,54 @@ class FinishEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
props.is_editing = False
|
props.is_editing = False
|
||||||
|
|
||||||
update_door_modifier_representation(context)
|
update_door_modifier_representation(obj)
|
||||||
|
|
||||||
pset = tool.Pset.get_element_pset(element, "BBIM_Door")
|
pset = tool.Pset.get_element_pset(element, "BBIM_Door")
|
||||||
door_data = tool.Ifc.get().createIfcText(json.dumps(door_data, default=list))
|
door_data = tool.Ifc.get().createIfcText(json.dumps(door_data, default=list))
|
||||||
ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": door_data})
|
ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Data": door_data})
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
for obj in context.selected_objects:
|
||||||
|
self.finish_editing_door_on_object(obj)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.enable_editing_door"
|
bl_idname = "bim.enable_editing_door"
|
||||||
bl_label = "Enable Editing Door"
|
bl_label = "Enable Editing Door on Selected Objects"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
obj = context.active_object
|
for obj in context.selected_objects:
|
||||||
props = obj.BIMDoorProperties
|
props = obj.BIMDoorProperties
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
if not tool.Blender.Modifier.is_door(element):
|
||||||
data.update(data.pop("lining_properties"))
|
continue
|
||||||
data.update(data.pop("panel_properties"))
|
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
||||||
|
data.update(data.pop("lining_properties"))
|
||||||
|
data.update(data.pop("panel_properties"))
|
||||||
|
|
||||||
# required since we could load pset from .ifc and BIMDoorProperties won't be set
|
# required since we could load pset from .ifc and BIMDoorProperties won't be set
|
||||||
props.set_props_kwargs_from_ifc_data(data)
|
props.set_props_kwargs_from_ifc_data(data)
|
||||||
props.is_editing = True
|
props.is_editing = True
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class RemoveDoor(bpy.types.Operator, tool.Ifc.Operator):
|
class RemoveDoor(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.remove_door"
|
bl_idname = "bim.remove_door"
|
||||||
bl_label = "Remove Door"
|
bl_label = "Remove Door on Selected Objects"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def remove_door_on_object(self, obj):
|
||||||
obj = context.active_object
|
|
||||||
props = obj.BIMDoorProperties
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if not tool.Blender.Modifier.is_door(element):
|
||||||
|
return
|
||||||
obj.BIMDoorProperties.is_editing = False
|
obj.BIMDoorProperties.is_editing = False
|
||||||
|
|
||||||
pset = tool.Pset.get_element_pset(element, "BBIM_Door")
|
pset = tool.Pset.get_element_pset(element, "BBIM_Door")
|
||||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset)
|
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset)
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
for obj in context.selected_objects:
|
||||||
|
self.remove_door_on_object(obj)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
Reference in New Issue
Block a user