diff --git a/src/blenderbim/blenderbim/core/geometry.py b/src/blenderbim/blenderbim/core/geometry.py index fa34dd865c..1d9074c0af 100644 --- a/src/blenderbim/blenderbim/core/geometry.py +++ b/src/blenderbim/blenderbim/core/geometry.py @@ -54,14 +54,11 @@ def add_representation( ) if geometry.does_object_have_mesh_with_faces(obj): - styles = [ - blenderbim.core.style.add_style(ifc, style, obj=material) - for material in geometry.get_object_materials_without_styles(obj) - ] + [geometry.run_style_add_style(obj=mat) for mat in geometry.get_object_materials_without_styles(obj)] ifc.run( "style.assign_representation_styles", shape_representation=representation, - styles=styles, + styles=geometry.get_styles(obj), should_use_presentation_style_assignment=geometry.should_use_presentation_style_assignment(), ) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 41901ebde4..2cde394cf0 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -89,6 +89,7 @@ class Geometry: def get_profile_set_usage(cls, element): pass def get_representation_data(cls, representation): pass def get_representation_name(cls, representation): pass + def get_styles(cls, obj): pass def get_total_representation_items(cls, obj): pass def has_data_users(cls, data): pass def import_representation(cls, obj, representation, enable_dynamic_voids=False): pass @@ -103,6 +104,7 @@ class Geometry: def replace_object_with_empty(cls, obj): pass def resolve_mapped_representation(cls, representation): pass def run_geometry_update_representation(cls, obj=None): pass + def run_style_add_style(cls, obj=None): pass def should_force_faceted_brep(cls): pass def should_force_triangulation(cls): pass def should_use_presentation_style_assignment(cls): pass diff --git a/src/blenderbim/blenderbim/tool/geometry.py b/src/blenderbim/blenderbim/tool/geometry.py index b56f09bfb7..f7fd10b648 100644 --- a/src/blenderbim/blenderbim/tool/geometry.py +++ b/src/blenderbim/blenderbim/tool/geometry.py @@ -20,6 +20,7 @@ import bpy import logging import ifcopenshell import blenderbim.core.tool +import blenderbim.core.style import blenderbim.tool as tool import blenderbim.bim.import_ifc from mathutils import Vector @@ -145,6 +146,10 @@ class Geometry(blenderbim.core.tool.Geometry): def get_representation_name(cls, representation): return f"{representation.ContextOfItems.id()}/{representation.id()}" + @classmethod + def get_styles(cls, obj): + return [tool.Style.get_style(s.material) for s in obj.material_slots if s.material] + @classmethod def get_total_representation_items(cls, obj): return max(1, len(obj.material_slots)) @@ -246,6 +251,10 @@ class Geometry(blenderbim.core.tool.Geometry): def run_geometry_update_representation(cls, obj=None): bpy.ops.bim.update_representation(obj=obj.name, ifc_representation_class="") + @classmethod + def run_style_add_style(cls, obj=None): + return blenderbim.core.style.add_style(tool.Ifc, tool.Style, obj=obj) + @classmethod def should_force_faceted_brep(cls): return bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep diff --git a/src/blenderbim/test/bim/feature/geometry.feature b/src/blenderbim/test/bim/feature/geometry.feature index 3ca93317b7..dec38ac9df 100644 --- a/src/blenderbim/test/bim/feature/geometry.feature +++ b/src/blenderbim/test/bim/feature/geometry.feature @@ -309,6 +309,23 @@ Scenario: Override duplicate move - with active IFC data And the object "IfcBuildingStorey/My Storey.001" exists And the object "IfcBuildingStorey/My Storey.001" is an "IfcBuildingStorey" +Scenario: Override duplicate move - copying a coloured representation + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + And I add a material + And I set "scene.BIMRootProperties.ifc_class" to "IfcWall" + And I press "bim.assign_class" + And the object "IfcWall/Cube" is selected + And the material "Material" colour is set to "1,0,0,1" + When I press "object.duplicate_move" + And I press "export_ifc.bim(filepath='{cwd}/test/files/export.ifc')" + And an empty Blender session is started + And I press "bim.load_project(filepath='{cwd}/test/files/export.ifc')" + Then the material "Material" colour is "1,0,0,1" + And the object "IfcWall/Cube" has the material "Material" + And the object "IfcWall/Cube.001" has the material "Material" + Scenario: Override duplicate move - copying a type instance with a representation map Given an empty IFC project And I add a cube diff --git a/src/blenderbim/test/core/test_geometry.py b/src/blenderbim/test/core/test_geometry.py index 7a5d122c64..ab565b3b7b 100644 --- a/src/blenderbim/test/core/test_geometry.py +++ b/src/blenderbim/test/core/test_geometry.py @@ -62,7 +62,8 @@ class TestAddRepresentation: # Add styles geometry.get_object_materials_without_styles("obj").should_be_called().will_return(["material"]) - test.core.test_style.TestAddStyle.predict(self, ifc, style, obj="material") + geometry.run_style_add_style(obj="material").should_be_called() + geometry.get_styles("obj").should_be_called().will_return(["style"]) # Link style to representation items geometry.should_use_presentation_style_assignment().should_be_called().will_return(False) diff --git a/src/blenderbim/test/tool/test_geometry.py b/src/blenderbim/test/tool/test_geometry.py index 1328bdab01..e928ec0abf 100644 --- a/src/blenderbim/test/tool/test_geometry.py +++ b/src/blenderbim/test/tool/test_geometry.py @@ -169,6 +169,18 @@ class TestGetRepresentationName(NewFile): assert subject.get_representation_name(representation) == f"{context.id()}/{representation.id()}" +class TestGetStyles(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc.set(ifc) + style = ifc.createIfcSurfaceStyle() + material = bpy.data.materials.new("Material") + tool.Ifc.link(style, material) + obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh")) + obj.data.materials.append(material) + subject.get_styles(obj) == [style] + + class TestGetCartesianPointCoordinateOffset(NewFile): def test_run(self): obj = bpy.data.objects.new("Object", None) @@ -387,6 +399,11 @@ class TestRunGeometryUpdateRepresentation(NewFile): pass +class TestRunStyleAddStyle(NewFile): + def test_nothing(self): + pass + + class TestShouldForceFacetedBrep(NewFile): def test_run(self): result = bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep