mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 10:06:47 +00:00
Port locations are now auto synchronised when hiding ports
This commit is contained in:
@@ -148,7 +148,7 @@ class IfcExporter:
|
||||
return checksum != str([s.id() for s in tool.Geometry.get_styles(obj) if s])
|
||||
|
||||
def sync_object_placement(self, obj):
|
||||
if not self.has_object_moved(obj):
|
||||
if not tool.Ifc.is_moved(obj):
|
||||
return
|
||||
blender_matrix = np.array(obj.matrix_world)
|
||||
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
@@ -162,17 +162,6 @@ class IfcExporter:
|
||||
blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
|
||||
return element
|
||||
|
||||
def has_object_moved(self, obj):
|
||||
if not obj.BIMObjectProperties.location_checksum:
|
||||
return True # Let's be conservative
|
||||
loc_check = np.frombuffer(eval(obj.BIMObjectProperties.location_checksum))
|
||||
rot_check = np.frombuffer(eval(obj.BIMObjectProperties.rotation_checksum))
|
||||
loc_real = np.array(obj.matrix_world.translation).flatten()
|
||||
rot_real = np.array(obj.matrix_world.to_3x3()).flatten()
|
||||
if np.allclose(loc_check, loc_real, atol=1e-4) and np.allclose(rot_check, rot_real, atol=1e-2):
|
||||
return False
|
||||
return True
|
||||
|
||||
def sync_grid_axis_object_placement(self, obj, element):
|
||||
grid = (element.PartOfU or element.PartOfV or element.PartOfW)[0]
|
||||
grid_obj = tool.Ifc.get_object(grid)
|
||||
|
||||
@@ -106,16 +106,13 @@ class MepGenerator:
|
||||
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="EPset_Parametric")
|
||||
ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Engine": "BlenderBIM.Mep"})
|
||||
|
||||
start_port_matrix = obj.matrix_world
|
||||
end_port_matrix = obj.matrix_world.copy()
|
||||
end_port_location = end_port_matrix @ Vector((0, 0, self.length))
|
||||
end_port_matrix[0][3] = end_port_location[0]
|
||||
end_port_matrix[1][3] = end_port_location[1]
|
||||
end_port_matrix[2][3] = end_port_location[2]
|
||||
start_port_matrix = Matrix()
|
||||
end_port_matrix = Matrix.Translation((0, 0, self.length))
|
||||
|
||||
for mat in [start_port_matrix, end_port_matrix]:
|
||||
port_obj = bpy.data.objects.new("Port", None)
|
||||
port_obj.matrix_world = mat
|
||||
port_obj.parent = obj
|
||||
port = tool.System.run_root_assign_class(obj=port_obj, ifc_class="IfcDistributionPort")
|
||||
tool.Ifc.run("system.assign_port", element=element, port=port)
|
||||
|
||||
|
||||
@@ -143,7 +143,8 @@ class AddTypeInstance(bpy.types.Operator):
|
||||
mat[1][3] *= unit_scale
|
||||
mat[2][3] *= unit_scale
|
||||
port_obj = bpy.data.objects.new("Port", None)
|
||||
port_obj.matrix_world = obj.matrix_world @ mathutils.Matrix(mat)
|
||||
port_obj.matrix_world = mathutils.Matrix(mat)
|
||||
port_obj.parent = obj
|
||||
port = tool.System.run_root_assign_class(obj=port_obj, ifc_class="IfcDistributionPort")
|
||||
tool.Ifc.run("system.assign_port", element=element, port=port)
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ class HidePorts(bpy.types.Operator, Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
core.hide_ports(tool.System, element=tool.Ifc.get_entity(context.active_object))
|
||||
core.hide_ports(tool.Ifc, tool.System, element=tool.Ifc.get_entity(context.active_object))
|
||||
|
||||
|
||||
class AddPort(bpy.types.Operator, Operator):
|
||||
|
||||
@@ -68,16 +68,26 @@ def select_system_products(system_tool, system=None):
|
||||
|
||||
def show_ports(system, element=None):
|
||||
ports = system.get_ports(element)
|
||||
system.load_ports(ports)
|
||||
system.load_ports(element, ports)
|
||||
system.select_elements(ports)
|
||||
|
||||
|
||||
def hide_ports(system, element=None):
|
||||
system.delete_element_objects(system.get_ports(element))
|
||||
def hide_ports(ifc, system, element=None):
|
||||
obj = ifc.get_object(element)
|
||||
if obj and ifc.is_moved(obj):
|
||||
system.run_geometry_edit_object_placement(obj=obj)
|
||||
|
||||
ports = system.get_ports(element)
|
||||
for port in ports:
|
||||
obj = ifc.get_object(port)
|
||||
if obj and ifc.is_moved(obj):
|
||||
system.run_geometry_edit_object_placement(obj=obj)
|
||||
|
||||
system.delete_element_objects(ports)
|
||||
|
||||
|
||||
def add_port(ifc, system, element=None):
|
||||
system.load_ports(system.get_ports(element))
|
||||
system.load_ports(element, system.get_ports(element))
|
||||
obj = system.create_empty_at_cursor_with_element_orientation(element)
|
||||
port = system.run_root_assign_class(obj=obj, ifc_class="IfcDistributionPort")
|
||||
ifc.run("system.assign_port", element=element, port=port)
|
||||
|
||||
@@ -473,7 +473,8 @@ class System:
|
||||
def get_ports(cls, element): pass
|
||||
def import_system_attributes(cls, system): pass
|
||||
def import_systems(cls): pass
|
||||
def load_ports(cls, port): pass
|
||||
def load_ports(cls, element, ports): pass
|
||||
def run_geometry_edit_object_placement(cls, obj=None): pass
|
||||
def run_root_assign_class(cls, obj=None, ifc_class=None, predefined_type=None, should_add_representation=True, context=None, ifc_representation_class=None): pass
|
||||
def select_elements(cls, elements): pass
|
||||
def select_system_products(cls, system): pass
|
||||
|
||||
@@ -81,9 +81,10 @@ class System(blenderbim.core.tool.System):
|
||||
new.ifc_class = system.is_a()
|
||||
|
||||
@classmethod
|
||||
def load_ports(cls, ports):
|
||||
def load_ports(cls, element, ports):
|
||||
if not ports:
|
||||
return
|
||||
obj = tool.Ifc.get_object(element)
|
||||
ifc_import_settings = import_ifc.IfcImportSettings.factory()
|
||||
ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
|
||||
ifc_importer.file = tool.Ifc.get()
|
||||
@@ -93,9 +94,16 @@ class System(blenderbim.core.tool.System):
|
||||
for port in ports or []:
|
||||
if tool.Ifc.get_object(port):
|
||||
continue
|
||||
ifc_importer.create_product(port)
|
||||
port_obj = ifc_importer.create_product(port)
|
||||
if obj:
|
||||
port_obj.parent = obj
|
||||
port_obj.matrix_parent_inverse = obj.matrix_world.inverted()
|
||||
ifc_importer.place_objects_in_collections()
|
||||
|
||||
@classmethod
|
||||
def run_geometry_edit_object_placement(cls, obj=None):
|
||||
return blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
|
||||
|
||||
@classmethod
|
||||
def run_root_assign_class(
|
||||
cls,
|
||||
|
||||
@@ -93,22 +93,31 @@ class TestSelectSystemProducts:
|
||||
class TestShowPorts:
|
||||
def test_run(self, system):
|
||||
system.get_ports("element").should_be_called().will_return(["port"])
|
||||
system.load_ports(["port"]).should_be_called()
|
||||
system.load_ports("element", ["port"]).should_be_called()
|
||||
system.select_elements(["port"]).should_be_called()
|
||||
subject.show_ports(system, element="element")
|
||||
|
||||
|
||||
class TestHidePorts:
|
||||
def test_run(self, system):
|
||||
def test_run(self, ifc, system):
|
||||
ifc.get_object("element").should_be_called().will_return("obj")
|
||||
ifc.is_moved("obj").should_be_called().will_return(True)
|
||||
system.run_geometry_edit_object_placement(obj="obj").should_be_called()
|
||||
|
||||
system.get_ports("element").should_be_called().will_return(["port"])
|
||||
|
||||
ifc.get_object("port").should_be_called().will_return("port_obj")
|
||||
ifc.is_moved("port_obj").should_be_called().will_return(True)
|
||||
system.run_geometry_edit_object_placement(obj="port_obj").should_be_called()
|
||||
|
||||
system.delete_element_objects(["port"]).should_be_called()
|
||||
subject.hide_ports(system, element="element")
|
||||
subject.hide_ports(ifc, system, element="element")
|
||||
|
||||
|
||||
class TestAddPort:
|
||||
def test_run(self, ifc, system):
|
||||
system.get_ports("element").should_be_called().will_return(["port"])
|
||||
system.load_ports(["port"]).should_be_called()
|
||||
system.load_ports("element", ["port"]).should_be_called()
|
||||
system.create_empty_at_cursor_with_element_orientation("element").should_be_called().will_return("obj")
|
||||
system.run_root_assign_class(obj="obj", ifc_class="IfcDistributionPort").should_be_called().will_return("port")
|
||||
ifc.run("system.assign_port", element="element", port="port").should_be_called()
|
||||
|
||||
@@ -177,15 +177,21 @@ class TestLoadPorts(NewFile):
|
||||
ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject")
|
||||
ifcopenshell.api.run("unit.assign_unit", ifc)
|
||||
tool.Ifc().set(ifc)
|
||||
element = ifc.createIfcChiller()
|
||||
port = ifc.createIfcDistributionPort()
|
||||
subject.load_ports([port])
|
||||
subject.load_ports(element, [port])
|
||||
obj = tool.Ifc.get_object(port)
|
||||
assert obj
|
||||
assert obj.users_collection
|
||||
assert list(obj.location) == [0, 0, 0]
|
||||
|
||||
|
||||
class TestRunAssignClassOperator(NewFile):
|
||||
class TestRunGeometryEditObjectPlacement(NewFile):
|
||||
def test_nothing(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestRunRootAssignClass(NewFile):
|
||||
def test_nothing(self):
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user