mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 01:00:56 +00:00
Default to assigning material set usages if assigning to an occurrence. See #7794.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -210,14 +210,15 @@ class AssignMaterialToSelected(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_idname = "bim.assign_material_to_selected"
|
bl_idname = "bim.assign_material_to_selected"
|
||||||
bl_label = "Assign Material To Selected"
|
bl_label = "Assign Material To Selected"
|
||||||
bl_description = (
|
bl_description = (
|
||||||
"Assign currently selected material in Materials UI to the selected objects.\n\n"
|
"Assign currently selected material in Materials UI to the selected objects.\n"
|
||||||
"ALT+CLICK to assign material as a usage."
|
"Occurrences automatically get usages for layer/profile sets.\n\n"
|
||||||
|
"ALT+CLICK to assign without a usage."
|
||||||
)
|
)
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
material: bpy.props.IntProperty(name="Material IFC ID")
|
material: bpy.props.IntProperty(name="Material IFC ID")
|
||||||
assign_as_usage: bpy.props.BoolProperty(
|
should_auto_assign_usage: bpy.props.BoolProperty(
|
||||||
name="Assign Material As A Usage",
|
name="Auto Assign Usage",
|
||||||
default=False,
|
default=True,
|
||||||
options={"SKIP_SAVE"},
|
options={"SKIP_SAVE"},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -230,25 +231,19 @@ class AssignMaterialToSelected(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
if event.type == "LEFTMOUSE" and event.alt:
|
if event.type == "LEFTMOUSE" and event.alt:
|
||||||
material_class = tool.Ifc.get().by_id(self.material).is_a()
|
self.should_auto_assign_usage = False
|
||||||
if material_class not in ("IfcMaterialProfileSet", "IfcMaterialLayerSet"):
|
|
||||||
self.report({"ERROR"}, f"{material_class} cannot be assigned as a usage.")
|
|
||||||
return {"CANCELLED"}
|
|
||||||
self.assign_as_usage = True
|
|
||||||
return self.execute(context)
|
return self.execute(context)
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
material = tool.Ifc.get().by_id(self.material)
|
material = tool.Ifc.get().by_id(self.material)
|
||||||
objects = tool.Blender.get_selected_objects()
|
objects = tool.Blender.get_selected_objects()
|
||||||
material_type = material.is_a()
|
|
||||||
if self.assign_as_usage:
|
|
||||||
material_type += "Usage"
|
|
||||||
core.assign_material(
|
core.assign_material(
|
||||||
tool.Ifc,
|
tool.Ifc,
|
||||||
tool.Material,
|
tool.Material,
|
||||||
material_type=material_type,
|
material_type=material.is_a(),
|
||||||
objects=objects,
|
objects=objects,
|
||||||
material=material,
|
material=material,
|
||||||
|
should_auto_assign_usage=self.should_auto_assign_usage,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ def assign_material(
|
|||||||
material_type: Union[str, None],
|
material_type: Union[str, None],
|
||||||
objects: list[bpy.types.Object],
|
objects: list[bpy.types.Object],
|
||||||
material: Optional[ifcopenshell.entity_instance] = None,
|
material: Optional[ifcopenshell.entity_instance] = None,
|
||||||
|
should_auto_assign_usage: bool = True,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Assign material to the provided objects.
|
"""Assign material to the provided objects.
|
||||||
|
|
||||||
@@ -121,12 +122,18 @@ def assign_material(
|
|||||||
"""
|
"""
|
||||||
material_type = material_type or material_tool.get_object_ui_material_type()
|
material_type = material_type or material_tool.get_object_ui_material_type()
|
||||||
material = material or material_tool.get_object_ui_active_material()
|
material = material or material_tool.get_object_ui_active_material()
|
||||||
|
can_be_usage = should_auto_assign_usage and material_type in ("IfcMaterialLayerSet", "IfcMaterialProfileSet")
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
element = ifc.get_entity(obj)
|
element = ifc.get_entity(obj)
|
||||||
if not element:
|
if not element:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
ifc.run("material.assign_material", products=[element], type=material_type, material=material)
|
if can_be_usage and not material_tool.is_type_product(element):
|
||||||
|
element_material_type = material_type + "Usage"
|
||||||
|
else:
|
||||||
|
element_material_type = material_type
|
||||||
|
|
||||||
|
ifc.run("material.assign_material", products=[element], type=element_material_type, material=material)
|
||||||
assigned_material = material_tool.get_material(element)
|
assigned_material = material_tool.get_material(element)
|
||||||
assert assigned_material # Type checker.
|
assert assigned_material # Type checker.
|
||||||
|
|
||||||
@@ -136,7 +143,7 @@ def assign_material(
|
|||||||
material_tool.add_material_to_set(material_set=material, material=default_material)
|
material_tool.add_material_to_set(material_set=material, material=default_material)
|
||||||
elif material_tool.is_a_material_set(assigned_material):
|
elif material_tool.is_a_material_set(assigned_material):
|
||||||
material_tool.add_material_to_set(material_set=assigned_material, material=material)
|
material_tool.add_material_to_set(material_set=assigned_material, material=material)
|
||||||
material_tool.ensure_material_assigned(elements=[element], material_type=material_type, material=material)
|
material_tool.ensure_material_assigned(elements=[element], material_type=element_material_type, material=material)
|
||||||
|
|
||||||
|
|
||||||
def unassign_material(ifc: type[tool.Ifc], material_tool: type[tool.Material], objects: list[bpy.types.Object]) -> None:
|
def unassign_material(ifc: type[tool.Ifc], material_tool: type[tool.Material], objects: list[bpy.types.Object]) -> None:
|
||||||
|
|||||||
@@ -580,6 +580,7 @@ class Material:
|
|||||||
def import_material_definitions(cls, material_type: str): pass
|
def import_material_definitions(cls, material_type: str): pass
|
||||||
def is_a_flow_segment(cls, element): pass
|
def is_a_flow_segment(cls, element): pass
|
||||||
def is_a_material_set(cls, material): pass
|
def is_a_material_set(cls, material): pass
|
||||||
|
def is_type_product(cls, element): pass
|
||||||
def is_editing_materials(cls): pass
|
def is_editing_materials(cls): pass
|
||||||
def is_material_used_in_sets(cls, material): pass
|
def is_material_used_in_sets(cls, material): pass
|
||||||
def load_material_attributes(cls, material): pass
|
def load_material_attributes(cls, material): pass
|
||||||
|
|||||||
@@ -226,6 +226,10 @@ class Material(bonsai.core.tool.Material):
|
|||||||
"IfcMaterialProfileSet",
|
"IfcMaterialProfileSet",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_type_product(cls, element: ifcopenshell.entity_instance) -> bool:
|
||||||
|
return element.is_a("IfcTypeProduct")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_material_to_set(
|
def add_material_to_set(
|
||||||
cls, material_set: ifcopenshell.entity_instance, material: ifcopenshell.entity_instance
|
cls, material_set: ifcopenshell.entity_instance, material: ifcopenshell.entity_instance
|
||||||
|
|||||||
Reference in New Issue
Block a user