You can now select elements by material in the material manager.

This commit is contained in:
Dion Moult
2022-03-22 13:25:26 +11:00
parent 9b9f0058f9
commit 0bba31e5f9
10 changed files with 76 additions and 0 deletions
@@ -44,6 +44,7 @@ classes = (
operator.RemoveMaterialSet,
operator.RemoveProfile,
operator.ReorderMaterialSetItem,
operator.SelectByMaterial,
operator.UnassignMaterial,
operator.UnlinkMaterial,
prop.Material,
@@ -41,6 +41,12 @@ class MaterialsData:
@classmethod
def total_materials(cls):
if tool.Ifc.get_schema() == "IFC2X3":
return (
len(tool.Ifc.get().by_type("IfcMaterial"))
+ len(tool.Ifc.get().by_type("IfcMaterialLayerSet"))
+ len(tool.Ifc.get().by_type("IfcMaterialList"))
)
return (
len(tool.Ifc.get().by_type("IfcMaterial"))
+ len(tool.Ifc.get().by_type("IfcMaterialConstituentSet"))
@@ -49,6 +49,16 @@ class DisableEditingMaterials(bpy.types.Operator, tool.Ifc.Operator):
core.disable_editing_materials(tool.Material)
class SelectByMaterial(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.select_by_material"
bl_label = "Select By Material"
bl_options = {"REGISTER", "UNDO"}
material: bpy.props.IntProperty()
def _execute(self, context):
core.select_by_material(tool.Material, material=tool.Ifc.get().by_id(self.material))
class AssignParameterizedProfile(bpy.types.Operator):
bl_idname = "bim.assign_parameterized_profile"
bl_label = "Assign Parameterized Profile"
@@ -61,11 +61,15 @@ class BIM_PT_materials(Panel):
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]
op = row.operator("bim.select_by_material", text="", icon="RESTRICT_SELECT_OFF")
op.material = material.ifc_definition_id
row.operator("bim.remove_material", text="", icon="X").material = material.ifc_definition_id
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):
material = self.props.materials[self.props.active_material_index]
op = row.operator("bim.select_by_material", text="", icon="RESTRICT_SELECT_OFF")
op.material = material.ifc_definition_id
row.operator("bim.remove_material_set", text="", icon="X").material = material.ifc_definition_id
self.layout.template_list("BIM_UL_materials", "", self.props, "materials", self.props, "active_material_index")
@@ -66,3 +66,7 @@ def load_materials(material, material_type):
def disable_editing_materials(material):
material.disable_editing_materials()
def select_by_material(material_tool, material=None):
material_tool.select_elements(material_tool.get_elements_by_material(material))
+2
View File
@@ -280,9 +280,11 @@ class Material:
def disable_editing_materials(cls): pass
def enable_editing_materials(cls): pass
def get_active_material_type(cls): pass
def get_elements_by_material(cls, material): pass
def get_name(cls, obj): pass
def import_material_definitions(cls, material_type): pass
def is_editing_materials(cls): pass
def select_elements(cls, elements): pass
@interface
@@ -44,6 +44,10 @@ class Material(blenderbim.core.tool.Material):
def get_active_material_type(cls):
return bpy.context.scene.BIMMaterialProperties.material_type
@classmethod
def get_elements_by_material(cls, material):
return set(ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material))
@classmethod
def get_name(cls, obj):
return obj.name
@@ -66,3 +70,10 @@ class Material(blenderbim.core.tool.Material):
@classmethod
def is_editing_materials(cls):
return bpy.context.scene.BIMMaterialProperties.is_editing
@classmethod
def select_elements(cls, elements):
for element in elements:
obj = tool.Ifc.get_object(element)
if obj:
obj.select_set(True)
@@ -110,3 +110,12 @@ Scenario: Assign material - Assign a material profile set
When I set "active_object.BIMObjectMaterialProperties.material_type" to "IfcMaterialProfileSet"
And I press "bim.assign_material"
Then nothing happens
Scenario: Select by material
Scenario: Load materials - then add material
Given an empty IFC project
And I press "bim.load_materials"
And I press "bim.add_material(obj='')"
And the variable "material" is "{ifc}.by_type('IfcMaterial')[0].id()"
When I press "bim.select_by_material(material={material})"
Then nothing happens
@@ -147,3 +147,10 @@ class TestDisableEditingMaterials:
def test_run(self, material):
material.disable_editing_materials().should_be_called()
subject.disable_editing_materials(material)
class TestSelectByMaterial:
def test_run(self, material):
material.get_elements_by_material("material").should_be_called().will_return("elements")
material.select_elements("elements").should_be_called()
subject.select_by_material(material, material="material")
+22
View File
@@ -68,6 +68,16 @@ class TestGetActiveMaterialType(NewFile):
assert subject.get_active_material_type() == "IfcMaterialLayerSet"
class TestGetElementsByMaterial(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
material = ifcopenshell.api.run("material.add_material", ifc)
ifcopenshell.api.run("material.assign_material", ifc, product=element, material=material)
assert subject.get_elements_by_material(material) == {element}
class TestGetName(NewFile):
def test_run(self):
assert subject.get_name(bpy.data.materials.new("Material")) == "Material"
@@ -131,3 +141,15 @@ class TestIsEditingMaterials(NewFile):
subject.is_editing_materials() is False
bpy.context.scene.BIMMaterialProperties.is_editing = True
subject.is_editing_materials() is True
class TestSelectElements(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc().set(ifc)
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcPump")
obj = bpy.data.objects.new("Object", None)
bpy.context.scene.collection.objects.link(obj)
tool.Ifc.link(element, obj)
subject.select_elements([element])
assert obj in bpy.context.selected_objects