From 2cf50dc48f19ceabe658a66d3564d4f0af057b77 Mon Sep 17 00:00:00 2001 From: Sigma Dimensions <79010126+myoualid@users.noreply.github.com> Date: Tue, 13 Jun 2023 10:28:31 +0100 Subject: [PATCH] split material assign/unassign operators into tool and core --- .../bim/module/material/operator.py | 77 +------------------ src/blenderbim/blenderbim/core/material.py | 29 +++++++ src/blenderbim/blenderbim/core/tool.py | 7 +- src/blenderbim/blenderbim/tool/material.py | 77 +++++++++++++++++-- 4 files changed, 109 insertions(+), 81 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/material/operator.py b/src/blenderbim/blenderbim/bim/module/material/operator.py index 9c16244daa..a5f0f8df62 100644 --- a/src/blenderbim/blenderbim/bim/module/material/operator.py +++ b/src/blenderbim/blenderbim/bim/module/material/operator.py @@ -174,67 +174,7 @@ class AssignMaterial(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): objects = [bpy.data.objects.get(self.obj)] if self.obj else tool.Blender.get_selected_objects() - active_obj = context.active_object - active_object_material_type = self.material_type or active_obj.BIMObjectMaterialProperties.material_type - material = tool.Ifc.get().by_id(int(active_obj.BIMObjectMaterialProperties.material)) - for obj in objects: - element = tool.Ifc.get_entity(obj) - if not element: - continue - ifcopenshell.api.run( - "material.assign_material", - tool.Ifc.get(), - product=element, - type=active_object_material_type, - material=material, - ) - assigned_material = ifcopenshell.util.element.get_material(element) - if assigned_material.is_a("IfcMaterialConstituentSet"): - if not assigned_material.MaterialConstituents: - ifcopenshell.api.run( - "material.add_constituent", - tool.Ifc.get(), - constituent_set=assigned_material, - material=material, - ) - elif assigned_material.is_a() == "IfcMaterialLayerSet": - if not assigned_material.MaterialLayers: - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) - layer = ifcopenshell.api.run( - "material.add_layer", - tool.Ifc.get(), - layer_set=assigned_material, - material=material, - ) - thickness = 0.1 # Arbitrary metric thickness for now - layer.LayerThickness = thickness / unit_scale - elif assigned_material.is_a("IfcMaterialProfileSet"): - if not assigned_material.MaterialProfiles: - named_profiles = [p for p in tool.Ifc.get().by_type("IfcProfileDef") if p.ProfileName] - if named_profiles: - profile = named_profiles[0] - else: - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) - size = 0.5 / unit_scale - profile = tool.Ifc.get().create_entity( - "IfcRectangleProfileDef", - ProfileName="New Profile", - ProfileType="AREA", - XDim=size, - YDim=size, - ) - material_profile = ifcopenshell.api.run( - "material.add_profile", - tool.Ifc.get(), - profile_set=assigned_material, - material=tool.Ifc.get().by_type("IfcMaterial")[0], - ) - ifcopenshell.api.run( - "material.assign_profile", - tool.Ifc.get(), - material_profile=material_profile, - profile=profile, - ) + core.assign_material(tool.Ifc, tool.Material, material_type= self.material_type , objects=objects ) class UnassignMaterial(bpy.types.Operator, tool.Ifc.Operator): @@ -245,20 +185,7 @@ class UnassignMaterial(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): objects = [bpy.data.objects.get(self.obj)] if self.obj else tool.Blender.get_selected_objects() - for obj in objects: - element = tool.Ifc.get_entity(obj) - if element: - material = ifcopenshell.util.element.get_material(element, should_inherit=False) - inherited_material = ifcopenshell.util.element.get_material(element, should_inherit=True) - print(material, inherited_material) - if material and "Usage" in material.is_a(): - element_type = ifcopenshell.util.element.get_type(element) - ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), product=element_type) - elif not material and inherited_material: - element_type = ifcopenshell.util.element.get_type(element) - ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), product=element_type) - elif material: - ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), product=element) + core.unassign_material(tool.Ifc, tool.Material, objects=objects ) class AddConstituent(bpy.types.Operator, tool.Ifc.Operator): diff --git a/src/blenderbim/blenderbim/core/material.py b/src/blenderbim/blenderbim/core/material.py index d65e91c5e2..6203a53fe8 100644 --- a/src/blenderbim/blenderbim/core/material.py +++ b/src/blenderbim/blenderbim/core/material.py @@ -90,3 +90,32 @@ def edit_material(ifc, material_tool, material): def disable_editing_material(material_tool): material_tool.disable_editing_material() + + +def assign_material(ifc, material_tool, material_type, objects): + material_type = material_type or material_tool.get_active_object_material() + material = material_tool.get_active_material() + for obj in objects: + element = ifc.get_entity(obj) + if not element: + continue + ifc.run("material.assign_material", product=element, type=material_type, material=material) + assigned_material = material_tool.get_material(element) + if material_tool.is_a_material_set(assigned_material): + material_tool.add_material_to_set(material_set=assigned_material, material=material) + + +def unassign_material(ifc, material_tool, objects): + for obj in objects: + element = ifc.get_entity(obj) + if element: + material = material_tool.get_material(element, should_inherit=False) + inherited_material = material_tool.get_material(element, should_inherit=True) + if material and "Usage" in material.is_a(): + element_type = material_tool.get_type(element) + ifc.run("material.unassign_material", product=element_type) + elif not material and inherited_material: + element_type = material_tool.get_type(element) + ifc.run("material.unassign_material", product=element_type) + elif material: + ifc.run("material.unassign_material", product=element) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index ebf5202a98..0675b29359 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -433,17 +433,22 @@ class Loader: @interface class Material: def add_default_material_object(cls): pass + def add_material_to_set(cls, material_set, material): pass def delete_object(cls, obj): pass def disable_editing_material(cls): pass def disable_editing_materials(cls): pass def enable_editing_material(cls, material): pass def enable_editing_materials(cls): pass def get_active_material_type(cls): pass - def get_active_material_type(cls): pass + def get_active_material(cls): pass + def get_active_object_material(cls, obj): pass def get_elements_by_material(cls, material): pass def get_material_attributes(cls): pass + def get_material(cls, element, should_inherit): pass def get_name(cls, obj): pass + def get_type(cls, element): pass def import_material_definitions(cls, material_type): pass + def is_a_material_set(cls, material): pass def is_editing_materials(cls): pass def is_material_used_in_sets(cls, material): pass def load_material_attributes(cls, material): pass diff --git a/src/blenderbim/blenderbim/tool/material.py b/src/blenderbim/blenderbim/tool/material.py index b0a9a3dd09..3047c605e8 100644 --- a/src/blenderbim/blenderbim/tool/material.py +++ b/src/blenderbim/blenderbim/tool/material.py @@ -21,6 +21,8 @@ import ifcopenshell import blenderbim.core.tool import blenderbim.tool as tool import blenderbim.bim.helper +import ifcopenshell.util.unit +import ifcopenshell.util.element class Material(blenderbim.core.tool.Material): @@ -101,10 +103,6 @@ class Material(blenderbim.core.tool.Material): return True return False - @classmethod - def get_active_material_type(cls): - return bpy.context.scene.BIMMaterialProperties.material_type - @classmethod def load_material_attributes(cls, material): props = bpy.context.scene.BIMMaterialProperties @@ -115,7 +113,7 @@ class Material(blenderbim.core.tool.Material): def enable_editing_material(cls, material): props = bpy.context.scene.BIMMaterialProperties props.active_material_id = material.id() - props.editing_material_type = "ATTRIBUTES" + props.editing_material_type = "ATTRIBUTES" @classmethod def get_material_attributes(cls): @@ -126,3 +124,72 @@ class Material(blenderbim.core.tool.Material): props = bpy.context.scene.BIMMaterialProperties props.active_material_id = 0 props.editing_material_type = "" + + @classmethod + def get_type(cls, element): + return ifcopenshell.util.element.get_type(element) + + @classmethod + def get_active_object_material(cls): + active_obj = bpy.context.active_object + if not active_obj: + return + return active_obj.BIMObjectMaterialProperties.material_type + + @classmethod + def get_active_material(cls): + return tool.Ifc.get().by_id(int(bpy.context.active_object.BIMObjectMaterialProperties.material)) + + @classmethod + def get_material(cls, element, should_inherit=False): + return ifcopenshell.util.element.get_material(element, should_inherit=should_inherit) + + @classmethod + def is_a_material_set(cls, material): + return material.is_a() in [ + "IfcMaterialProfile", + "IfcMaterialLayer", + "IfcMaterialConstituent", + "IfcMaterialList", + ] + + @classmethod + def add_material_to_set(cls, material_set, material): + if material_set.is_a("IfcMaterialConstituentSet"): + if not material_set.MaterialConstituents: + tool.Ifc.run( + "material.add_constituent", + constituent_set=material_set, + material=material, + ) + elif material_set.is_a() == "IfcMaterialLayerSet": + if not material_set.MaterialLayers: + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + layer = tool.Ifc.run( + "material.add_layer", + layer_set=material_set, + material=material, + ) + thickness = 0.1 # Arbitrary metric thickness for now + layer.LayerThickness = thickness / unit_scale + elif material_set.is_a("IfcMaterialProfileSet"): + if not material_set.MaterialProfiles: + named_profiles = [p for p in tool.Ifc.get().by_type("IfcProfileDef") if p.ProfileName] + if named_profiles: + profile = named_profiles[0] + else: + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + size = 0.5 / unit_scale + profile = tool.Ifc.get().create_entity( + "IfcRectangleProfileDef", + ProfileName="New Profile", + ProfileType="AREA", + XDim=size, + YDim=size, + ) + material_profile = ifcopenshell.api.run( + "material.add_profile", + profile_set=material_set, + material=material, + profile=profile, + )