"""Place shared calculation sources beside their peripheral distribution channels.""" def place_shared_sources(bodies, peripheral_nodes, positions, sizes, *, gap): """Place consumer regions first, then keep their producers outside and to the left.""" ordinary = [box for members, box in bodies if not members & peripheral_nodes] if not ordinary: ordinary = [(x, x + sizes[node].width, y, y - sizes[node].height) for node, (x, y) in positions.items() if node not in peripheral_nodes] ceiling = max(box[2] for box in ordinary) floor = min(box[3] for box in ordinary) for index, (members, (left, right, top, bottom)) in enumerate(bodies): if not members & peripheral_nodes: continue links = [link for node in members for socket in node.outputs for link in socket.links if link.to_node not in members and link.to_node in positions] if not links: continue height = top - bottom candidates = (ceiling + gap * 2 + height, floor - gap * 2) new_top = min(candidates, key=lambda level: (sum( abs(positions[link.to_node][1] - level + height / 2) for link in links), -level)) dy = new_top - top new_left = float("inf") for link in links: source, target = link.from_node, link.to_node source_y = positions[source][1] + dy - sizes[source].sockets[link.from_socket] target_y = positions[target][1] - sizes[target].sockets[link.to_socket] runway = (abs(source_y - target_y) + height * 2) * 0.8 + gap * 3 new_left = min(new_left, positions[target][0] - runway - (positions[source][0] - left) - sizes[source].width) dx = new_left - left for node in members: x, y = positions[node] positions[node] = (x + dx, y + dy) bodies[index] = (members, (left + dx, right + dx, top + dy, bottom + dy)) ceiling = max(ceiling, top + dy) floor = min(floor, bottom + dy)