mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Implement task quantity sets for parametric quantification
This commit is contained in:
@@ -11,17 +11,22 @@ classes = (
|
||||
operator.AddQto,
|
||||
operator.GuessQuantity,
|
||||
prop.PsetProperties,
|
||||
prop.MaterialPsetProperties,
|
||||
prop.TaskPsetProperties,
|
||||
ui.BIM_PT_object_psets,
|
||||
ui.BIM_PT_object_qtos,
|
||||
ui.BIM_PT_material_psets,
|
||||
ui.BIM_PT_task_qtos,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.Object.PsetProperties = bpy.props.PointerProperty(type=prop.PsetProperties)
|
||||
bpy.types.Material.PsetProperties = bpy.props.PointerProperty(type=prop.PsetProperties)
|
||||
bpy.types.Material.PsetProperties = bpy.props.PointerProperty(type=prop.MaterialPsetProperties)
|
||||
bpy.types.Scene.TaskPsetProperties = bpy.props.PointerProperty(type=prop.TaskPsetProperties)
|
||||
|
||||
|
||||
def unregister():
|
||||
del bpy.types.Object.PsetProperties
|
||||
del bpy.types.Material.PsetProperties
|
||||
del bpy.types.Scene.TaskPsetProperties
|
||||
|
||||
@@ -11,6 +11,30 @@ from ifcopenshell.api.cost.data import Data as CostData
|
||||
from blenderbim.bim.module.pset.qto_calculator import QtoCalculator
|
||||
|
||||
|
||||
def get_pset_props(context, obj, obj_type):
|
||||
if obj_type == "Object":
|
||||
obj = bpy.data.objects.get(obj)
|
||||
return obj.PsetProperties
|
||||
elif obj_type == "Material":
|
||||
obj = bpy.data.materials.get(obj)
|
||||
return obj.PsetProperties
|
||||
elif obj_type == "Task":
|
||||
return context.scene.TaskPsetProperties
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
class TogglePsetExpansion(bpy.types.Operator):
|
||||
bl_idname = "bim.toggle_pset_expansion"
|
||||
bl_label = "Toggle Pset Expansion"
|
||||
@@ -32,11 +56,7 @@ class EnablePsetEditing(bpy.types.Operator):
|
||||
obj_type: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
if self.obj_type == "Object":
|
||||
obj = bpy.data.objects.get(self.obj)
|
||||
elif self.obj_type == "Material":
|
||||
obj = bpy.data.materials.get(self.obj)
|
||||
self.props = obj.PsetProperties
|
||||
self.props = get_pset_props(context, self.obj, self.obj_type)
|
||||
|
||||
while len(self.props.properties) > 0:
|
||||
self.props.properties.remove(0)
|
||||
@@ -138,11 +158,7 @@ class DisablePsetEditing(bpy.types.Operator):
|
||||
obj_type: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
if self.obj_type == "Object":
|
||||
obj = bpy.data.objects.get(self.obj)
|
||||
elif self.obj_type == "Material":
|
||||
obj = bpy.data.materials.get(self.obj)
|
||||
props = obj.PsetProperties
|
||||
props = get_pset_props(context, self.obj, self.obj_type)
|
||||
props.active_pset_id = 0
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -161,12 +177,8 @@ class EditPset(bpy.types.Operator):
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
if self.obj_type == "Object":
|
||||
obj = bpy.data.objects.get(self.obj)
|
||||
elif self.obj_type == "Material":
|
||||
obj = bpy.data.materials.get(self.obj)
|
||||
oprops = obj.BIMObjectProperties
|
||||
props = obj.PsetProperties
|
||||
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)
|
||||
properties = {}
|
||||
|
||||
pset_id = self.pset_id or props.active_pset_id
|
||||
@@ -213,7 +225,7 @@ class EditPset(bpy.types.Operator):
|
||||
},
|
||||
)
|
||||
CostData.purge()
|
||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||
Data.load(IfcStore.get_file(), ifc_definition_id)
|
||||
bpy.ops.bim.disable_pset_editing(obj=self.obj, obj_type=self.obj_type)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -231,20 +243,17 @@ class RemovePset(bpy.types.Operator):
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
if self.obj_type == "Object":
|
||||
obj = bpy.data.objects.get(self.obj)
|
||||
elif self.obj_type == "Material":
|
||||
obj = bpy.data.materials.get(self.obj)
|
||||
props = obj.BIMObjectProperties
|
||||
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)
|
||||
ifcopenshell.api.run(
|
||||
"pset.remove_pset",
|
||||
self.file,
|
||||
**{
|
||||
"product": self.file.by_id(props.ifc_definition_id),
|
||||
"product": self.file.by_id(ifc_definition_id),
|
||||
"pset": self.file.by_id(self.pset_id),
|
||||
},
|
||||
)
|
||||
Data.load(IfcStore.get_file(), props.ifc_definition_id)
|
||||
Data.load(IfcStore.get_file(), ifc_definition_id)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -254,36 +263,24 @@ class AddPset(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
obj: bpy.props.StringProperty()
|
||||
obj_type: bpy.props.StringProperty()
|
||||
pset_name: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
if self.obj_type == "Object":
|
||||
obj = bpy.data.objects.get(self.obj)
|
||||
elif self.obj_type == "Material":
|
||||
obj = bpy.data.materials.get(self.obj)
|
||||
oprops = obj.BIMObjectProperties
|
||||
props = obj.PsetProperties
|
||||
|
||||
if self.pset_name:
|
||||
pset_name = self.pset_name
|
||||
elif self.obj_type == "Object":
|
||||
pset_name = props.pset_name
|
||||
elif self.obj_type == "Material":
|
||||
pset_name = props.material_pset_name
|
||||
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)
|
||||
|
||||
ifcopenshell.api.run(
|
||||
"pset.add_pset",
|
||||
self.file,
|
||||
**{
|
||||
"product": self.file.by_id(oprops.ifc_definition_id),
|
||||
"name": pset_name,
|
||||
"product": self.file.by_id(ifc_definition_id),
|
||||
"name": props.pset_name,
|
||||
},
|
||||
)
|
||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||
Data.load(IfcStore.get_file(), ifc_definition_id)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -291,24 +288,25 @@ class AddQto(bpy.types.Operator):
|
||||
bl_idname = "bim.add_qto"
|
||||
bl_label = "Add Qto"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
obj: bpy.props.StringProperty()
|
||||
obj_type: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
obj = context.active_object
|
||||
oprops = obj.BIMObjectProperties
|
||||
props = obj.PsetProperties
|
||||
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)
|
||||
ifcopenshell.api.run(
|
||||
"pset.add_qto",
|
||||
self.file,
|
||||
**{
|
||||
"product": self.file.by_id(oprops.ifc_definition_id),
|
||||
"product": self.file.by_id(ifc_definition_id),
|
||||
"name": props.qto_name,
|
||||
},
|
||||
)
|
||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||
Data.load(IfcStore.get_file(), ifc_definition_id)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -52,6 +52,15 @@ def getMaterialPsetNames(self, context):
|
||||
return psetnames[ifc_class]
|
||||
|
||||
|
||||
def getTaskQtoNames(self, context):
|
||||
global qtonames
|
||||
ifc_class = "IfcTask"
|
||||
if ifc_class not in qtonames:
|
||||
psets = blenderbim.bim.schema.ifc.psetqto.get_applicable(ifc_class, qto_only=True)
|
||||
qtonames[ifc_class] = [(p.Name, p.Name, "") for p in psets]
|
||||
return qtonames[ifc_class]
|
||||
|
||||
|
||||
def getQtoNames(self, context):
|
||||
global qtonames
|
||||
if "/" in context.active_object.name:
|
||||
@@ -69,4 +78,17 @@ class PsetProperties(PropertyGroup):
|
||||
properties: CollectionProperty(name="Properties", type=Attribute)
|
||||
pset_name: EnumProperty(items=getPsetNames, name="Pset Name")
|
||||
qto_name: EnumProperty(items=getQtoNames, name="Qto Name")
|
||||
material_pset_name: EnumProperty(items=getMaterialPsetNames, name="Pset Name")
|
||||
|
||||
|
||||
class MaterialPsetProperties(PropertyGroup):
|
||||
active_pset_id: IntProperty(name="Active Pset ID")
|
||||
active_pset_name: StringProperty(name="Pset Name")
|
||||
properties: CollectionProperty(name="Properties", type=Attribute)
|
||||
pset_name: EnumProperty(items=getMaterialPsetNames, name="Pset Name")
|
||||
|
||||
|
||||
class TaskPsetProperties(PropertyGroup):
|
||||
active_pset_id: IntProperty(name="Active Pset ID")
|
||||
active_pset_name: StringProperty(name="Pset Name")
|
||||
properties: CollectionProperty(name="Properties", type=Attribute)
|
||||
qto_name: EnumProperty(items=getTaskQtoNames, name="Qto Name")
|
||||
|
||||
@@ -3,6 +3,14 @@ from ifcopenshell.api.pset.data import Data
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
|
||||
def get_active_pset_obj_name(context, obj_type):
|
||||
if obj_type == "Object":
|
||||
return context.active_object.name
|
||||
elif obj_type == "Material":
|
||||
return context.active_object.active_material.name
|
||||
return ""
|
||||
|
||||
|
||||
def draw_psetqto_ui(context, pset_id, pset, props, layout, obj_type):
|
||||
box = layout.box()
|
||||
row = box.row(align=True)
|
||||
@@ -10,29 +18,30 @@ def draw_psetqto_ui(context, pset_id, pset, props, layout, obj_type):
|
||||
pset["is_expanded"] = True
|
||||
icon = "TRIA_DOWN" if pset["is_expanded"] else "TRIA_RIGHT"
|
||||
row.operator("bim.toggle_pset_expansion", icon=icon, text="", emboss=False).pset_id = pset_id
|
||||
obj_name = get_active_pset_obj_name(context, obj_type)
|
||||
if not props.active_pset_id:
|
||||
row.label(text=pset["Name"], icon="COPY_ID")
|
||||
op = row.operator("bim.enable_pset_editing", icon="GREASEPENCIL", text="")
|
||||
op.pset_id = pset_id
|
||||
op.obj = context.active_object.name if obj_type == "Object" else context.active_object.active_material.name
|
||||
op.obj = obj_name
|
||||
op.obj_type = obj_type
|
||||
op = row.operator("bim.remove_pset", icon="X", text="")
|
||||
op.pset_id = pset_id
|
||||
op.obj = context.active_object.name if obj_type == "Object" else context.active_object.active_material.name
|
||||
op.obj = obj_name
|
||||
op.obj_type = obj_type
|
||||
elif props.active_pset_id != pset_id:
|
||||
row.label(text=pset["Name"], icon="COPY_ID")
|
||||
op = row.operator("bim.remove_pset", icon="X", text="")
|
||||
op.pset_id = pset_id
|
||||
op.obj = context.active_object.name if obj_type == "Object" else context.active_object.active_material.name
|
||||
op.obj = obj_name
|
||||
op.obj_type = obj_type
|
||||
elif props.active_pset_id == pset_id:
|
||||
row.prop(props, "active_pset_name", icon="COPY_ID", text="")
|
||||
op = row.operator("bim.edit_pset", icon="CHECKMARK", text="")
|
||||
op.obj = context.active_object.name if obj_type == "Object" else context.active_object.active_material.name
|
||||
op.obj = obj_name
|
||||
op.obj_type = obj_type
|
||||
op = row.operator("bim.disable_pset_editing", icon="CANCEL", text="")
|
||||
op.obj = context.active_object.name if obj_type == "Object" else context.active_object.active_material.name
|
||||
op.obj = obj_name
|
||||
op.obj_type = obj_type
|
||||
if pset["is_expanded"]:
|
||||
if props.active_pset_id == pset_id:
|
||||
@@ -163,7 +172,9 @@ class BIM_PT_object_qtos(Panel):
|
||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "qto_name", text="")
|
||||
row.operator("bim.add_qto", icon="ADD", text="")
|
||||
op = row.operator("bim.add_qto", icon="ADD", text="")
|
||||
op.obj = context.active_object.name
|
||||
op.obj_type = "Object"
|
||||
|
||||
qtos = [(qto_id, Data.qtos[qto_id]) for qto_id in Data.products[oprops.ifc_definition_id]["qtos"]]
|
||||
for qto_id, qto in sorted(qtos, key = lambda v: v[1]["Name"]):
|
||||
@@ -202,7 +213,7 @@ class BIM_PT_material_psets(Panel):
|
||||
if oprops.ifc_definition_id not in Data.products:
|
||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "material_pset_name", text="")
|
||||
row.prop(props, "pset_name", text="")
|
||||
op = row.operator("bim.add_pset", icon="ADD", text="")
|
||||
op.obj = context.active_object.active_material.name
|
||||
op.obj_type = "Material"
|
||||
@@ -210,3 +221,36 @@ class BIM_PT_material_psets(Panel):
|
||||
psets = [(pset_id, Data.psets[pset_id]) for pset_id in Data.products[oprops.ifc_definition_id]["psets"]]
|
||||
for pset_id, pset in sorted(psets, key = lambda v: v[1]["Name"]):
|
||||
draw_psetqto_ui(context, pset_id, pset, props, self.layout, "Material")
|
||||
|
||||
|
||||
class BIM_PT_task_qtos(Panel):
|
||||
bl_label = "IFC Task Quantity Sets"
|
||||
bl_idname = "BIM_PT_task_qtos"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "scene"
|
||||
bl_parent_id = "BIM_PT_work_schedules"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.BIMWorkScheduleProperties
|
||||
total_tasks = len(context.scene.BIMTaskTreeProperties.tasks)
|
||||
if total_tasks > 0 and props.active_task_index < total_tasks:
|
||||
return True
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
props = context.scene.TaskPsetProperties
|
||||
wprops = context.scene.BIMWorkScheduleProperties
|
||||
tprops = context.scene.BIMTaskTreeProperties
|
||||
ifc_definition_id = tprops.tasks[wprops.active_task_index].ifc_definition_id
|
||||
if ifc_definition_id not in Data.products:
|
||||
Data.load(IfcStore.get_file(), ifc_definition_id)
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "qto_name", text="")
|
||||
op = row.operator("bim.add_qto", icon="ADD", text="")
|
||||
op.obj_type = "Task"
|
||||
|
||||
qtos = [(qto_id, Data.qtos[qto_id]) for qto_id in Data.products[ifc_definition_id]["qtos"]]
|
||||
for qto_id, qto in sorted(qtos, key = lambda v: v[1]["Name"]):
|
||||
draw_psetqto_ui(context, qto_id, qto, props, self.layout, "Task")
|
||||
|
||||
Reference in New Issue
Block a user