Перейти до основного вмісту

raygeo.geo.algo.nest2d.placement

Placement search for nesting algorithms.

Provides candidate generation strategies (bottom-left, grid, perimeter), position search, and high-level nesting orchestration.

Functions

calculate_fitness()

calculate_fitness(
polygon_groups: Sequence[Sequence[numpy.ndarray]],
rotations: Sequence[float],
sheet_indices: Sequence[int],
*,
num_parts: int = 0,
) -> float

Calculate fitness score for a set of placements.

Lower is better. Returns infinity if no placements or zero area.

ParameterTypeDescription
polygon_groupsSequence[Sequence[numpy.ndarray]]Polygons for each placement.
rotationsSequence[float]Rotation angle in degrees for each placement.
sheet_indicesSequence[int]0-based sheet index for each placement.
num_partsintTotal number of parts (some may be unplaced).
ReturnsfloatFitness score (lower is better).
ComplexityO(n) where n = number of placements.

filter_candidates_multi_resolution()

filter_candidates_multi_resolution(
candidates: list[tuple[float, float]],
ifp_bounds: tuple[float, float, float, float],
min_dist: float,
) -> list[tuple[float, float]]

Remove candidates that are too close together.

ParameterTypeDescription
candidateslist[tuple[float, float]]List of (x, y) candidate positions.
ifp_boundstuple[float, float, float, float]IFP bounding box (min_x, min_y, max_x, max_y).
min_distfloatMinimum allowed distance between candidates.
Returnslist[tuple[float, float]]Filtered list of (x, y) positions.
ComplexityO(n log n) for spatial distance filtering.

find_valid_position()

find_valid_position(
ifp_polygons: Sequence[Sequence[tuple[float, float]]],
part_polygons: Sequence[Sequence[tuple[float, float]]],
part_hulls: Sequence[Sequence[tuple[float, float]]],
placed_polys_list: Sequence[Sequence[Sequence[tuple[float, float]]]],
placed_hulls_list: Sequence[Sequence[Sequence[tuple[float, float]]]],
grid: spatial_grid2d.SpatialGrid,
sheet_world_offset: tuple[float, float],
spacing: float = 1,
min_area: float = 1,
curve_tolerance: float = 0.5,
) -> tuple[float, float] | None

Find a valid position: heuristic search first, NFP fallback second.

Supports hull-based collision detection and sheet world offsets.

ParameterTypeDescription
ifp_polygonsSequence[Sequence[tuple[float, float]]]IFP polygons (valid placement region).
part_polygonsSequence[Sequence[tuple[float, float]]]Part polygons to place.
part_hullsSequence[Sequence[tuple[float, float]]]Convex hulls for collision (may be empty).
placed_polys_listSequence[Sequence[Sequence[tuple[float, float]]]]Already-placed parts, each a list of polygons.
placed_hulls_listSequence[Sequence[Sequence[tuple[float, float]]]]Hulls of already-placed parts, each a list.
gridspatial_grid2d.SpatialGridSpatialGrid for fast neighbor lookup.
sheet_world_offsettuple[float, float](offset_x, offset_y) for this sheet.
spacingfloat = 1Minimum spacing between parts.
min_areafloat = 1Minimum overlap area (clipper coords).
curve_tolerancefloat = 0.5Curve tolerance for distance filtering.
Returnstuple[float, float] | None(x, y) position or None.
ComplexityO(n * m) for candidate search with overlap checks.

find_valid_position_nfp()

find_valid_position_nfp(
ifp_polygons: Sequence[Sequence[tuple[float, float]]],
part_polygons: Sequence[Sequence[tuple[float, float]]],
part_hulls: Sequence[Sequence[tuple[float, float]]],
placed_polys_list: Sequence[Sequence[Sequence[tuple[float, float]]]],
placed_hulls_list: Sequence[Sequence[Sequence[tuple[float, float]]]],
grid: spatial_grid2d.SpatialGrid,
sheet_world_offset: tuple[float, float],
spacing: float = 1,
min_area: float = 1,
curve_tolerance: float = 0.5,
) -> tuple[float, float] | None

Find a valid position using NFP-based region subtraction.

Computes No-Fit Polygons for nearby placed parts and subtracts them from the IFP to identify viable placement regions.

ParameterTypeDescription
ifp_polygonsSequence[Sequence[tuple[float, float]]]IFP polygons (valid placement region).
part_polygonsSequence[Sequence[tuple[float, float]]]Part polygons to place.
part_hullsSequence[Sequence[tuple[float, float]]]Convex hulls for collision (may be empty).
placed_polys_listSequence[Sequence[Sequence[tuple[float, float]]]]Already-placed parts, each a list of polygons.
placed_hulls_listSequence[Sequence[Sequence[tuple[float, float]]]]Hulls of already-placed parts, each a list.
gridspatial_grid2d.SpatialGridSpatialGrid for fast neighbor lookup.
sheet_world_offsettuple[float, float](offset_x, offset_y) for this sheet.
spacingfloat = 1Minimum spacing between parts.
min_areafloat = 1Minimum overlap area (clipper coords).
curve_tolerancefloat = 0.5Curve tolerance for distance filtering.
Returnstuple[float, float] | None(x, y) position or None.
ComplexityO(n * m) for NFP construction per nearby placed part.

find_valid_position_scored()

find_valid_position_scored(
ifp_polygons: Sequence[Sequence[tuple[float, float]]],
part_polygons: Sequence[Sequence[tuple[float, float]]],
part_hulls: Sequence[Sequence[tuple[float, float]]],
placed_polys_list: Sequence[Sequence[Sequence[tuple[float, float]]]],
placed_hulls_list: Sequence[Sequence[Sequence[tuple[float, float]]]],
grid: spatial_grid2d.SpatialGrid,
sheet_world_offset: tuple[float, float],
spacing: float = 1,
min_area: float = 1,
curve_tolerance: float = 0.5,
) -> tuple[float, float] | None

Find a valid position using heuristic candidate search.

Uses IFP vertices, bottom-left sweep, grid, placed polygon vertices, and perimeter candidates. Falls back to NFP-region candidates. Scores candidates and picks the best valid one.

ParameterTypeDescription
ifp_polygonsSequence[Sequence[tuple[float, float]]]IFP polygons (valid placement region).
part_polygonsSequence[Sequence[tuple[float, float]]]Part polygons to place.
part_hullsSequence[Sequence[tuple[float, float]]]Convex hulls for collision (may be empty).
placed_polys_listSequence[Sequence[Sequence[tuple[float, float]]]]Already-placed parts, each a list of polygons.
placed_hulls_listSequence[Sequence[Sequence[tuple[float, float]]]]Hulls of already-placed parts, each a list.
gridspatial_grid2d.SpatialGridSpatialGrid for fast neighbor lookup.
sheet_world_offsettuple[float, float](offset_x, offset_y) for this sheet.
spacingfloat = 1Minimum spacing between parts.
min_areafloat = 1Minimum overlap area (clipper coords).
curve_tolerancefloat = 0.5Curve tolerance for distance filtering.
Returnstuple[float, float] | None(x, y) position or None.
ComplexityO(n * m) for scored candidate search.

generate_bottom_left_candidates()

generate_bottom_left_candidates(
ifp_bounds: tuple[float, float, float, float],
part_bounds: tuple[float, float, float, float],
spacing: float,
) -> list[tuple[float, float]]

Generate candidate positions scanning from bottom-left.

ParameterTypeDescription
ifp_boundstuple[float, float, float, float]IFP bounding box (min_x, min_y, max_x, max_y).
part_boundstuple[float, float, float, float]Part bounding box (min_x, min_y, max_x, max_y).
spacingfloatMinimum spacing between parts.
Returnslist[tuple[float, float]]List of (x, y) candidate positions.
ComplexityO(n) where n = number of grid cells scanned.

generate_grid_candidates()

generate_grid_candidates(
ifp_bounds: tuple[float, float, float, float],
part_bounds: tuple[float, float, float, float],
spacing: float,
) -> list[tuple[float, float]]

Generate candidate positions in a grid pattern.

ParameterTypeDescription
ifp_boundstuple[float, float, float, float]IFP bounding box (min_x, min_y, max_x, max_y).
part_boundstuple[float, float, float, float]Part bounding box (min_x, min_y, max_x, max_y).
spacingfloatGrid spacing.
Returnslist[tuple[float, float]]List of (x, y) candidate positions.
ComplexityO(n) where n = number of grid cells.

generate_perimeter_candidates()

generate_perimeter_candidates(
placed_groups: Sequence[Sequence[list[tuple[float, float]]]],
part_bounds: tuple[float, float, float, float],
spacing: float,
) -> list[tuple[float, float]]

Generate edge-aligned candidates around placed parts.

For each placed part (group of polygons), produces 8 positions: right-bottom, right-top, left-bottom, left-top, above-left, above-right, below-left, below-right.

ParameterTypeDescription
placed_groupsSequence[Sequence[list[tuple[float, float]]]]List of placed parts, each a list of polygons.
part_boundstuple[float, float, float, float]Part bounding box (min_x, min_y, max_x, max_y).
spacingfloatMinimum spacing between parts.
Returnslist[tuple[float, float]]List of (x, y) candidate positions.
ComplexityO(n) where n = number of placed parts.

place_parts()

place_parts(
part_polys: Sequence[Sequence[Sequence[tuple[float, float]]]],
part_hulls: Sequence[Sequence[Sequence[tuple[float, float]]]],
sheet_polys: Sequence[Sequence[tuple[float, float]]],
sheet_offsets: Sequence[tuple[float, float]],
rotations: Sequence[float],
flips_h: Sequence[bool],
flips_v: Sequence[bool],
spacing: float = 1,
min_area: float = 1,
curve_tolerance: float = 0.5,
) -> list[dict]

Place as many parts as possible onto sheets.

Supports combined IFP for multi-polygon parts, hull-based collision detection, world-space offsets per sheet, gravity post-processing, and fitness calculation.

Parts are sorted by area (largest first). For each part, the best sheet and position are selected. After all parts are placed, gravity is applied per sheet.

ParameterTypeDescription
part_polysSequence[Sequence[Sequence[tuple[float, float]]]]List of parts, each a list of polygon point lists.
part_hullsSequence[Sequence[Sequence[tuple[float, float]]]]List of hull groups per part (may be empty).
sheet_polysSequence[Sequence[tuple[float, float]]]List of sheet polygons.
sheet_offsetsSequence[tuple[float, float]]World-space offset (x, y) for each sheet.
rotationsSequence[float]Rotation angle (degrees) for each part.
flips_hSequence[bool]Horizontal flip flag per part.
flips_vSequence[bool]Vertical flip flag per part.
spacingfloat = 1Minimum spacing between parts.
min_areafloat = 1Minimum overlap area (clipper coords).
curve_tolerancefloat = 0.5Curve tolerance for distance filtering.
Returnslist[dict]List of dicts, one per sheet, with keys: placements, sheet_index, unused_part_indices, fitness.
ComplexityO(p * s * n * m) where p = parts, s = sheets.