User Guide: Accessing Routing Results#

After generate() or optimize(), the RoutingResults object contains all routing solutions and visualization helpers.

RoutingResults Object#

result = route_planner.generate(specifications=specs, n_iterations=1)
# or
result = route_planner.optimize(costs=costs, settings=settings, picked_path="best")

Key attributes:

  • result.solutions — list of Solution objects, one per specification

  • result.cadmap — the CadMap used for routing

Visualizing Generated Paths#

The paths produced by generate() follow the voxel grid. Display them with:

# Interactive parallel-coordinates plot (compare all solutions)
result.plot_data_generated().plot()

This opens an interactive view where you can select which pipes to highlight and inspect their cost metrics.

Visualizing Optimized Paths#

After optimize(), display the refined geometry:

result.plot_data_optimized().plot()

The parallel plot shows per-pipe metrics including: cost, weighted_length, n_bends, deviation, sideways_cost.

3D CAD View with Packs#

collect_packs() groups pipes that share a common sub-path into packs (bundles).

# Collect packs from generated paths
packs = result.collect_packs(only_optimized=False)

# Collect packs from optimized paths (only valid after optimize())
packs = result.collect_packs(only_optimized=True)

# Open interactive 3D viewer showing pipes and packs
result.specific_packs_cad_view(packs)

specific_packs_cad_view opens a BabylonJS 3D viewer in your browser showing: - All routed pipe segments - Highlighted pack bundles - The CAD voxelization

Bifurcation Points#

Bifurcation points are the locations where a pipe bundle splits into separate branches. They are useful for placing junction boxes, tees, or connectors.

bifurcation_pts = result.cadmap.get_bifurcation_points(
    packs=packs,
    tolerance=0.04,    # grouping tolerance in metres
    with_ports=False,  # exclude port positions from the output
)

print("Bifurcation points:", bifurcation_pts)
# [array([x1, y1, z1]), array([x2, y2, z2]), ...]

tolerance controls when two nearby bifurcation candidates are merged into one. A good starting value is 2 × voxel_size.

Accessing Per-Pipe Path Data#

For programmatic access to the actual pipe coordinates, iterate over result.solutions:

all_paths = []
all_best_pipes = []
for solution in result.solutions:
    for pipe in solution.optimized_pipes:
        all_paths.append(solution.pipe.grid_path)
        all_best_pipes.extend(solution.pipe.optimized_pipes)

Note

The solutions list contains one entry per Specification. If n_iterations > 1, each solution contains multiple alternative paths; collect_packs(only_optimized=True) automatically uses the best one.

Complete Inspection Example#

from routing.core.finders import SmartFinder
from routing.core.optimizer import Costs, Settings
from routing.core.route_planner import RoutePlanner

route_planner = RoutePlanner(cadmap, SmartFinder("AStar", "manhattan", "never"))

# Generate
result = route_planner.generate(specifications=specs, n_iterations=1)

# Inspect generated paths
result.plot_data_generated().plot()
packs_gen = result.collect_packs(only_optimized=False)
result.specific_packs_cad_view(packs_gen)

# Optimize
costs = Costs(length=1000, sideways=100, short_line=5000,
              gravity=5000, bend=250, constraints=5000, interferences=1e8)
settings = Settings(voxel_size=0.01, max_shift=0.1, n_iterations=3, max_iter=1000)
result = route_planner.optimize(costs=costs, settings=settings, picked_path="best")

# Inspect optimized paths
result.plot_data_optimized().plot()
packs_opt = result.collect_packs(only_optimized=True)
result.specific_packs_cad_view(packs_opt)

# Find bifurcation points
bifurcation_pts = result.cadmap.get_bifurcation_points(
    packs_opt, tolerance=0.04, with_ports=False
)
result.cadmap.show_with_points(bifurcation_pts)

Next Steps#