|
|
|
|
@ -206,6 +206,79 @@ def _append_orthogonal(points, target_point, preferred_axis=None):
|
|
|
|
|
_append_unique(points, point)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _collinear_points(first, middle, last):
|
|
|
|
|
ax = float(middle.x) - float(first.x)
|
|
|
|
|
ay = float(middle.y) - float(first.y)
|
|
|
|
|
az = float(middle.z) - float(first.z)
|
|
|
|
|
bx = float(last.x) - float(middle.x)
|
|
|
|
|
by = float(last.y) - float(middle.y)
|
|
|
|
|
bz = float(last.z) - float(middle.z)
|
|
|
|
|
cross_x = ay * bz - az * by
|
|
|
|
|
cross_y = az * bx - ax * bz
|
|
|
|
|
cross_z = ax * by - ay * bx
|
|
|
|
|
dot = ax * bx + ay * by + az * bz
|
|
|
|
|
return (
|
|
|
|
|
abs(cross_x) <= 0.000001
|
|
|
|
|
and abs(cross_y) <= 0.000001
|
|
|
|
|
and abs(cross_z) <= 0.000001
|
|
|
|
|
and dot >= -0.000001
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _route_point_key(point, tolerance=0.001):
|
|
|
|
|
scale = 1.0 / float(tolerance or 0.001)
|
|
|
|
|
return (
|
|
|
|
|
int(round(float(point.x) * scale)),
|
|
|
|
|
int(round(float(point.y) * scale)),
|
|
|
|
|
int(round(float(point.z) * scale)),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _simplify_collinear_points(points, preserved_point_keys=None):
|
|
|
|
|
normalized = [_vector(point) for point in points or [] if _is_finite_point(_vector(point))]
|
|
|
|
|
if len(normalized) <= 2:
|
|
|
|
|
return normalized
|
|
|
|
|
preserved_indices = {0, 1, len(normalized) - 2, len(normalized) - 1}
|
|
|
|
|
preserved_point_keys = set(preserved_point_keys or [])
|
|
|
|
|
simplified = [normalized[0]]
|
|
|
|
|
simplified_indices = [0]
|
|
|
|
|
for index, point in enumerate(normalized[1:], start=1):
|
|
|
|
|
_append_unique(simplified, point)
|
|
|
|
|
if len(simplified_indices) < len(simplified):
|
|
|
|
|
simplified_indices.append(index)
|
|
|
|
|
while len(simplified) >= 3 and _collinear_points(
|
|
|
|
|
simplified[-3],
|
|
|
|
|
simplified[-2],
|
|
|
|
|
simplified[-1],
|
|
|
|
|
):
|
|
|
|
|
if (
|
|
|
|
|
simplified_indices[-2] in preserved_indices
|
|
|
|
|
or _route_point_key(simplified[-2]) in preserved_point_keys
|
|
|
|
|
):
|
|
|
|
|
break
|
|
|
|
|
simplified.pop(-2)
|
|
|
|
|
simplified_indices.pop(-2)
|
|
|
|
|
return simplified
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _important_route_node_keys(network, path_keys, path_result):
|
|
|
|
|
edges = network.get("edges", {}) if isinstance(network, dict) else {}
|
|
|
|
|
important = {
|
|
|
|
|
key
|
|
|
|
|
for key in path_keys or []
|
|
|
|
|
if len(edges.get(key, []) or []) != 2
|
|
|
|
|
}
|
|
|
|
|
segments = path_result.get("segments", []) if isinstance(path_result, dict) else []
|
|
|
|
|
for index in range(1, len(path_keys or []) - 1):
|
|
|
|
|
previous_segment = segments[index - 1] if index - 1 < len(segments) else {}
|
|
|
|
|
next_segment = segments[index] if index < len(segments) else {}
|
|
|
|
|
previous_carrier = (previous_segment.get("carrier") or {}).get("name", "")
|
|
|
|
|
next_carrier = (next_segment.get("carrier") or {}).get("name", "")
|
|
|
|
|
if previous_carrier != next_carrier:
|
|
|
|
|
important.add(path_keys[index])
|
|
|
|
|
return important
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _offset(point, direction, distance):
|
|
|
|
|
return App.Vector(
|
|
|
|
|
float(point.x) + float(direction.x) * float(distance),
|
|
|
|
|
@ -716,6 +789,10 @@ def build_network_route(start_terminal, end_terminal, route_index=0, options=Non
|
|
|
|
|
_append_unique(points, point)
|
|
|
|
|
_append_orthogonal(points, end_exit)
|
|
|
|
|
_append_unique(points, end_origin)
|
|
|
|
|
points = _simplify_collinear_points(
|
|
|
|
|
points,
|
|
|
|
|
preserved_point_keys=_important_route_node_keys(network, path_keys, path_result),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
"algorithm": "network-dijkstra-v1",
|
|
|
|
|
|