Support bulk deletion of psets on selected objects

This commit is contained in:
Dion Moult
2022-09-03 14:32:39 +10:00
parent f9019a4007
commit 557d3429eb
3 changed files with 106 additions and 43 deletions
+21
View File
@@ -138,6 +138,27 @@ def get_enum_items(data, prop_name, context):
return items return items
def get_obj_ifc_definition_id(context, obj, obj_type):
if obj_type == "Object":
return bpy.data.objects.get(obj).BIMObjectProperties.ifc_definition_id
elif obj_type == "Material":
return bpy.data.materials.get(obj).BIMObjectProperties.ifc_definition_id
elif obj_type == "Task":
return context.scene.BIMTaskTreeProperties.tasks[
context.scene.BIMWorkScheduleProperties.active_task_index
].ifc_definition_id
elif obj_type == "Resource":
return context.scene.BIMResourceTreeProperties.resources[
context.scene.BIMResourceProperties.active_resource_index
].ifc_definition_id
elif obj_type == "Profile":
return context.scene.BIMProfileProperties.profiles[
context.scene.BIMProfileProperties.active_profile_index
].ifc_definition_id
elif obj_type == "WorkSchedule":
return context.scene.BIMWorkScheduleProperties.active_work_schedule_id
# hack to close popup # hack to close popup
# https://blender.stackexchange.com/a/202576/130742 # https://blender.stackexchange.com/a/202576/130742
def close_operator_panel(event): def close_operator_panel(event):
@@ -23,6 +23,7 @@ import ifcopenshell.util.unit
import ifcopenshell.util.pset import ifcopenshell.util.pset
import ifcopenshell.util.attribute import ifcopenshell.util.attribute
import blenderbim.bim.schema import blenderbim.bim.schema
import blenderbim.bim.helper
import blenderbim.bim.handler import blenderbim.bim.handler
import blenderbim.tool as tool import blenderbim.tool as tool
import blenderbim.core.pset as core import blenderbim.core.pset as core
@@ -42,11 +43,9 @@ class Operator:
def get_pset_props(context, obj, obj_type): def get_pset_props(context, obj, obj_type):
if obj_type == "Object": if obj_type == "Object":
obj = bpy.data.objects.get(obj) return bpy.data.objects.get(obj).PsetProperties
return obj.PsetProperties
elif obj_type == "Material": elif obj_type == "Material":
obj = bpy.data.materials.get(obj) return bpy.data.materials.get(obj).PsetProperties
return obj.PsetProperties
elif obj_type == "Task": elif obj_type == "Task":
return context.scene.TaskPsetProperties return context.scene.TaskPsetProperties
elif obj_type == "Resource": elif obj_type == "Resource":
@@ -57,29 +56,6 @@ def get_pset_props(context, obj, obj_type):
return context.scene.WorkSchedulePsetProperties return context.scene.WorkSchedulePsetProperties
def get_pset_obj_ifc_definition_id(context, obj, obj_type):
if obj_type == "Object":
obj = bpy.data.objects.get(obj)
return obj.BIMObjectProperties.ifc_definition_id
elif obj_type == "Material":
obj = bpy.data.materials.get(obj)
return obj.BIMObjectProperties.ifc_definition_id
elif obj_type == "Task":
return context.scene.BIMTaskTreeProperties.tasks[
context.scene.BIMWorkScheduleProperties.active_task_index
].ifc_definition_id
elif obj_type == "Resource":
return context.scene.BIMResourceTreeProperties.resources[
context.scene.BIMResourceProperties.active_resource_index
].ifc_definition_id
elif obj_type == "Profile":
return context.scene.BIMProfileProperties.profiles[
context.scene.BIMProfileProperties.active_profile_index
].ifc_definition_id
elif obj_type == "WorkSchedule":
return context.scene.BIMWorkScheduleProperties.active_work_schedule_id
class TogglePsetExpansion(bpy.types.Operator, Operator): class TogglePsetExpansion(bpy.types.Operator, Operator):
bl_idname = "bim.toggle_pset_expansion" bl_idname = "bim.toggle_pset_expansion"
bl_label = "Toggle Pset Expansion" bl_label = "Toggle Pset Expansion"
@@ -102,7 +78,7 @@ class EnablePsetEditing(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.props = get_pset_props(context, self.obj, self.obj_type) self.props = get_pset_props(context, self.obj, self.obj_type)
self.props.properties.clear() self.props.properties.clear()
ifc_definition_id = get_pset_obj_ifc_definition_id(context, self.obj, self.obj_type) ifc_definition_id = blenderbim.bim.helper.get_obj_ifc_definition_id(context, self.obj, self.obj_type)
Data.load(IfcStore.get_file(), ifc_definition_id) Data.load(IfcStore.get_file(), ifc_definition_id)
data = Data.psets if self.pset_id in Data.psets else Data.qtos data = Data.psets if self.pset_id in Data.psets else Data.qtos
pset_data = data[self.pset_id] pset_data = data[self.pset_id]
@@ -243,7 +219,7 @@ class EditPset(bpy.types.Operator, Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
props = get_pset_props(context, self.obj, self.obj_type) props = get_pset_props(context, self.obj, self.obj_type)
ifc_definition_id = get_pset_obj_ifc_definition_id(context, self.obj, self.obj_type) ifc_definition_id = blenderbim.bim.helper.get_obj_ifc_definition_id(context, self.obj, self.obj_type)
properties = {} properties = {}
pset_id = self.pset_id or props.active_pset_id pset_id = self.pset_id or props.active_pset_id
@@ -298,18 +274,24 @@ class RemovePset(bpy.types.Operator, Operator):
obj_type: bpy.props.StringProperty() obj_type: bpy.props.StringProperty()
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() if self.obj_type == "Object":
props = get_pset_props(context, self.obj, self.obj_type) if context.selected_objects:
ifc_definition_id = get_pset_obj_ifc_definition_id(context, self.obj, self.obj_type) objects = [o.name for o in context.selected_objects]
ifcopenshell.api.run( else:
"pset.remove_pset", objects = [context.active_object.name]
self.file, else:
**{ objects = [self.obj]
"product": self.file.by_id(ifc_definition_id), pset_name = tool.Ifc.get().by_id(self.pset_id).Name
"pset": self.file.by_id(self.pset_id), for obj in objects:
}, props = get_pset_props(context, obj, self.obj_type)
) ifc_definition_id = blenderbim.bim.helper.get_obj_ifc_definition_id(context, obj, self.obj_type)
Data.load(IfcStore.get_file(), ifc_definition_id) element = tool.Ifc.get().by_id(ifc_definition_id)
pset = ifcopenshell.util.element.get_psets(element, should_inherit=False).get(pset_name, None)
if pset:
ifcopenshell.api.run(
"pset.remove_pset", tool.Ifc.get(), product=element, pset=tool.Ifc.get().by_id(pset["id"])
)
Data.load(IfcStore.get_file(), ifc_definition_id)
class AddPset(bpy.types.Operator, Operator): class AddPset(bpy.types.Operator, Operator):
@@ -330,7 +312,7 @@ class AddPset(bpy.types.Operator, Operator):
else: else:
objects = [self.obj] objects = [self.obj]
for obj in objects: for obj in objects:
ifc_definition_id = get_pset_obj_ifc_definition_id(context, obj, self.obj_type) ifc_definition_id = blenderbim.bim.helper.get_obj_ifc_definition_id(context, obj, self.obj_type)
if not ifc_definition_id: if not ifc_definition_id:
continue continue
element = tool.Ifc.get().by_id(ifc_definition_id) element = tool.Ifc.get().by_id(ifc_definition_id)
@@ -349,7 +331,7 @@ class AddQto(bpy.types.Operator, Operator):
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
props = get_pset_props(context, self.obj, self.obj_type) props = get_pset_props(context, self.obj, self.obj_type)
ifc_definition_id = get_pset_obj_ifc_definition_id(context, self.obj, self.obj_type) ifc_definition_id = blenderbim.bim.helper.get_obj_ifc_definition_id(context, self.obj, self.obj_type)
ifcopenshell.api.run( ifcopenshell.api.run(
"pset.add_qto", "pset.add_qto",
self.file, self.file,
@@ -1,6 +1,34 @@
@pset @pset
Feature: Pset Feature: Pset
Scenario: Add pset - object
Given an empty IFC project
And I add a cube
And the object "Cube" is selected
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
And the object "IfcWall/Cube" is selected
And I set "active_object.PsetProperties.pset_name" to "Pset_WallCommon"
When I press "bim.add_pset(obj='IfcWall/Cube', obj_type='Object')"
Then nothing happens
Scenario: Add pset - multiple objects
Given an empty IFC project
And I add a cube
And the object "Cube" is selected
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
And the object "IfcWall/Cube" is selected
And I add a cube
And the object "Cube" is selected
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
And the object "IfcWall/Cube" is selected
And additionally the object "IfcWall/Cube.001" is selected
And I set "active_object.PsetProperties.pset_name" to "Pset_WallCommon"
When I press "bim.add_pset(obj='IfcWall/Cube', obj_type='Object')"
Then nothing happens
Scenario: Enable pset editing - object Scenario: Enable pset editing - object
Given an empty IFC project Given an empty IFC project
And I add a cube And I add a cube
@@ -117,3 +145,35 @@ Scenario: Copy property to selected - copy property
And I set "active_object.PsetProperties.properties[2].metadata.string_value" to "Foo" And I set "active_object.PsetProperties.properties[2].metadata.string_value" to "Foo"
When I press "bim.copy_property_to_selection(name='FireRating')" When I press "bim.copy_property_to_selection(name='FireRating')"
Then nothing happens Then nothing happens
Scenario: Remove pset - object
Given an empty IFC project
And I add a cube
And the object "Cube" is selected
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
And the object "IfcWall/Cube" is selected
And I set "active_object.PsetProperties.pset_name" to "Pset_WallCommon"
And I press "bim.add_pset(obj='IfcWall/Cube', obj_type='Object')"
And the variable "pset" is "{ifc}.by_type('IfcPropertySet')[-1].id()"
When I press "bim.remove_pset(pset_id={pset}, obj='IfcWall/Cube', obj_type='Object')"
Then nothing happens
Scenario: Remove pset - multiple objects
Given an empty IFC project
And I add a cube
And the object "Cube" is selected
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
And the object "IfcWall/Cube" is selected
And I add a cube
And the object "Cube" is selected
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
And the object "IfcWall/Cube" is selected
And additionally the object "IfcWall/Cube.001" is selected
And I set "active_object.PsetProperties.pset_name" to "Pset_WallCommon"
And I press "bim.add_pset(obj='IfcWall/Cube', obj_type='Object')"
And the variable "pset" is "{ifc}.by_type('IfcPropertySet')[-1].id()"
When I press "bim.remove_pset(pset_id={pset}, obj='IfcWall/Cube', obj_type='Object')"
Then nothing happens