From 2d847d1704ef5e1f86fcdefc4709f685f73db34d Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 10 Aug 2023 16:30:51 +0500 Subject: [PATCH] Adjusting connected elements on bim.regenerate_distribution_element Basically commented out automatic adjustment after 45f81b478 - now it's hapenning only when you decide to regenerate it. It's adjusting connected segments extrusion and location, for all other elements besides segments it's adjusting only location. The idea is it will try to change as less as possible. Demo - https://imgur.com/oZ1I2Bl --- .../blenderbim/bim/module/model/mep.py | 63 ++++++++++++++++--- .../blenderbim/bim/module/system/operator.py | 8 +-- src/blenderbim/blenderbim/tool/model.py | 5 ++ 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/mep.py b/src/blenderbim/blenderbim/bim/module/model/mep.py index bcc45920c3..6aae52ac71 100644 --- a/src/blenderbim/blenderbim/bim/module/model/mep.py +++ b/src/blenderbim/blenderbim/bim/module/model/mep.py @@ -73,29 +73,68 @@ class RegenerateDistributionElement(bpy.types.Operator, tool.Ifc.Operator): [e for e in ifcopenshell.util.system.get_connected_from(element) if e not in processed_elements] ) - if len(connected) == 1: - extend_branch(list(connected)[0], branch, element) - else: - for connected_element in connected: - branch_element["children"].append(extend_branch(connected_element, [], element)) + for connected_element in connected: + branch_element["children"].append(extend_branch(connected_element, [], element)) return branch - queue = extend_branch(current_element, [])[0]["children"] + extended_branch = extend_branch(current_element, []) + queue = extended_branch[0]["children"] # import pprint # pprint.pprint(queue) + def get_connected_ports_between(element1, element2): + ports1 = tool.System.get_ports(element1) + ports2 = tool.System.get_ports(element2) + + for p in ports1: + connected_port = tool.System.get_connected_port(p) + # in IFC2X3 there is no PredefinedType + if getattr(p, "PredefinedType", None) == "WIRELESS": + continue + if connected_port in ports2: + return p, connected_port + + return None, None + + si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + def process_branch(branch): for branch_element in branch: element = branch_element["element"] print("processing", element) predecessor = branch_element["predecessor"] - if False: # If the element does not need to be transformed, return early. - return + # Perform the extend, translate, rotate, etc the element as necessary based on the predecessor. - # For segments, prioritise extensions instead of translations. - # For everything else, only translate. No rotation. + # For everything besides segments, only translate. No rotation. + + obj = tool.Ifc.get_object(element) + obj_pred = tool.Ifc.get_object(predecessor) + if tool.Ifc.is_moved(obj): + blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) + if tool.Ifc.is_moved(obj_pred): + blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj_pred) + + port, port_pred = get_connected_ports_between(element, predecessor) + port_matrix_pred = tool.Model.get_element_matrix(port_pred) + + # Only segments can be extended + # extension for them takes priority over translation + if element.is_a("IfcFlowSegment"): + DumbProfileJoiner().join_E(obj, port_matrix_pred.translation * si_conversion) + context.view_layer.update() # update since extrusion might involve changing object's location + + port_martix = tool.Model.get_element_matrix(port) + port_location = port_martix.translation + port_location_pred = port_matrix_pred.translation + if not tool.Cad.are_vectors_equal(port_location, port_location_pred): + obj.location += (port_location_pred - port_location) * si_conversion + context.view_layer.update() # otherwise tool.Ifc.is_moved won't get triggered + else: + # If the element does not need to be transformed, return early. + return + for child_branch in branch_element["children"]: process_branch(child_branch) @@ -229,6 +268,10 @@ class MEPGenerator: if port_position == "end_port": tool.Model.edit_element_placement(port, end_port_matrix) + continue + + # NOTE: currently this functionality is moved to bim.regenerate_distribution_element + connected_port = tool.System.get_connected_port(port) if not connected_port: continue diff --git a/src/blenderbim/blenderbim/bim/module/system/operator.py b/src/blenderbim/blenderbim/bim/module/system/operator.py index e3a35e3670..71336ec7fb 100644 --- a/src/blenderbim/blenderbim/bim/module/system/operator.py +++ b/src/blenderbim/blenderbim/bim/module/system/operator.py @@ -240,14 +240,10 @@ class MEPConnectElements(bpy.types.Operator, Operator): self.report({"ERROR"}, "Couldn't find free ports to connect.") return - def get_element_matrix(element): - placement = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement) - return Matrix(placement) - for port1 in obj1_ports: - port1_location = get_element_matrix(port1).translation + port1_location = tool.Model.get_element_matrix(port1).translation for port2 in obj2_ports: - port2_location = get_element_matrix(port2).translation + port2_location = tool.Model.get_element_matrix(port2).translation if tool.Cad.are_vectors_equal(port1_location, port2_location): core.connect_port(tool.Ifc, port1, port2) return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/tool/model.py b/src/blenderbim/blenderbim/tool/model.py index 705ca56710..a4e9295d72 100644 --- a/src/blenderbim/blenderbim/tool/model.py +++ b/src/blenderbim/blenderbim/tool/model.py @@ -768,6 +768,11 @@ class Model(blenderbim.core.tool.Model): return tool.Ifc.run("geometry.edit_object_placement", product=element, matrix=matrix, is_si=True) + @classmethod + def get_element_matrix(cls, element): + placement = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement) + return Matrix(placement) + @classmethod def reload_body_representation(cls, obj_or_objects): """Update body representation including all decomposed objects"""