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
This commit is contained in:
Andrej730
2023-08-10 16:30:51 +05:00
parent 631d8fcfb1
commit 2d847d1704
3 changed files with 60 additions and 16 deletions
@@ -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
@@ -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"}
+5
View File
@@ -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"""