Use Cases: Which Script to Start From ===================================== Each script of ``scripts/`` answers one routing question on a known case. This page starts from what you want to do: it names the script to start from, the page that explains it, and what to change to make the case yours. :doc:`scripts` lists the same scripts folder by folder, with the data they read. .. contents:: On this page :local: :depth: 1 Find your use case ------------------ .. list-table:: :header-rows: 1 :widths: 38 34 28 * - You want to… - Start from - Then read * - Route your first conduits through a STEP assembly - ``simple_test_cases/window_test_case.py`` - :doc:`tutorials/basic_routing` * - Route through the inside of a closed body - ``simple_test_cases/cube_case.py`` - :doc:`tutorials/routing_inside_volume` * - Impose bend, slope, straight length or clamping on a pipe type - ``simple_test_cases/constraint_rules_example.py`` - :doc:`tutorials/design_rules` * - Write a design rule of your own - ``simple_test_cases/constraint_rules_example.py``, then ``labyrinth_toggled_constraint.py`` - :doc:`user_guide/design_rules_reference` * - Let one volume impose its weights around itself - ``simple_test_cases/weighting_overwrite_case.py`` - :doc:`user_guide/core_concepts` * - Attract, repel or forbid routes in a region of space - ``simple_test_cases/shaped_zone_example.py`` - :doc:`tutorials/shaped_zones` * - Force conduits through mandatory passages - ``simple_test_cases/window_forced_zones.py`` - :ref:`shaped-zones-forced` * - Lay conduits side by side in trays on floors, walls and ramps - ``parallel_packs/ramp_room_test_case.py`` - :ref:`pooling-trays` * - Gather compatible conduits in bundles, keep the others apart - ``parallel_packs/ramp_room_test_case.py`` with ``model = "generic"`` - :doc:`user_guide/pooling` * - Tap a conduit with a tee - ``route_planning/window_tees.py`` - :doc:`tutorials/tee_routing` * - Choose where tees tap, compare sites, optimize some conduits only - ``route_planning/window_tees_by_hand.py`` - :doc:`tutorials/tee_routing` * - Route a large assembly, fine grids only where needed - ``simple_test_cases/large_room_with_obstacles.py`` - :doc:`tutorials/large_room_obstacles`, :doc:`user_guide/multi_scale` * - Read pipe types and specifications from Excel or CSV - ``simple_test_cases/specification_from_spreadsheet.py`` - :doc:`tutorials/specification_from_spreadsheet` * - Read ports from Excel - The tutorial holds the code - :doc:`tutorials/port_import_excel` * - Turn routed cables into one optimized harness - ``electrical_harness/consolidate_topology_window_case.py`` - :doc:`user_guide/harness_generation` * - Run an industrial case end to end - ``otter_test_cases/DAR_test_case.py``, ``grit_test_case/GRIT_test_case.py`` - :ref:`use-cases-industrial` * - Search paths in a plain 3D grid, without CAD - The tutorials hold the code - :doc:`tutorials/pathfinding_basic`, :doc:`tutorials/theta_star` Every path above is relative to ``scripts/``. Most scripts open a 3D view at the end; the ones that optimize take minutes where generation alone takes seconds. First routing on a CAD assembly ------------------------------- **Start from** ``simple_test_cases/window_test_case.py``: the full pipeline on the window case — a STEP assembly of two volumes and twenty conduits. It loads the CAD, attaches a :class:`~routing.core.design_rules.WeightingRule` to each volume, builds the :class:`~routing.core.cadmap.CadMap`, generates the routes, pools them as trays, draws them and optimizes their geometry. The pipe types and port couples live in ``window_input_data.py``, a module the script imports. **Smaller**: ``simple_test_cases/cube_case.py`` routes one conduit around a cube, then through it with ``voxel_inside=True``. **Make it yours**: replace the STEP file and ``window_input_data.py`` with your assembly and your conduits; keep ``voxel_size`` coarse until the routes look right. Constraints and rules of your own --------------------------------- **Start from** ``simple_test_cases/constraint_rules_example.py``: clamping, minimum straight length and slope set on the pipe types (:class:`~routing.core.design_rules.ClampingConstraint`, :class:`~routing.core.design_rules.StraightLengthRule`, :class:`~routing.core.design_rules.GravityRule`), a :class:`~routing.core.design_rules.DistanceAttributeToggler` switching a constraint on near a volume, and a :class:`~routing.core.design_rules.ConstraintRule` written from scratch. The optimization is off: set ``RUN_OPTIMIZATION`` to run it. **Further**: ``simple_test_cases/labyrinth_toggled_constraint.py`` prices a custom length rule on a toggled attribute, on one grid and on coarse and fine grids, and checks what the search counted and charged. Weights around volumes ---------------------- **Start from** ``simple_test_cases/weighting_overwrite_case.py``: the window case where the outer volume imposes its own weights up to 0.1 m from itself (``RuledVolume(overwrite_distance=0.1)``), whatever the other volumes weigh there, then the same routing without the override to measure what it changed. Generation only. The inside of a closed body is a routing space too: see ``cube_case.py`` above. Zones and forced passages ------------------------- **Start from** ``simple_test_cases/shaped_zone_example.py``: an attractive and a repulsive :class:`~routing.core.design_rules.WeightedZone`, a :class:`~routing.core.design_rules.ForbiddenZone` that cuts the ports it catches, and a :class:`~routing.core.design_rules.ForcedZone` every conduit goes through. ``shaped_zone_example_multi.py`` and ``shaped_zone_example_multi_scale.py`` run the same zones on a decomposed map. **Forced passages, measured**: ``simple_test_cases/window_forced_zones.py`` forces the window case through three zones and routes it again without them: for each conduit, the order it passed the zones, the tunnel it took, its length and its detour. Pooling: bundles and trays -------------------------- **Start from** ``parallel_packs/ramp_room_test_case.py``: a room with a floor, two walls, a ramp up to a mezzanine and obstacles, and 36 conduits of four diameters leaving, crossing and joining it. They are pooled as trays resting on the faces flagged ``support=True``; ``model = "generic"`` gathers the same conduits in bundles instead, to compare. ``max_layers`` and ``aspect`` shape the trays, ``decomposition`` switches between one grid, grids at one voxel size and coarse and fine grids, and ``inspect_conduit`` replays the routing up to one conduit to show the field the packs paint for it. The room and the conduits live in ``ramp_room_geometry.py`` and ``ramp_room_specifications.py``. **On known cases**: ``parallel_packs/window_parallel_packs.py`` and ``parallel_packs/large_room_with_obstacles.py`` pool the window case and the large room as trays, generation only. **Loops**: the window scripts that pool in bundles — ``window_test_case_multi.py``, ``window_forced_zones.py``, ``weighting_overwrite_case.py`` — set ``PoolingRule(allow_loops=False)``: a route that rejoins a bundle it has left pays the rule's ``cost``, following a bundle or branching off it stays free (see :ref:`pooling-loops`). Tees ---- **Start from** ``route_planning/window_tees.py``: four conduits and seven tees given in disorder — one tapping at a declared site, one explored every 0.3 m, a tee tapping a tee — planned, generated, optimized and summarized in three calls. The inputs live in ``route_planning/window_tees_base.py``. **By hand**: ``route_planning/window_tees_by_hand.py`` holds the cycle itself — the conduits generated with two paths each, one of them standing by its second path, then optimized; the tees declared on the routed conduits, generated and optimized alone; last, a tee explored site by site before it is laid, picked near a point and optimized alone. Large assemblies, multi-grid and multi-scale -------------------------------------------- **Start from** ``simple_test_cases/large_room_with_obstacles.py``: a large room of fixed and mobile obstacles on coarse and fine grids, its conduits pooled as trays. **One case, three decompositions**: ``window_test_case_multi.py`` cuts the window map into grids at one voxel size, ``window_test_case_multi_scale.py`` completes a coarse grid with a finer one and searches with Theta*. ``window_forced_zones.py``, ``window_tees_base.py`` and ``ramp_room_test_case.py`` hold a ``decomposition`` switch that runs the same case on one grid, on grids at one voxel size, or on coarse and fine grids. Spreadsheet inputs ------------------ **Start from** ``simple_test_cases/specification_from_spreadsheet.py``: pipe types and specifications read from one Excel workbook, or from two CSV files, into a list of :class:`~routing.core.core.Specification` ready to route. No CAD involved. Ports alone come from Excel through :meth:`~routing.core.core.Port.from_xlsx_stream`: see :doc:`tutorials/port_import_excel`. Electrical harness ------------------ **Start from** ``electrical_harness/consolidate_topology_window_case.py``: one :meth:`~routing.core.route_planner.RoutePlanner.generate_harness` call on the window case — route, bundle into a harness of branches and junctions, optimize its geometry. ``--smoke`` runs it on a tiny optimization budget, ``--headless`` skips the 3D view. **On a real product**: ``grit_test_case/GRIT_test_case.py`` extracts the ports from the connectors' CAD and runs the same pipeline on many cables. .. _use-cases-industrial: Industrial cases ---------------- These scripts read real assemblies and open their files relative to the working directory: run them from their own folder. - ``otter_test_cases/DAR_test_case.py`` — a multi-part assembly read from STEP, its ports, pipes and cables read from Excel nomenclatures; clamping set per pipe type, trays per fixation type, then optimization. ``DAR_test_case_multi_grid.py`` and ``DAR_test_case_multi_scale.py`` run it on a decomposed map. The first run caches the voxelized CAD in ``processed_data/``. - ``building_test_case/building_test_case.py`` — two cables across a 12.5 m room with obstacles, routed inside the room volume. - ``grit_test_case/GRIT_test_case.py`` — the harness pipeline above; its first run needs ``vtk`` to decimate the CAD. Pathfinding without CAD ----------------------- The pathfinding engine searches any 3D weight grid. No script covers it: the code of :doc:`tutorials/pathfinding_basic` and :doc:`tutorials/theta_star` runs as it stands. Make a script your own ---------------------- - **Copy the closest script** into your package and change one thing at a time; keep the original to compare the routes. - **Keep the case out of the routing script.** The scripts import their geometry and their conduits from modules of their own (``window_input_data.py``, ``window_tees_base.py``, ``ramp_room_geometry.py`` and ``ramp_room_specifications.py``), so that the script shows the routing only. Do the same with your CAD and your specifications. - **Generate first, optimize last.** The optimization multiplies the run time: comment it out until the generated routes are the ones you want. - **Choose the voxel size yourself.** It sets the narrowest passage the router sees and the size of the search: halving it multiplies the cells by eight. - **Read the result before drawing it.** ``print(result.summary())`` shows one line per conduit, and ``result.routed_solutions`` leaves out the conduits no route joins (see :doc:`user_guide/results_access`).