mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 11:36:59 +00:00
Fix bug where copying elements shared a placement. This fix speeds up copying parent elements in the decomposition significantly, like when copying a storey.
This commit is contained in:
@@ -12,11 +12,14 @@ class Usecase:
|
|||||||
def execute(self):
|
def execute(self):
|
||||||
self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(self.file.schema)
|
self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(self.file.schema)
|
||||||
result = ifcopenshell.util.element.copy(self.file, self.settings["product"])
|
result = ifcopenshell.util.element.copy(self.file, self.settings["product"])
|
||||||
|
self.copy_direct_attributes(result)
|
||||||
self.copy_indirect_attributes(self.settings["product"], result)
|
self.copy_indirect_attributes(self.settings["product"], result)
|
||||||
# Copying representations is too hard, so for now we just don't do it.
|
|
||||||
self.remove_representations(result)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def copy_direct_attributes(self, to_element):
|
||||||
|
self.remove_representations(to_element)
|
||||||
|
self.copy_object_placements(to_element)
|
||||||
|
|
||||||
def copy_indirect_attributes(self, from_element, to_element):
|
def copy_indirect_attributes(self, from_element, to_element):
|
||||||
for inverse in self.file.get_inverse(from_element):
|
for inverse in self.file.get_inverse(from_element):
|
||||||
if inverse.is_a("IfcRelDefinesByProperties"):
|
if inverse.is_a("IfcRelDefinesByProperties"):
|
||||||
@@ -46,3 +49,8 @@ class Usecase:
|
|||||||
element.Representation = None
|
element.Representation = None
|
||||||
elif element.is_a("IfcTypeProduct"):
|
elif element.is_a("IfcTypeProduct"):
|
||||||
element.RepresentationMaps = None
|
element.RepresentationMaps = None
|
||||||
|
|
||||||
|
def copy_object_placements(self, element):
|
||||||
|
if not element.is_a("IfcProduct") or not element.ObjectPlacement:
|
||||||
|
return
|
||||||
|
element.ObjectPlacement = ifcopenshell.util.element.copy(self.file, element.ObjectPlacement)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import numpy
|
||||||
import test.bootstrap
|
import test.bootstrap
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
|
|
||||||
@@ -10,7 +11,20 @@ class TestCopyClass(test.bootstrap.IFC4):
|
|||||||
assert new.GlobalId != element.GlobalId
|
assert new.GlobalId != element.GlobalId
|
||||||
assert new.is_a("IfcWall")
|
assert new.is_a("IfcWall")
|
||||||
|
|
||||||
def test_copying_an_element_with_properties(self):
|
def test_copying_object_placements_so_children_of_the_original_element_dont_reference_the_new_element(self):
|
||||||
|
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
|
||||||
|
ifcopenshell.api.run("unit.assign_unit", self.file)
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
|
||||||
|
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
|
ifcopenshell.api.run("spatial.assign_container", self.file, product=subelement, relating_structure=element)
|
||||||
|
matrix = numpy.identity(4)
|
||||||
|
ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=element, matrix=matrix.copy())
|
||||||
|
ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=subelement, matrix=matrix.copy())
|
||||||
|
new = ifcopenshell.api.run("root.copy_class", self.file, product=element)
|
||||||
|
assert subelement.ObjectPlacement.PlacementRelTo == element.ObjectPlacement
|
||||||
|
assert subelement.ObjectPlacement.PlacementRelTo != new.ObjectPlacement
|
||||||
|
|
||||||
|
def test_copying_psets_so_changing_properties_of_the_new_element_does_not_affect_the_old(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="Foobar")
|
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="Foobar")
|
||||||
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"foo": "bar"})
|
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"foo": "bar"})
|
||||||
@@ -32,7 +46,7 @@ class TestCopyClass(test.bootstrap.IFC4):
|
|||||||
assert element.ContainsElements
|
assert element.ContainsElements
|
||||||
assert not new.ContainsElements
|
assert not new.ContainsElements
|
||||||
|
|
||||||
def test_copying_contents_of_a_container(self):
|
def test_copying_contents_of_a_container_and_maintaining_the_containment_relationship(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
ifcopenshell.api.run("spatial.assign_container", self.file, product=subelement, relating_structure=element)
|
ifcopenshell.api.run("spatial.assign_container", self.file, product=subelement, relating_structure=element)
|
||||||
@@ -55,7 +69,7 @@ class TestCopyClass(test.bootstrap.IFC4):
|
|||||||
assert element.IsDecomposedBy
|
assert element.IsDecomposedBy
|
||||||
assert not new.IsDecomposedBy
|
assert not new.IsDecomposedBy
|
||||||
|
|
||||||
def test_copying_an_aggregate_decomposition(self):
|
def test_copying_an_aggregate_decomposition_and_maintaining_the_aggregate_relationship(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcElementAssembly")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcElementAssembly")
|
||||||
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBeam")
|
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBeam")
|
||||||
ifcopenshell.api.run("aggregate.assign_object", self.file, product=subelement, relating_object=element)
|
ifcopenshell.api.run("aggregate.assign_object", self.file, product=subelement, relating_object=element)
|
||||||
|
|||||||
Reference in New Issue
Block a user