Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Business modules

Explanation

Nesting engine

What the nesting/engine package does in code, geometry types, transforms, and SVG and DXF output, and where layouts really come from.

The package src/cluster_erp/modules/nesting/engine/ holds the geometry code of the nesting module: shared geometry types, polygon transforms, a DXF reader, a DXF writer, and an SVG writer. At this commit it contains no placement algorithm; layouts come from an external nesting tool through the import route. This page explains what the package does, how the module uses it, and what is stored but not used. The import itself is on integration and KPI.

In short

  • The package has five files: types.py, transforms.py, dxf_reader.py, dxf_writer.py, and svg_writer.py (folder listing of src/cluster_erp/modules/nesting/engine/).
  • No function in the package places parts on a sheet. The job summary states that results only come from an external tool and shows the tool's name instead of the stored algorithm (src/cluster_erp/modules/nesting/nesting_jobs/services.py:827-834).
  • The import check uses the transforms to rebuild each placed outline and to reject parts outside the sheet or overlapping (src/cluster_erp/modules/nesting/integration/services.py:48-106).
  • The drawing routes rebuild placements from the stored layout and render them as SVG or DXF (src/cluster_erp/modules/nesting/nesting_jobs/routes.py:33-118, src/cluster_erp/modules/nesting/nesting_jobs/routes.py:307-396).

How it works

Geometry types

types.py defines frozen and plain dataclasses that carry geometry between the module and the writers (src/cluster_erp/modules/nesting/engine/types.py:12-142):

Type Holds Source
SheetGeom Sheet width and height, edge margin, kerf, part gap; usable size and area src/cluster_erp/modules/nesting/engine/types.py:12-36
PartGeom Part id, label, outline, quantity, allowed rotations, priority, mirror flag src/cluster_erp/modules/nesting/engine/types.py:39-61
Placement Placed instance: part id, instance number, x, y, rotation, mirror flag, outline, sheet index src/cluster_erp/modules/nesting/engine/types.py:64-84
RemnantRect A leftover rectangle on a sheet src/cluster_erp/modules/nesting/engine/types.py:87
SheetResult, NestResult Per-sheet and whole-run result containers src/cluster_erp/modules/nesting/engine/types.py:109-142

Transforms

transforms.py wraps Shapely affine operations: rotate about the centroid, translate, mirror, move the outline so that its bounding box starts at the origin, area, bounding box, buffer, and conversion between polygons and coordinate lists (src/cluster_erp/modules/nesting/engine/transforms.py:9-88). rotate_and_normalize rotates and then moves the outline back to the origin (src/cluster_erp/modules/nesting/engine/transforms.py:84-88). make_rect builds a rectangle for a part that has no outline (src/cluster_erp/modules/nesting/engine/transforms.py:68-69).

Rebuilding a stored layout

The diagram shows how a drawing is produced from a stored job.

flowchart LR
 J["NestingJob.layout_placements"] --> R["_reconstruct_placements"]
 P["NestingPart.geometry_polygon or part size"] --> R
 R --> T["mirror_polygon, rotate_and_normalize, translate_polygon"]
 T --> S["render_svg or render_multi_sheet_svg"]
 T --> D["write_multi_sheet_dxf"]

In prose: _reconstruct_placements builds a SheetGeom from the job and, for each stored placement, takes the part's true outline when it has one, else a rectangle of the part's length and width (src/cluster_erp/modules/nesting/nesting_jobs/routes.py:45-82). It mirrors the outline if the placement is mirrored, rotates and normalises it, and moves it to the placement's x and y (src/cluster_erp/modules/nesting/nesting_jobs/routes.py:84-90). GET /nesting-jobs/{id}/svg returns the stored layout_svg when there is one; otherwise it renders all sheets, or one sheet when sheet_index is given (src/cluster_erp/modules/nesting/nesting_jobs/routes.py:307-361). GET /nesting-jobs/{id}/dxf writes a multi-sheet DXF (src/cluster_erp/modules/nesting/nesting_jobs/routes.py:364-396).

Writers

  • The DXF writer puts the sheet outline, the parts, labels, and remnants on four named layers (src/cluster_erp/modules/nesting/engine/dxf_writer.py:19-27, src/cluster_erp/modules/nesting/engine/dxf_writer.py:30).
  • The SVG writer draws each sheet with its margin, parts coloured by part id, labels, and remnants (src/cluster_erp/modules/nesting/engine/svg_writer.py:14-41, src/cluster_erp/modules/nesting/engine/svg_writer.py:147-239).

Why it is built this way

The code states two reasons. The job summary says that results only come from an external tool, so showing the built-in algorithm value would misrepresent how the nest was made (src/cluster_erp/modules/nesting/nesting_jobs/services.py:827-829). The import says that the external tool read the source DXF and is the system of record for the part outline (src/cluster_erp/modules/nesting/integration/services.py:214-216). Beyond these comments, rationale not determined from code.

Rules and boundaries

  • Geometry is computed with floating-point Shapely objects; areas that leave the engine are converted to Decimal through strings (src/cluster_erp/modules/nesting/engine/types.py:49-61, src/cluster_erp/modules/nesting/integration/services.py:31-45). Money is not computed in the engine.
  • The overlap and inside-sheet check runs only when every placed part has a true outline, because a bounding-box check would reject interlocked shapes (src/cluster_erp/modules/nesting/integration/services.py:53-64).

Interaction with other parts

The engine is used only inside the nesting module: by the import check (src/cluster_erp/modules/nesting/integration/services.py:68-73) and by the drawing routes (src/cluster_erp/modules/nesting/nesting_jobs/routes.py:36-43, src/cluster_erp/modules/nesting/nesting_jobs/routes.py:328-371). No contract carries engine types. The web layout viewer loads the SVG route; see nesting module.

Limits and open points

  • read_part_geometry in dxf_reader.py turns DXF entities into an outline (src/cluster_erp/modules/nesting/engine/dxf_reader.py:24-56). A grep for read_part_geometry in src/ and tests/ finds no caller.
  • SheetResult and NestResult are referenced only inside types.py (grep).
  • The job columns algorithm (default heuristic), ga_population_size, ga_generations, and ga_mutation_rate are stored (src/cluster_erp/modules/nesting/nesting_jobs/models.py:56-60, src/cluster_erp/modules/nesting/nesting_jobs/models.py:156-173). A grep for the three ga_ names finds no use outside the model and the schemas.
  • The default result_source is built_in; an import sets it to external (src/cluster_erp/modules/nesting/nesting_jobs/models.py:215-219, src/cluster_erp/modules/nesting/integration/services.py:323).

Terms introduced

Term Code identifier Definition Turkish term Source
placement Placement One placed instance of a part on a sheet, with position, rotation, and mirror flag. Yerleşim konumu src/cluster_erp/modules/nesting/engine/types.py:65
sheet geometry SheetGeom Sheet size with edge margin, kerf, and part gap. Levha geometrisi src/cluster_erp/modules/nesting/engine/types.py:13
result source result_source Whether a job's layout is built_in or external. Sonuç kaynağı src/cluster_erp/modules/nesting/nesting_jobs/models.py:215

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13