mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
Support editing profile set usage attributes cardinal point and reference extent. Thanks Jesusbill!
This commit is contained in:
@@ -2,6 +2,7 @@ import bpy
|
|||||||
import json
|
import json
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
import ifcopenshell.util.attribute
|
import ifcopenshell.util.attribute
|
||||||
|
import blenderbim.bim.helper
|
||||||
from blenderbim.bim.module.material.prop import purge as material_prop_purge
|
from blenderbim.bim.module.material.prop import purge as material_prop_purge
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from ifcopenshell.api.material.data import Data
|
from ifcopenshell.api.material.data import Data
|
||||||
@@ -26,7 +27,7 @@ class AssignParameterizedProfile(bpy.types.Operator):
|
|||||||
ifcopenshell.api.run(
|
ifcopenshell.api.run(
|
||||||
"material.assign_profile",
|
"material.assign_profile",
|
||||||
self.file,
|
self.file,
|
||||||
**{"material_profile": self.file.by_id(self.material_profile), "profile": profile}
|
**{"material_profile": self.file.by_id(self.material_profile), "profile": profile},
|
||||||
)
|
)
|
||||||
Data.load_profiles()
|
Data.load_profiles()
|
||||||
ProfileData.load(self.file)
|
ProfileData.load(self.file)
|
||||||
@@ -175,9 +176,7 @@ class RemoveProfile(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
|
obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
|
||||||
self.file = IfcStore.get_file()
|
self.file = IfcStore.get_file()
|
||||||
ifcopenshell.api.run(
|
ifcopenshell.api.run("material.remove_profile", self.file, **{"profile": self.file.by_id(self.profile)})
|
||||||
"material.remove_profile", self.file, **{"profile": self.file.by_id(self.profile)}
|
|
||||||
)
|
|
||||||
Data.load_profiles()
|
Data.load_profiles()
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
@@ -313,20 +312,28 @@ class EnableEditingAssignedMaterial(bpy.types.Operator):
|
|||||||
elif product_data["type"] == "IfcMaterialLayerSet":
|
elif product_data["type"] == "IfcMaterialLayerSet":
|
||||||
material_set_data = Data.layer_sets[product_data["id"]]
|
material_set_data = Data.layer_sets[product_data["id"]]
|
||||||
elif product_data["type"] == "IfcMaterialLayerSetUsage":
|
elif product_data["type"] == "IfcMaterialLayerSetUsage":
|
||||||
layer_set_usage = Data.layer_set_usages[product_data["id"]]
|
material_set_usage = Data.layer_set_usages[product_data["id"]]
|
||||||
material_set_data = Data.layer_sets[layer_set_usage["ForLayerSet"]]
|
material_set_data = Data.layer_sets[material_set_usage["ForLayerSet"]]
|
||||||
material_set_class = "IfcMaterialLayerSet"
|
material_set_class = "IfcMaterialLayerSet"
|
||||||
elif product_data["type"] == "IfcMaterialProfileSet":
|
elif product_data["type"] == "IfcMaterialProfileSet":
|
||||||
material_set_data = Data.profile_sets[product_data["id"]]
|
material_set_data = Data.profile_sets[product_data["id"]]
|
||||||
elif product_data["type"] == "IfcMaterialProfileSetUsage":
|
elif product_data["type"] == "IfcMaterialProfileSetUsage":
|
||||||
profile_set_usage = Data.profile_set_usages[product_data["id"]]
|
material_set_usage = Data.profile_set_usages[product_data["id"]]
|
||||||
material_set_data = Data.profile_sets[profile_set_usage["ForProfileSet"]]
|
material_set_data = Data.profile_sets[material_set_usage["ForProfileSet"]]
|
||||||
material_set_class = "IfcMaterialProfileSet"
|
material_set_class = "IfcMaterialProfileSet"
|
||||||
elif product_data["type"] == "IfcMaterialList":
|
elif product_data["type"] == "IfcMaterialList":
|
||||||
material_set_data = Data.lists[product_data["id"]]
|
material_set_data = Data.lists[product_data["id"]]
|
||||||
else:
|
else:
|
||||||
material_set_data = {}
|
material_set_data = {}
|
||||||
|
|
||||||
|
while len(props.material_set_usage_attributes) > 0:
|
||||||
|
props.material_set_usage_attributes.remove(0)
|
||||||
|
|
||||||
|
if "Usage" in product_data["type"]:
|
||||||
|
blenderbim.bim.helper.import_attributes(
|
||||||
|
product_data["type"], props.material_set_usage_attributes, material_set_usage, self.import_attributes
|
||||||
|
)
|
||||||
|
|
||||||
while len(props.material_set_attributes) > 0:
|
while len(props.material_set_attributes) > 0:
|
||||||
props.material_set_attributes.remove(0)
|
props.material_set_attributes.remove(0)
|
||||||
|
|
||||||
@@ -340,6 +347,36 @@ class EnableEditingAssignedMaterial(bpy.types.Operator):
|
|||||||
new.string_value = "" if new.is_null else material_set_data[attribute.name()]
|
new.string_value = "" if new.is_null else material_set_data[attribute.name()]
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def import_attributes(self, name, prop, data):
|
||||||
|
if name == "CardinalPoint":
|
||||||
|
# TODO: complain to buildingSMART
|
||||||
|
cardinal_point_map = {
|
||||||
|
1: "bottom left",
|
||||||
|
2: "bottom centre",
|
||||||
|
3: "bottom right",
|
||||||
|
4: "mid-depth left",
|
||||||
|
5: "mid-depth centre",
|
||||||
|
6: "mid-depth right",
|
||||||
|
7: "top left",
|
||||||
|
8: "top centre",
|
||||||
|
9: "top right",
|
||||||
|
10: "geometric centroid",
|
||||||
|
11: "bottom in line with the geometric centroid",
|
||||||
|
12: "left in line with the geometric centroid",
|
||||||
|
13: "right in line with the geometric centroid",
|
||||||
|
14: "top in line with the geometric centroid",
|
||||||
|
15: "shear centre",
|
||||||
|
16: "bottom in line with the shear centre",
|
||||||
|
17: "left in line with the shear centre",
|
||||||
|
18: "right in line with the shear centre",
|
||||||
|
19: "top in line with the shear centre",
|
||||||
|
}
|
||||||
|
prop.data_type = "enum"
|
||||||
|
prop.enum_items = json.dumps(cardinal_point_map)
|
||||||
|
if data[name]:
|
||||||
|
prop.enum_value = str(data[name])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class DisableEditingAssignedMaterial(bpy.types.Operator):
|
class DisableEditingAssignedMaterial(bpy.types.Operator):
|
||||||
bl_idname = "bim.disable_editing_assigned_material"
|
bl_idname = "bim.disable_editing_assigned_material"
|
||||||
@@ -358,6 +395,7 @@ class EditAssignedMaterial(bpy.types.Operator):
|
|||||||
bl_label = "Edit Assigned Material"
|
bl_label = "Edit Assigned Material"
|
||||||
obj: bpy.props.StringProperty()
|
obj: bpy.props.StringProperty()
|
||||||
material_set: bpy.props.IntProperty()
|
material_set: bpy.props.IntProperty()
|
||||||
|
material_set_usage: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
self.file = IfcStore.get_file()
|
||||||
@@ -379,12 +417,24 @@ class EditAssignedMaterial(bpy.types.Operator):
|
|||||||
ifcopenshell.api.run(
|
ifcopenshell.api.run(
|
||||||
"material.edit_assigned_material",
|
"material.edit_assigned_material",
|
||||||
self.file,
|
self.file,
|
||||||
**{
|
**{"element": material_set, "attributes": attributes},
|
||||||
"element": material_set,
|
|
||||||
"attributes": attributes,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
|
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
|
||||||
|
|
||||||
|
if self.material_set_usage:
|
||||||
|
material_set_usage = self.file.by_id(self.material_set_usage)
|
||||||
|
attributes = blenderbim.bim.helper.export_attributes(props.material_set_usage_attributes)
|
||||||
|
attributes["CardinalPoint"] = int(attributes["CardinalPoint"]) if attributes["CardinalPoint"] else None
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"material.edit_assigned_material",
|
||||||
|
self.file,
|
||||||
|
**{"element": material_set_usage, "attributes": attributes},
|
||||||
|
)
|
||||||
|
if material_set_usage.is_a("IfcMaterialLayerSetUsage"):
|
||||||
|
Data.load_layer_usages()
|
||||||
|
elif material_set_usage.is_a("IfcMaterialProfileSetUsage"):
|
||||||
|
Data.load_profile_usages()
|
||||||
|
|
||||||
if material_set.is_a("IfcMaterialConstituentSet"):
|
if material_set.is_a("IfcMaterialConstituentSet"):
|
||||||
Data.load_constituents()
|
Data.load_constituents()
|
||||||
elif material_set.is_a("IfcMaterialLayerSet"):
|
elif material_set.is_a("IfcMaterialLayerSet"):
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ class BIMObjectMaterialProperties(PropertyGroup):
|
|||||||
material_type: EnumProperty(items=getMaterialTypes, name="Material Type")
|
material_type: EnumProperty(items=getMaterialTypes, name="Material Type")
|
||||||
material: EnumProperty(items=getMaterials, name="Material")
|
material: EnumProperty(items=getMaterials, name="Material")
|
||||||
is_editing: BoolProperty(name="Is Editing", default=False)
|
is_editing: BoolProperty(name="Is Editing", default=False)
|
||||||
|
material_set_usage_attributes: CollectionProperty(name="Material Set Usage Attributes", type=Attribute)
|
||||||
material_set_attributes: CollectionProperty(name="Material Set Attributes", type=Attribute)
|
material_set_attributes: CollectionProperty(name="Material Set Attributes", type=Attribute)
|
||||||
active_material_set_item_id: IntProperty(name="Active Material Set ID")
|
active_material_set_item_id: IntProperty(name="Active Material Set ID")
|
||||||
material_set_item_attributes: CollectionProperty(name="Material Set Item Attributes", type=Attribute)
|
material_set_item_attributes: CollectionProperty(name="Material Set Item Attributes", type=Attribute)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import blenderbim.bim.helper
|
||||||
from bpy.types import Panel
|
from bpy.types import Panel
|
||||||
from ifcopenshell.api.material.data import Data
|
from ifcopenshell.api.material.data import Data
|
||||||
from ifcopenshell.api.profile.data import Data as ProfileData
|
from ifcopenshell.api.profile.data import Data as ProfileData
|
||||||
@@ -109,6 +110,8 @@ class BIM_PT_object_material(Panel):
|
|||||||
if self.props.is_editing:
|
if self.props.is_editing:
|
||||||
op = row.operator("bim.edit_assigned_material", icon="CHECKMARK", text="")
|
op = row.operator("bim.edit_assigned_material", icon="CHECKMARK", text="")
|
||||||
op.material_set = self.material_set_id
|
op.material_set = self.material_set_id
|
||||||
|
if "Usage" in self.product_data["type"]:
|
||||||
|
op.material_set_usage = self.product_data["id"]
|
||||||
row.operator("bim.disable_editing_assigned_material", icon="CANCEL", text="")
|
row.operator("bim.disable_editing_assigned_material", icon="CANCEL", text="")
|
||||||
else:
|
else:
|
||||||
row.operator("bim.enable_editing_assigned_material", icon="GREASEPENCIL", text="")
|
row.operator("bim.enable_editing_assigned_material", icon="GREASEPENCIL", text="")
|
||||||
@@ -140,6 +143,8 @@ class BIM_PT_object_material(Panel):
|
|||||||
self.draw_read_only_set_ui()
|
self.draw_read_only_set_ui()
|
||||||
|
|
||||||
def draw_editable_set_ui(self):
|
def draw_editable_set_ui(self):
|
||||||
|
blenderbim.bim.helper.draw_attributes(self.props.material_set_usage_attributes, self.layout)
|
||||||
|
|
||||||
for attribute in self.props.material_set_attributes:
|
for attribute in self.props.material_set_attributes:
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(attribute, "string_value", text=attribute.name)
|
row.prop(attribute, "string_value", text=attribute.name)
|
||||||
@@ -265,6 +270,38 @@ class BIM_PT_object_material(Panel):
|
|||||||
row.label(text="Description")
|
row.label(text="Description")
|
||||||
row.label(text=str(self.material_set_data["Description"]))
|
row.label(text=str(self.material_set_data["Description"]))
|
||||||
|
|
||||||
|
if self.product_data["type"] == "IfcMaterialProfileSetUsage":
|
||||||
|
# TODO: complain to buildingSMART
|
||||||
|
cardinal_point_map = {
|
||||||
|
1: "bottom left",
|
||||||
|
2: "bottom centre",
|
||||||
|
3: "bottom right",
|
||||||
|
4: "mid-depth left",
|
||||||
|
5: "mid-depth centre",
|
||||||
|
6: "mid-depth right",
|
||||||
|
7: "top left",
|
||||||
|
8: "top centre",
|
||||||
|
9: "top right",
|
||||||
|
10: "geometric centroid",
|
||||||
|
11: "bottom in line with the geometric centroid",
|
||||||
|
12: "left in line with the geometric centroid",
|
||||||
|
13: "right in line with the geometric centroid",
|
||||||
|
14: "top in line with the geometric centroid",
|
||||||
|
15: "shear centre",
|
||||||
|
16: "bottom in line with the shear centre",
|
||||||
|
17: "left in line with the shear centre",
|
||||||
|
18: "right in line with the shear centre",
|
||||||
|
19: "top in line with the shear centre",
|
||||||
|
}
|
||||||
|
if self.material_set_usage["CardinalPoint"]:
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.label(text="CardinalPoint")
|
||||||
|
row.label(text=cardinal_point_map[self.material_set_usage["CardinalPoint"]])
|
||||||
|
if self.material_set_usage["ReferenceExtent"]:
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.label(text="ReferenceExtent")
|
||||||
|
row.label(text=str(self.material_set_usage["ReferenceExtent"]))
|
||||||
|
|
||||||
total_thickness = 0
|
total_thickness = 0
|
||||||
for item_id in self.set_items:
|
for item_id in self.set_items:
|
||||||
if self.product_data["type"] == "IfcMaterialList":
|
if self.product_data["type"] == "IfcMaterialList":
|
||||||
|
|||||||
@@ -27,7 +27,11 @@ target_views_enum = []
|
|||||||
|
|
||||||
|
|
||||||
def getAttributeEnumValues(self, context):
|
def getAttributeEnumValues(self, context):
|
||||||
return [(e, e, "") for e in json.loads(self.enum_items)]
|
# Support weird buildingSMART dictionary mappings which behave like enums
|
||||||
|
data = json.loads(self.enum_items)
|
||||||
|
if isinstance(data, dict):
|
||||||
|
return [(str(k), v, "") for k, v in data.items()]
|
||||||
|
return [(e, e, "") for e in data]
|
||||||
|
|
||||||
|
|
||||||
def updateSchemaDir(self, context):
|
def updateSchemaDir(self, context):
|
||||||
|
|||||||
Reference in New Issue
Block a user