routing.pathfinding.core.grid#

A grid: its nodes built from a weight tensor, their walkable-neighbour masks, the neighbourhood in visiting order.

class routing.pathfinding.core.grid.Grid#

Bases: object

The cells of one grid: its nodes on their frame, their walkable-neighbour masks, the attribute layout.

nodes[x][y][z] is a walkable node or None; bit k of walkable_bits[x, y, z] says the cell at NEIGHBOR_OFFSETS[k] exists and is walkable; attribute_map lays out the nodes’ toggled attributes and path state. A weight update reconciles the grid in place (reconcile()).

attribute_map#
grid_id#
lengths_size#
line_of_sight(origin: SmartGridNode, target: SmartGridNode) → cython.bint#

Whether every cell the segment origin -> target crosses (origin aside) holds a walkable node.

mean_weight_toward(origin: SmartGridNode, target: SmartGridNode, collect: list | None = None) → cython.double#

Mean weight of the nodes the segment origin -> target crosses (origin aside), target’s if none.

With collect, the cells met are appended to it as the walk meets them, so a caller that must also read what the segment crosses does not walk it a second time. Bresenham is not symmetric, so reading them here is what keeps a caller on the very cells segment_cells() would give it.

neighbors(cell: SmartGridNode, diagonal_movement: cython.int, touched: list | None = None) → list#

List the walkable neighbours of cell in the order the search visits them: axes, other grids, allowed diagonals.

With touched, the neighbours a finder has not written yet (neither opened, closed nor tested) join that list: they are the cells the finder may write from here, recorded once for the cleanup.

nodes#
reconcile(voxels: cython.long[:, :], weights: cython.double[:, :, :], attributes: cython.long[:, :], attribute_map: AttributeMap, refresh_layout: cython.bint) → None#

Create, refresh or delete the node of each of voxels from its new weight and toggled attributes.

A voxel becoming walkable gets a node; a node that stays, or that lost its weight but keeps connections to another grid, takes the new weight, walkability and attributes; a node that lost its weight and has no connection is deleted. attributes holds, per base attribute of attribute_map in its order, the attribute’s value at each voxel; with refresh_layout the grid adopts attribute_map and every kept node reallocates its attribute arrays on it.

refresh_attributes(voxels: cython.long[:, :], attributes: cython.long[:, :]) → None#

Write the toggled attributes attributes (per attribute, per voxel) on the existing nodes of voxels.

refresh_walkable_bits(walkable: object) → None#

Recompute, per cell, the mask of its walkable neighbours from the boolean tensor walkable.

segment_cells(origin: SmartGridNode, target: SmartGridNode)#

List the cells the segment origin -> target crosses, origin aside, target last; None where no node stands.

update_walkable_bits(voxels: cython.long[:, :], walkable: object) → None#

Refresh the masks after the walkability of voxels changed to walkable (one flag per voxel).

Bit k of a cell stands for the cell at offset k, so a voxel that changed rewrites that bit on each of its 26 neighbours and nothing else: the masks end as a full recomputation (refresh_walkable_bits()) would leave them, at the cost of the changed voxels only.

voxel_size#
walkable_bits#
routing.pathfinding.core.grid.build_grid_nodes(attribute_map: AttributeMap, weights: cython.double[:, :, :], grid_id: cython.int)#

Build the [x][y][z] nested lists of a grid’s nodes: a walkable node where the weight is positive, None elsewhere.