Tutorial: Routing Inside a Closed Volume#
By default a RuledVolume voxelizes only the shell of a solid:
the volume acts as an obstacle and pipes are routed around it. Sometimes you want the
opposite — to route a pipe through the interior of a closed body, such as a chamber, a
duct or an enclosure. Setting voxel_inside=True fills the enclosed voxels so the solver
can route inside the solid.
This tutorial contrasts the two modes on a single cube: one route outside it, one route
through it. The runnable version is scripts/simple_test_cases/cube_case.py.
The voxel_inside Flag#
from_volume_model() accepts a voxel_inside flag:
|
Behavior |
|---|---|
|
Only the solid’s surface is voxelized. The body is an obstacle; pipes route around it. |
|
Enclosed voxels are filled. The interior becomes routable space; pipes can pass through. |
Routing Outside the Cube (default)#
With ports placed just outside the cube and the volume left as an obstacle
(voxel_inside defaults to False), the pipe routes around the body:
ruled_volume = RuledVolume.from_volume_model(volume_model, [weighting_rule],
name="cubic_volume")
input_port = Port(coordinates=(0.11, 0, 0), direction=(1, 0, 0), length=0.02)
output_port = Port(coordinates=(-0.11, 0, 0), direction=(-1, 0, 0), length=0.02)
specifications = [Specification(input_port, output_port, pipe_type, "test")]
ports_prims = [input_port.volmdlr_primitives(radius=0.01),
output_port.volmdlr_primitives(radius=0.01)]
ports_model = RuledVolume.from_volume_model(VolumeModel(ports_prims), [], name="ports")
bounding_box = CadMap.build_bounding_volume(
[ruled_volume, ports_model], [], voxel_size, voxel_margin=30
)
cadmap = CadMap.from_project_inputs(
design_rules=design_rules, ruled_volumes=[ruled_volume],
bounding_box=bounding_box, voxel_size=voxel_size, exact_distances=True,
weights_operator="min_distance", build_cad=False,
)
finder = SmartFinder("AStar", "manhattan", "never")
routing_result = RoutePlanner(cadmap, finder).generate(specifications, 0, False)
routing_result.display_3d()
Routing Through the Cube (voxel_inside=True)#
Now place the ports inside the cube and rebuild the RuledVolume with
voxel_inside=True so the interior is routable. Note the voxel_margin=0 — the route
stays within the body:
input_port = Port(coordinates=(0.1, 0, 0), direction=(-1, 0, 0), length=0.005)
output_port = Port(coordinates=(-0.1, 0, 0), direction=(1, 0, 0), length=0.005)
specifications = [Specification(input_port, output_port, pipe_type, "test")]
ports_prims = [input_port.volmdlr_primitives(radius=0.01),
output_port.volmdlr_primitives(radius=0.01)]
ports_model = RuledVolume.from_volume_model(VolumeModel(ports_prims), [], name="ports")
bounding_box = CadMap.build_bounding_volume(
[ruled_volume, ports_model], [], voxel_size, voxel_margin=0
)
ruled_volume = RuledVolume.from_volume_model(
volume_model, [weighting_rule], voxel_inside=True, name=""
)
cadmap = CadMap.from_project_inputs(
design_rules=design_rules, ruled_volumes=[ruled_volume],
bounding_box=bounding_box, voxel_size=voxel_size, exact_distances=True,
weights_operator="min_distance", build_cad=True,
)
finder = SmartFinder("AStar", "manhattan", "never")
routing_result = RoutePlanner(cadmap, finder).generate(specifications, 0, False)
routing_result.display_3d()
The only change that switches outside vs inside routing is the voxel_inside flag on
from_volume_model (together with placing the ports inside the body and using a zero
voxel margin).
Next Steps#
Tutorial: Routing Pipes Through a CAD Assembly — the full routing workflow.
Tutorial: Routing in Large Spaces with Obstacles — routing around obstacles in an open space.
Core Concepts —
RuledVolumeandCadMapreference.