diff --git a/src/blenderbim/blenderbim/bim/module/material/operator.py b/src/blenderbim/blenderbim/bim/module/material/operator.py index 6403923e2a..1f1cf41701 100644 --- a/src/blenderbim/blenderbim/bim/module/material/operator.py +++ b/src/blenderbim/blenderbim/bim/module/material/operator.py @@ -169,6 +169,33 @@ class AssignMaterial(bpy.types.Operator, tool.Ifc.Operator): ) 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, + ) class UnassignMaterial(bpy.types.Operator, tool.Ifc.Operator): diff --git a/src/blenderbim/test/bim/feature/material.feature b/src/blenderbim/test/bim/feature/material.feature index 67ef617b4f..8fe71ff8cc 100644 --- a/src/blenderbim/test/bim/feature/material.feature +++ b/src/blenderbim/test/bim/feature/material.feature @@ -242,6 +242,7 @@ Scenario: Assign material - material profile set When I set "active_object.BIMObjectMaterialProperties.material_type" to "IfcMaterialProfileSet" And I press "bim.assign_material" Then the object "IfcWallType/Empty" does not have the material "Default" + And the object "IfcWallType/Empty" has a profiled material containing the material "Default" and profile "New Profile" Scenario: Unassign material - material profile set Given an empty IFC project diff --git a/src/blenderbim/test/bim/test_feature.py b/src/blenderbim/test/bim/test_feature.py index b75c7e18d1..e1d48426fe 100644 --- a/src/blenderbim/test/bim/test_feature.py +++ b/src/blenderbim/test/bim/test_feature.py @@ -503,12 +503,13 @@ def the_object_name_has_the_material_material(name, material): @then( - parsers.parse('the object "{name}" has a "{thickness}" thick layered material containing the material "{material}"') + parsers.parse( + 'the object "{name}" has a "{thickness}" thick layered material containing the material "{material_name}"' + ) ) -def the_object_name_has_the_thickness_thick_layered_material_containing_the_material_material( - name, thickness, material +def the_object_name_has_a_thickness_thick_layered_material_containing_the_material_material( + name, thickness, material_name ): - material_name = material element = tool.Ifc.get_entity(the_object_name_exists(name)) material = ifcopenshell.util.element.get_material(element) assert material and "LayerSet" in material.is_a() @@ -523,6 +524,28 @@ def the_object_name_has_the_thickness_thick_layered_material_containing_the_mate assert material_name in material_names +@then( + parsers.parse( + 'the object "{name}" has a profiled material containing the material "{material_name}" and profile "{profile_name}"' + ) +) +def the_object_name_has_a_profiled_material_containing_the_material_material_and_profile_profile( + name, material_name, profile_name +): + element = tool.Ifc.get_entity(the_object_name_exists(name)) + material = ifcopenshell.util.element.get_material(element) + assert material and "ProfileSet" in material.is_a() + if material.is_a("IfcMaterialProfileSetUsage"): + material = material.ForProfileSet + material_names = [] + profile_names = [] + for profile in material.MaterialProfiles or []: + material_names.append(profile.Material.Name) + profile_names.append(profile.Profile.ProfileName) + assert material_name in material_names, f"No material {material_name} found in profiled materials: {material_names}" + assert profile_name in profile_names, f"No profile {profile_name} found in material profiles: {profile_names}" + + @then(parsers.parse('the object "{name}" does not have the material "{material}"')) def the_object_name_does_not_have_the_material_material(name, material): assert material not in [ms.material.name for ms in the_object_name_exists(name).material_slots]