From e86ba7d2fbcc723796b8c006a47789694bc2415e Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Tue, 15 Aug 2023 14:23:23 +0500 Subject: [PATCH] show error if transition length is more the segments length --- .../blenderbim/bim/module/model/mep.py | 21 ++++++++++++++++++- src/blenderbim/blenderbim/tool/cad.py | 15 ++++++------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/mep.py b/src/blenderbim/blenderbim/bim/module/model/mep.py index cc6294714a..d68c6d43f6 100644 --- a/src/blenderbim/blenderbim/bim/module/model/mep.py +++ b/src/blenderbim/blenderbim/bim/module/model/mep.py @@ -642,10 +642,22 @@ class MEPAddTransition(bpy.types.Operator, tool.Ifc.Operator): end_segment_data["end_point"]: end_segment_data["end_port"], } + # transition points start_point, end_point = tool.Cad.closest_points( (start_segment_data["start_point"], start_segment_data["end_point"]), (end_segment_data["start_point"], end_segment_data["end_point"]), ) + + first_segment_start, second_segment_end = [ + p for p in ( + start_segment_data["start_point"], + start_segment_data["end_point"], + end_segment_data["start_point"], + end_segment_data["end_point"]) + if p not in (start_point, end_point) + ] + entire_length = (first_segment_start - second_segment_end).length + transition_dir = (end_point - start_point).normalized() start_port = points_ports_map[start_point] end_port = points_ports_map[end_point] @@ -659,9 +671,16 @@ class MEPAddTransition(bpy.types.Operator, tool.Ifc.Operator): if not rep: self.report({"ERROR"}, f"Failed to add transition - this kind of profiles is not yet supported.") return {"CANCELLED"} + + # TODO: test it + full_transition_length = transition_data["full_transition_length"] * si_conversion + if full_transition_length >= entire_length: + self.report({"ERROR"}, f"Failed to add transition - transition length is larger the segments and the distance between them.") + # TODO: handle the case without creating representation in the first place? + ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=rep) + return {"CANCELLED"} middle_point = (start_point + end_point) / 2 - full_transition_length = transition_data["full_transition_length"] * si_conversion start_segment_extend_point = middle_point - transition_dir * full_transition_length / 2 end_segment_extend_point = middle_point + transition_dir * full_transition_length / 2 DumbProfileJoiner().join_E(start_object, start_segment_extend_point) diff --git a/src/blenderbim/blenderbim/tool/cad.py b/src/blenderbim/blenderbim/tool/cad.py index c1b1e59b60..7d0fe1bca7 100644 --- a/src/blenderbim/blenderbim/tool/cad.py +++ b/src/blenderbim/blenderbim/tool/cad.py @@ -252,7 +252,7 @@ class Cad: return False @classmethod - def closest_points(cls, edge1, edge2): + def closest_points(cls, edge1, edge2) -> bool: """ closest end points between `edge1` and `edge2` assuming `edge1` and `edge2` are collinear. @@ -263,15 +263,12 @@ class Cad: direction = (edge1[1] - edge1[0]).normalized() # Project points onto the line to get scalar values along the direction - points1_values = [(p, p.dot(direction)) for p in edge1] - points2_values = [(p, p.dot(direction)) for p in edge2] + points_values = [(p, p.dot(direction)) for p in (edge1 + edge2)] + sorted_points = sorted(points_values, key=lambda el: el[1]) - # Sort the projections for both edges - sorted_points1 = sorted(points1_values, key=lambda el: el[1]) - sorted_points2 = sorted(points2_values, key=lambda el: el[1]) - - # The closest points will be the last point of the first edge and the first point of the second edge - return sorted_points1[-1][0], sorted_points2[0][0] + edge1_point = next((p for p, v in sorted_points[1:3] if p in edge1), None) + edge2_point = next((p for p, v in sorted_points[1:3] if p in edge2), None) + return edge1_point, edge2_point @classmethod def find_intersecting_edges(cls, bm, pt, idx1, idx2):