mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
Fix bug where copying objects with profiles should only share profiles if the profile is named.
This commit is contained in:
@@ -654,7 +654,7 @@ class EditExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
if not profile:
|
if not profile:
|
||||||
|
|
||||||
def msg(self, context):
|
def msg(self, context):
|
||||||
self.layout.label(text="INVALID PROFILE: " + indices[1])
|
self.layout.label(text="INVALID PROFILE")
|
||||||
|
|
||||||
bpy.context.window_manager.popup_menu(msg, title="Error", icon="ERROR")
|
bpy.context.window_manager.popup_menu(msg, title="Error", icon="ERROR")
|
||||||
DecorationsHandler.install(context)
|
DecorationsHandler.install(context)
|
||||||
@@ -667,6 +667,7 @@ class EditExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_profile)
|
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_profile)
|
||||||
|
|
||||||
blenderbim.core.geometry.switch_representation(
|
blenderbim.core.geometry.switch_representation(
|
||||||
|
tool.Ifc,
|
||||||
tool.Geometry,
|
tool.Geometry,
|
||||||
obj=obj,
|
obj=obj,
|
||||||
representation=representation,
|
representation=representation,
|
||||||
|
|||||||
@@ -50,18 +50,21 @@ class Root(blenderbim.core.tool.Root):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def copy_representation(cls, source, dest):
|
def copy_representation(cls, source, dest):
|
||||||
|
def exclude_callback(attribute):
|
||||||
|
return attribute.is_a("IfcProfileDef") and attribute.ProfileName
|
||||||
|
|
||||||
if dest.is_a("IfcProduct"):
|
if dest.is_a("IfcProduct"):
|
||||||
if not source.Representation:
|
if not source.Representation:
|
||||||
return
|
return
|
||||||
dest.Representation = ifcopenshell.util.element.copy_deep(
|
dest.Representation = ifcopenshell.util.element.copy_deep(
|
||||||
tool.Ifc.get(), source.Representation, exclude=["IfcGeometricRepresentationContext", "IfcProfileDef"]
|
tool.Ifc.get(), source.Representation, exclude=["IfcGeometricRepresentationContext"], exclude_callback=exclude_callback
|
||||||
)
|
)
|
||||||
elif dest.is_a("IfcTypeProduct"):
|
elif dest.is_a("IfcTypeProduct"):
|
||||||
if not source.RepresentationMaps:
|
if not source.RepresentationMaps:
|
||||||
return
|
return
|
||||||
dest.RepresentationMaps = [
|
dest.RepresentationMaps = [
|
||||||
ifcopenshell.util.element.copy_deep(
|
ifcopenshell.util.element.copy_deep(
|
||||||
tool.Ifc.get(), m, exclude=["IfcGeometricRepresentationContext", "IfcProfileDef"]
|
tool.Ifc.get(), m, exclude=["IfcGeometricRepresentationContext"], exclude_callback=exclude_callback
|
||||||
)
|
)
|
||||||
for m in source.RepresentationMaps
|
for m in source.RepresentationMaps
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -666,7 +666,7 @@ def copy(ifc_file, element):
|
|||||||
return new
|
return new
|
||||||
|
|
||||||
|
|
||||||
def copy_deep(ifc_file, element, exclude=None):
|
def copy_deep(ifc_file, element, exclude=None, exclude_callback=None):
|
||||||
"""
|
"""
|
||||||
Recursively copy an element and all of its directly related subelements.
|
Recursively copy an element and all of its directly related subelements.
|
||||||
|
|
||||||
@@ -679,6 +679,10 @@ def copy_deep(ifc_file, element, exclude=None):
|
|||||||
:param exclude: An optional list of strings of IFC class names to not copy.
|
:param exclude: An optional list of strings of IFC class names to not copy.
|
||||||
If any of the subelement is this class, it will not be copied and the
|
If any of the subelement is this class, it will not be copied and the
|
||||||
original instance will be referenced.
|
original instance will be referenced.
|
||||||
|
:type exclude: list[str],optional
|
||||||
|
:param exclude_callback: A callback to determine whether or not to exclude
|
||||||
|
an entity or not. Returns True to exclude and False to exclude.
|
||||||
|
:type exclude_callback: function,optional
|
||||||
:return: The newly copied element
|
:return: The newly copied element
|
||||||
:rtype: ifcopenshell.entity_instance.entity_instance
|
:rtype: ifcopenshell.entity_instance.entity_instance
|
||||||
"""
|
"""
|
||||||
@@ -687,13 +691,21 @@ def copy_deep(ifc_file, element, exclude=None):
|
|||||||
if attribute is None:
|
if attribute is None:
|
||||||
continue
|
continue
|
||||||
if isinstance(attribute, ifcopenshell.entity_instance):
|
if isinstance(attribute, ifcopenshell.entity_instance):
|
||||||
if not exclude or (exclude and not any([attribute.is_a(e) for e in exclude])):
|
if exclude and any([attribute.is_a(e) for e in exclude]):
|
||||||
|
pass
|
||||||
|
elif exclude_callback and exclude_callback(attribute):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
attribute = copy_deep(ifc_file, attribute, exclude=exclude)
|
attribute = copy_deep(ifc_file, attribute, exclude=exclude)
|
||||||
elif isinstance(attribute, tuple) and attribute and isinstance(attribute[0], ifcopenshell.entity_instance):
|
elif isinstance(attribute, tuple) and attribute and isinstance(attribute[0], ifcopenshell.entity_instance):
|
||||||
if not exclude or (exclude and not any([attribute[0].is_a(e) for e in exclude])):
|
if exclude and any([attribute[0].is_a(e) for e in exclude]):
|
||||||
|
pass
|
||||||
|
elif exclude_callback and exclude_callback(attribute[0]):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
attribute = list(attribute)
|
attribute = list(attribute)
|
||||||
for j, item in enumerate(attribute):
|
for j, item in enumerate(attribute):
|
||||||
attribute[j] = copy_deep(ifc_file, item, exclude=exclude)
|
attribute[j] = copy_deep(ifc_file, item, exclude=exclude, exclude_callback=exclude_callback)
|
||||||
if new.attribute_name(i) == "GlobalId":
|
if new.attribute_name(i) == "GlobalId":
|
||||||
new[i] = ifcopenshell.guid.new()
|
new[i] = ifcopenshell.guid.new()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ class TestAddContext(test.bootstrap.IFC4):
|
|||||||
assert context.ContextType == "Plan"
|
assert context.ContextType == "Plan"
|
||||||
assert context.is_a() == "IfcGeometricRepresentationContext"
|
assert context.is_a() == "IfcGeometricRepresentationContext"
|
||||||
assert context.WorldCoordinateSystem.is_a() == "IfcAxis2Placement2D"
|
assert context.WorldCoordinateSystem.is_a() == "IfcAxis2Placement2D"
|
||||||
assert context.WorldCoordinateSystem.Location.Coordinates == (0, 0, 0)
|
assert context.WorldCoordinateSystem.Location.Coordinates == (0, 0)
|
||||||
assert context.WorldCoordinateSystem.RefDirection.DirectionRatios == (1, 0, 0)
|
assert context.WorldCoordinateSystem.RefDirection.DirectionRatios == (1, 0)
|
||||||
assert context.CoordinateSpaceDimension == 2
|
assert context.CoordinateSpaceDimension == 2
|
||||||
|
|
||||||
def test_defaulting_to_3d_with_an_unknown_context_type(self):
|
def test_defaulting_to_3d_with_an_unknown_context_type(self):
|
||||||
|
|||||||
@@ -700,3 +700,10 @@ class TestCopyDeepIFC4(test.bootstrap.IFC4):
|
|||||||
rel.RelatedObjects = [element]
|
rel.RelatedObjects = [element]
|
||||||
rel2 = subject.copy_deep(self.file, rel, exclude=["IfcWall"])
|
rel2 = subject.copy_deep(self.file, rel, exclude=["IfcWall"])
|
||||||
assert rel.RelatedObjects == rel2.RelatedObjects
|
assert rel.RelatedObjects == rel2.RelatedObjects
|
||||||
|
|
||||||
|
def test_copying_an_element_recursively_with_aggregates_with_an_exclude_callback(self):
|
||||||
|
element = self.file.createIfcWall(Name="name")
|
||||||
|
rel = self.file.createIfcRelAggregates()
|
||||||
|
rel.RelatedObjects = [element]
|
||||||
|
rel2 = subject.copy_deep(self.file, rel, exclude_callback=lambda x: x.is_a("IfcWall"))
|
||||||
|
assert rel.RelatedObjects == rel2.RelatedObjects
|
||||||
|
|||||||
Reference in New Issue
Block a user