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"""