mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
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:
@@ -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"}
|
||||
|
||||
@@ -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"""
|
||||
|
||||
Reference in New Issue
Block a user