Assigning a profile set auto creates profiles if none exist to prevent invalid data.

This commit is contained in:
Dion Moult
2023-02-05 15:29:39 +11:00
parent 9f399b34fb
commit 77234706b0
3 changed files with 55 additions and 4 deletions
@@ -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):
@@ -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
+27 -4
View File
@@ -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]