mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 14:33:28 +00:00
You can now assign and unassign styles to materials
This commit is contained in:
@@ -40,10 +40,12 @@ classes = (
|
||||
operator.EditMaterial,
|
||||
operator.EditMaterialSetItem,
|
||||
operator.EditMaterialSetItemProfile,
|
||||
operator.EditMaterialStyle,
|
||||
operator.EnableEditingAssignedMaterial,
|
||||
operator.EnableEditingMaterial,
|
||||
operator.EnableEditingMaterialSetItem,
|
||||
operator.EnableEditingMaterialSetItemProfile,
|
||||
operator.EnableEditingMaterialStyle,
|
||||
operator.ExpandMaterialCategory,
|
||||
operator.LoadMaterials,
|
||||
operator.RemoveConstituent,
|
||||
@@ -55,6 +57,7 @@ classes = (
|
||||
operator.ReorderMaterialSetItem,
|
||||
operator.SelectByMaterial,
|
||||
operator.UnassignMaterial,
|
||||
operator.UnassignMaterialStyle,
|
||||
operator.UnlinkMaterial,
|
||||
prop.Material,
|
||||
prop.BIMMaterialProperties,
|
||||
|
||||
@@ -38,6 +38,9 @@ class MaterialsData:
|
||||
"total_materials": cls.total_materials(),
|
||||
"material_types": cls.material_types(),
|
||||
"profiles": cls.profiles(),
|
||||
"styles": cls.styles(),
|
||||
"contexts": cls.contexts(),
|
||||
"active_styles": cls.active_styles(),
|
||||
}
|
||||
cls.is_loaded = True
|
||||
|
||||
@@ -79,6 +82,58 @@ class MaterialsData:
|
||||
if p.ProfileName
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def contexts(cls):
|
||||
results = []
|
||||
for element in tool.Ifc.get().by_type("IfcGeometricRepresentationContext", include_subtypes=False):
|
||||
results.append((str(element.id()), element.ContextType or "Unnamed", ""))
|
||||
for element in tool.Ifc.get().by_type("IfcGeometricRepresentationSubContext", include_subtypes=False):
|
||||
results.append(
|
||||
(
|
||||
str(element.id()),
|
||||
"{}/{}/{}".format(
|
||||
element.ContextType or "Unnamed",
|
||||
element.ContextIdentifier or "Unnamed",
|
||||
element.TargetView or "Unnamed",
|
||||
),
|
||||
"",
|
||||
)
|
||||
)
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def styles(cls):
|
||||
return [(str(s.id()), s.Name or "Unnamed", "") for s in tool.Ifc.get().by_type("IfcSurfaceStyle") if s.Name]
|
||||
|
||||
@classmethod
|
||||
def active_styles(cls):
|
||||
props = bpy.context.scene.BIMMaterialProperties
|
||||
results = []
|
||||
if props.materials and props.active_material_index < len(props.materials):
|
||||
material = props.materials[props.active_material_index].ifc_definition_id
|
||||
if not material:
|
||||
return results
|
||||
material = tool.Ifc.get().by_id(material)
|
||||
for definition in material.HasRepresentation:
|
||||
for representation in definition.Representations:
|
||||
if not representation.is_a("IfcStyledRepresentation"):
|
||||
continue
|
||||
context = representation.ContextOfItems
|
||||
for item in representation.Items:
|
||||
if not item.is_a("IfcStyledItem"):
|
||||
continue
|
||||
for style in item.Styles:
|
||||
if style.is_a("IfcSurfaceStyle"):
|
||||
results.append({
|
||||
"context_type": context.ContextType,
|
||||
"context_identifier": getattr(context, "ContextIdentifier", ""),
|
||||
"target_view": getattr(context, "TargetView", ""),
|
||||
"name": style.Name or "Unnamed",
|
||||
"id": style.id(),
|
||||
"context_id": context.id(),
|
||||
})
|
||||
return results
|
||||
|
||||
|
||||
class ObjectMaterialData:
|
||||
data = {}
|
||||
|
||||
@@ -715,3 +715,50 @@ class ContractMaterialCategory(bpy.types.Operator):
|
||||
category.is_expanded = False
|
||||
core.load_materials(tool.Material, props.material_type)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EnableEditingMaterialStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.enable_editing_material_style"
|
||||
bl_label = "Enable Editing Material Style"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
material: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMMaterialProperties
|
||||
props.active_material_id = self.material
|
||||
props.editing_material_type = "STYLE"
|
||||
|
||||
|
||||
class EditMaterialStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.edit_material_style"
|
||||
bl_label = "Edit Material Style"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMMaterialProperties
|
||||
material = tool.Ifc.get().by_id(props.active_material_id)
|
||||
style = tool.Ifc.get().by_id(int(props.styles))
|
||||
context = tool.Ifc.get().by_id(int(props.contexts))
|
||||
ifcopenshell.api.run(
|
||||
"style.assign_material_style", tool.Ifc.get(), material=material, style=style, context=context
|
||||
)
|
||||
tool.Material.disable_editing_material()
|
||||
core.load_materials(tool.Material, props.material_type)
|
||||
|
||||
|
||||
class UnassignMaterialStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.unassign_material_style"
|
||||
bl_label = "Unassign Material Style"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
style: bpy.props.IntProperty()
|
||||
context: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMMaterialProperties
|
||||
material = tool.Ifc.get().by_id(props.materials[props.active_material_index].ifc_definition_id)
|
||||
style = tool.Ifc.get().by_id(self.style)
|
||||
context = tool.Ifc.get().by_id(self.context)
|
||||
ifcopenshell.api.run(
|
||||
"style.unassign_material_style", tool.Ifc.get(), material=material, style=style, context=context
|
||||
)
|
||||
core.load_materials(tool.Material, props.material_type)
|
||||
|
||||
@@ -103,11 +103,24 @@ def get_profiles(self, context):
|
||||
return MaterialsData.data["profiles"]
|
||||
|
||||
|
||||
def get_styles(self, context):
|
||||
if not MaterialsData.is_loaded:
|
||||
MaterialsData.load()
|
||||
return MaterialsData.data["styles"]
|
||||
|
||||
|
||||
def get_contexts(self, context):
|
||||
if not MaterialsData.is_loaded:
|
||||
MaterialsData.load()
|
||||
return MaterialsData.data["contexts"]
|
||||
|
||||
|
||||
class Material(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
is_category: BoolProperty(name="Is Category", default=False)
|
||||
is_expanded: BoolProperty(name="Is Expanded", default=True)
|
||||
has_style: BoolProperty(name="Has Style", default=True)
|
||||
total_elements: IntProperty(name="Total Elements")
|
||||
|
||||
|
||||
@@ -119,7 +132,9 @@ class BIMMaterialProperties(PropertyGroup):
|
||||
profiles: EnumProperty(items=get_profiles, name="Profiles")
|
||||
active_material_id: IntProperty(name="Active Material ID")
|
||||
material_attributes: CollectionProperty(name="Material Attributes", type=Attribute)
|
||||
editing_material_type = StringProperty(name="Editing Material Type")
|
||||
editing_material_type: StringProperty(name="Editing Material Type")
|
||||
styles: EnumProperty(items=get_styles, name="Styles")
|
||||
contexts: EnumProperty(items=get_contexts, name="Contexts")
|
||||
|
||||
|
||||
class BIMObjectMaterialProperties(PropertyGroup):
|
||||
|
||||
@@ -57,26 +57,19 @@ class BIM_PT_materials(Panel):
|
||||
row.alignment = "RIGHT"
|
||||
|
||||
if self.props.material_type == "IfcMaterial":
|
||||
if not self.props.active_material_id:
|
||||
row.operator("bim.add_material", text="", icon="ADD")
|
||||
row.operator("bim.add_material", text="", icon="ADD")
|
||||
if self.props.materials and self.props.active_material_index < len(self.props.materials):
|
||||
material = self.props.materials[self.props.active_material_index]
|
||||
if material.ifc_definition_id:
|
||||
if self.props.active_material_id:
|
||||
row.operator(
|
||||
"bim.edit_material", text="", icon="CHECKMARK"
|
||||
).material = material.ifc_definition_id
|
||||
row.operator(
|
||||
"bim.disable_editing_material", text="", icon="CANCEL"
|
||||
).material = material.ifc_definition_id
|
||||
self.draw_editable_material_attributes_ui()
|
||||
else:
|
||||
op = row.operator("bim.select_by_material", text="", icon="RESTRICT_SELECT_OFF")
|
||||
op.material = material.ifc_definition_id
|
||||
row.operator(
|
||||
"bim.enable_editing_material", text="", icon="GREASEPENCIL"
|
||||
).material = material.ifc_definition_id
|
||||
row.operator("bim.remove_material", text="", icon="X").material = material.ifc_definition_id
|
||||
op = row.operator("bim.select_by_material", text="", icon="RESTRICT_SELECT_OFF")
|
||||
op.material = material.ifc_definition_id
|
||||
op = row.operator("bim.enable_editing_material", text="", icon="GREASEPENCIL")
|
||||
op.material = material.ifc_definition_id
|
||||
op = row.operator("bim.enable_editing_material_style", text="", icon="SHADING_RENDERED")
|
||||
op.material = material.ifc_definition_id
|
||||
row.operator("bim.remove_material", text="", icon="X").material = material.ifc_definition_id
|
||||
|
||||
self.draw_editing_ui()
|
||||
else:
|
||||
row.operator("bim.add_material_set", text="", icon="ADD").set_type = self.props.material_type
|
||||
if self.props.materials and self.props.active_material_index < len(self.props.materials):
|
||||
@@ -88,8 +81,33 @@ class BIM_PT_materials(Panel):
|
||||
|
||||
self.layout.template_list("BIM_UL_materials", "", self.props, "materials", self.props, "active_material_index")
|
||||
|
||||
def draw_editable_material_attributes_ui(self):
|
||||
blenderbim.bim.helper.draw_attributes(self.props.material_attributes, self.layout)
|
||||
for style in MaterialsData.data["active_styles"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="", icon="SHADING_RENDERED")
|
||||
row.label(text=style["context_type"])
|
||||
row.label(text=style["context_identifier"])
|
||||
row.label(text=style["target_view"])
|
||||
row.label(text=style["name"])
|
||||
op = row.operator("bim.unassign_material_style", text="", icon="X")
|
||||
op.style = style["id"]
|
||||
op.context = style["context_id"]
|
||||
|
||||
def draw_editing_ui(self):
|
||||
if not self.props.active_material_id:
|
||||
return
|
||||
ifc_definition_id = self.props.active_material_id
|
||||
if self.props.editing_material_type == "ATTRIBUTES":
|
||||
blenderbim.bim.helper.draw_attributes(self.props.material_attributes, self.layout)
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.edit_material", text="Save Material", icon="CHECKMARK").material = ifc_definition_id
|
||||
row.operator("bim.disable_editing_material", text="", icon="CANCEL")
|
||||
elif self.props.editing_material_type == "STYLE":
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props, "contexts", text="")
|
||||
row.prop(self.props, "styles", text="")
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.edit_material_style", text="Assign Style", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_material", text="", icon="CANCEL")
|
||||
|
||||
|
||||
class BIM_PT_material(Panel):
|
||||
@@ -343,3 +361,6 @@ class BIM_UL_materials(UIList):
|
||||
row2 = row.row()
|
||||
row2.alignment = "RIGHT"
|
||||
row2.label(text=str(item.total_elements))
|
||||
|
||||
if item.has_style:
|
||||
row2.label(text="", icon="SHADING_RENDERED")
|
||||
|
||||
@@ -80,6 +80,7 @@ class Material(blenderbim.core.tool.Material):
|
||||
new.total_elements = len(
|
||||
ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material)
|
||||
)
|
||||
new.has_style = bool(material.HasRepresentation)
|
||||
return
|
||||
for material in materials:
|
||||
new = props.materials.add()
|
||||
|
||||
Reference in New Issue
Block a user