mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 06:32:09 +00:00
See #1676. You can now duplicate space boundaries.
This commit is contained in:
@@ -491,8 +491,7 @@ class ShowBoundaries(bpy.types.Operator, tool.Ifc.Operator):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
for rel in element.BoundedBy or []:
|
||||
boundary_obj = loader.load_boundary(rel, obj)
|
||||
new = props.boundaries.add()
|
||||
new.obj = boundary_obj
|
||||
tool.Boundary.decorate_boundary(boundary_obj)
|
||||
BoundaryDecorator.install(bpy.context)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -527,6 +527,8 @@ class OverrideDuplicateMove(bpy.types.Operator):
|
||||
array_pset = tool.Ifc.get().by_id(array_pset["id"])
|
||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=new, pset=array_pset)
|
||||
old_to_new[tool.Ifc.get_entity(obj)] = [new]
|
||||
if new.is_a("IfcRelSpaceBoundary"):
|
||||
tool.Boundary.decorate_boundary(new_obj)
|
||||
# Recreate decompositions
|
||||
tool.Root.recreate_decompositions(relationships, old_to_new)
|
||||
blenderbim.bim.handler.purge_module_data()
|
||||
|
||||
@@ -21,6 +21,10 @@ def copy_class(ifc, collector, geometry, root, obj=None):
|
||||
element = ifc.get_entity(obj)
|
||||
if not element:
|
||||
return
|
||||
if root.is_element_a(element, "IfcRelSpaceBoundary"):
|
||||
new = ifc.run("boundary.copy_boundary", boundary=element)
|
||||
ifc.link(new, obj)
|
||||
return new
|
||||
representation = root.get_object_representation(obj)
|
||||
new = ifc.run("root.copy_class", product=element)
|
||||
ifc.link(new, obj)
|
||||
@@ -38,7 +42,7 @@ def copy_class(ifc, collector, geometry, root, obj=None):
|
||||
geometry.link(new_representation, data)
|
||||
root.assign_body_styles(new, obj)
|
||||
collector.assign(obj)
|
||||
if root.is_opening_element(new):
|
||||
if root.is_element_a(new, "IfcOpeningElement"):
|
||||
root.add_tracked_opening(obj)
|
||||
return new
|
||||
|
||||
|
||||
@@ -606,7 +606,7 @@ class Root:
|
||||
def get_object_name(cls, obj): pass
|
||||
def get_object_representation(cls, obj): pass
|
||||
def get_representation_context(cls, representation): pass
|
||||
def is_opening_element(cls, element): pass
|
||||
def is_element_a(cls, element, ifc_class): pass
|
||||
def link_object_data(cls, source_obj, destination_obj): pass
|
||||
def recreate_decompositions(cls, relationships, old_to_new): pass
|
||||
def run_geometry_add_representation(cls, obj=None, context=None, ifc_representation_class=None, profile_set_usage=None): pass
|
||||
|
||||
@@ -70,3 +70,9 @@ class Boundary(blenderbim.core.tool.Boundary):
|
||||
translation = obj.matrix_world.translation - space.matrix_world.translation
|
||||
obj.data.transform(mathutils.Matrix.Translation(translation))
|
||||
obj.matrix_world = space.matrix_world
|
||||
|
||||
@classmethod
|
||||
def decorate_boundary(cls, obj):
|
||||
new = bpy.context.scene.BIMBoundaryProperties.boundaries.add()
|
||||
new.obj = obj
|
||||
obj.show_in_front = True
|
||||
|
||||
@@ -119,8 +119,8 @@ class Root(blenderbim.core.tool.Root):
|
||||
return representation.ContextOfItems
|
||||
|
||||
@classmethod
|
||||
def is_opening_element(cls, element):
|
||||
return element.is_a("IfcOpeningElement")
|
||||
def is_element_a(cls, element, ifc_class):
|
||||
return element.is_a(ifc_class)
|
||||
|
||||
@classmethod
|
||||
def link_object_data(cls, source_obj, destination_obj):
|
||||
|
||||
@@ -28,6 +28,7 @@ class TestCopyClass:
|
||||
|
||||
def test_copy_with_new_geometry_derived_from_the_type(self, ifc, collector, root):
|
||||
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
|
||||
root.get_object_representation("obj").should_be_called().will_return("representation")
|
||||
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
||||
ifc.link("element", "obj").should_be_called()
|
||||
@@ -37,7 +38,7 @@ class TestCopyClass:
|
||||
ifc.get_object("type").should_be_called().will_return("type_obj")
|
||||
root.link_object_data("type_obj", "obj").should_be_called()
|
||||
collector.assign("obj").should_be_called()
|
||||
root.is_opening_element("element").should_be_called().will_return(False)
|
||||
root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False)
|
||||
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||
|
||||
def test_copy_with_new_geometry_copied_from_the_old(self, ifc, collector, geometry, root):
|
||||
@@ -45,6 +46,7 @@ class TestCopyClass:
|
||||
# copied. This was faster (though I cannot recreate it now) but had the
|
||||
# bigger problem of not preserving non-mesh geometry and openings.
|
||||
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
|
||||
root.get_object_representation("obj").should_be_called().will_return("representation")
|
||||
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
||||
ifc.link("element", "obj").should_be_called()
|
||||
@@ -60,22 +62,24 @@ class TestCopyClass:
|
||||
root.assign_body_styles("element", "obj").should_be_called()
|
||||
geometry.duplicate_object_data("obj").should_be_called().will_return("data")
|
||||
collector.assign("obj").should_be_called()
|
||||
root.is_opening_element("element").should_be_called().will_return(False)
|
||||
root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False)
|
||||
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||
|
||||
def test_copy_with_no_new_geometry(self, ifc, collector, geometry, root):
|
||||
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
|
||||
root.get_object_representation("obj").should_be_called().will_return(None)
|
||||
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
||||
ifc.link("element", "obj").should_be_called()
|
||||
root.get_element_type("element").should_be_called().will_return("type")
|
||||
root.does_type_have_representations("type").should_be_called().will_return(False)
|
||||
collector.assign("obj").should_be_called()
|
||||
root.is_opening_element("element").should_be_called().will_return(False)
|
||||
root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False)
|
||||
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||
|
||||
def test_copied_openings_are_tracked_for_special_visualiation(self, ifc, collector, root):
|
||||
def test_copied_openings_are_tracked_for_special_visualiation(self, ifc, collector, geometry, root):
|
||||
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
|
||||
root.get_object_representation("obj").should_be_called().will_return(None)
|
||||
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
|
||||
ifc.link("element", "obj").should_be_called()
|
||||
@@ -85,10 +89,17 @@ class TestCopyClass:
|
||||
ifc.get_object("type").should_be_called().will_return("type_obj")
|
||||
root.link_object_data("type_obj", "obj").should_be_called()
|
||||
collector.assign("obj").should_be_called()
|
||||
root.is_opening_element("element").should_be_called().will_return(True)
|
||||
root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(True)
|
||||
root.add_tracked_opening("obj").should_be_called()
|
||||
subject.copy_class(ifc, collector, geometry, root, obj="obj")
|
||||
|
||||
def test_copying_boundaries_are_dealt_with_specially(self, ifc, collector, geometry, root):
|
||||
ifc.get_entity("obj").should_be_called().will_return("original_element")
|
||||
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(True)
|
||||
ifc.run("boundary.copy_boundary", boundary="original_element").should_be_called().will_return("element")
|
||||
ifc.link("element", "obj").should_be_called()
|
||||
assert subject.copy_class(ifc, collector, geometry, root, obj="obj") == "element"
|
||||
|
||||
|
||||
class TestAssignClass:
|
||||
def test_do_nothing_if_already_assigned(self, ifc, collector, root):
|
||||
|
||||
@@ -132,11 +132,11 @@ class TestGetRepresentationContext(NewFile):
|
||||
assert subject.get_representation_context(representation) == context
|
||||
|
||||
|
||||
class TestIsOpeningElement(NewFile):
|
||||
class TestIsElementA(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
assert subject.is_opening_element(ifc.createIfcWall()) is False
|
||||
assert subject.is_opening_element(ifc.createIfcOpeningElement()) is True
|
||||
assert subject.is_a(ifc.createIfcWall(), "IfcSlab") is False
|
||||
assert subject.is_a(ifc.createIfcOpeningElement(), "IfcOpeningElement") is True
|
||||
|
||||
|
||||
class TestLinkObjectData(NewFile):
|
||||
|
||||
Reference in New Issue
Block a user