mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 17:57:02 +00:00
Fix #1872. Bug where duplicating an object didn't duplicate its styles.
This commit is contained in:
@@ -54,14 +54,11 @@ def add_representation(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if geometry.does_object_have_mesh_with_faces(obj):
|
if geometry.does_object_have_mesh_with_faces(obj):
|
||||||
styles = [
|
[geometry.run_style_add_style(obj=mat) for mat in geometry.get_object_materials_without_styles(obj)]
|
||||||
blenderbim.core.style.add_style(ifc, style, obj=material)
|
|
||||||
for material in geometry.get_object_materials_without_styles(obj)
|
|
||||||
]
|
|
||||||
ifc.run(
|
ifc.run(
|
||||||
"style.assign_representation_styles",
|
"style.assign_representation_styles",
|
||||||
shape_representation=representation,
|
shape_representation=representation,
|
||||||
styles=styles,
|
styles=geometry.get_styles(obj),
|
||||||
should_use_presentation_style_assignment=geometry.should_use_presentation_style_assignment(),
|
should_use_presentation_style_assignment=geometry.should_use_presentation_style_assignment(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ class Geometry:
|
|||||||
def get_profile_set_usage(cls, element): pass
|
def get_profile_set_usage(cls, element): pass
|
||||||
def get_representation_data(cls, representation): pass
|
def get_representation_data(cls, representation): pass
|
||||||
def get_representation_name(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 get_total_representation_items(cls, obj): pass
|
||||||
def has_data_users(cls, data): pass
|
def has_data_users(cls, data): pass
|
||||||
def import_representation(cls, obj, representation, enable_dynamic_voids=False): 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 replace_object_with_empty(cls, obj): pass
|
||||||
def resolve_mapped_representation(cls, representation): pass
|
def resolve_mapped_representation(cls, representation): pass
|
||||||
def run_geometry_update_representation(cls, obj=None): 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_faceted_brep(cls): pass
|
||||||
def should_force_triangulation(cls): pass
|
def should_force_triangulation(cls): pass
|
||||||
def should_use_presentation_style_assignment(cls): pass
|
def should_use_presentation_style_assignment(cls): pass
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import bpy
|
|||||||
import logging
|
import logging
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
|
import blenderbim.core.style
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
import blenderbim.bim.import_ifc
|
import blenderbim.bim.import_ifc
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
@@ -145,6 +146,10 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
def get_representation_name(cls, representation):
|
def get_representation_name(cls, representation):
|
||||||
return f"{representation.ContextOfItems.id()}/{representation.id()}"
|
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
|
@classmethod
|
||||||
def get_total_representation_items(cls, obj):
|
def get_total_representation_items(cls, obj):
|
||||||
return max(1, len(obj.material_slots))
|
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):
|
def run_geometry_update_representation(cls, obj=None):
|
||||||
bpy.ops.bim.update_representation(obj=obj.name, ifc_representation_class="")
|
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
|
@classmethod
|
||||||
def should_force_faceted_brep(cls):
|
def should_force_faceted_brep(cls):
|
||||||
return bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep
|
return bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep
|
||||||
|
|||||||
@@ -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" exists
|
||||||
And the object "IfcBuildingStorey/My Storey.001" is an "IfcBuildingStorey"
|
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
|
Scenario: Override duplicate move - copying a type instance with a representation map
|
||||||
Given an empty IFC project
|
Given an empty IFC project
|
||||||
And I add a cube
|
And I add a cube
|
||||||
|
|||||||
@@ -62,7 +62,8 @@ class TestAddRepresentation:
|
|||||||
|
|
||||||
# Add styles
|
# Add styles
|
||||||
geometry.get_object_materials_without_styles("obj").should_be_called().will_return(["material"])
|
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
|
# Link style to representation items
|
||||||
geometry.should_use_presentation_style_assignment().should_be_called().will_return(False)
|
geometry.should_use_presentation_style_assignment().should_be_called().will_return(False)
|
||||||
|
|||||||
@@ -169,6 +169,18 @@ class TestGetRepresentationName(NewFile):
|
|||||||
assert subject.get_representation_name(representation) == f"{context.id()}/{representation.id()}"
|
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):
|
class TestGetCartesianPointCoordinateOffset(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
@@ -387,6 +399,11 @@ class TestRunGeometryUpdateRepresentation(NewFile):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestRunStyleAddStyle(NewFile):
|
||||||
|
def test_nothing(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TestShouldForceFacetedBrep(NewFile):
|
class TestShouldForceFacetedBrep(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
result = bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep
|
result = bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep
|
||||||
|
|||||||
Reference in New Issue
Block a user