nx_slice_contour.nx
buildroot/runtime/nx_slice_contour.nx
about
nx_slice_contour.nx -- assemble nx_slice_plane segment soup into
closed NxPolygon contours via endpoint-adjacency walk.
Algorithm (per layer):
for each unvisited segment S:
start a polygon with S.A as first vertex, S.B as second
mark S visited
current_endpoint = S.B
loop:
find another unvisited segment T whose endpoint matches
current_endpoint
if T found:
add T's OTHER endpoint to polygon
mark T visited
current_endpoint = T's other endpoint
else:
contour is OPEN (dangling segment chain) -- emit as open
polygon with verdict set; slicer caller decides handling
if current_endpoint == S.A (start):
contour CLOSED -- emit as closed polygon
end for
Complexity: O(n²) per layer. At slicer-typical 10K segments/layer
this is ~100M ops -- well within seconds for a 100-layer slice.
Per cardinal feedback-bits-up-exceed-never-match: O(n) hash-based
version queued as P2.2.opt for after this primitive's semantics
have been compile-validated. Correctness first, perf second --
per "bad prints = massive waste of time and resources" directive.
Composes nx_slice_plane (segment soup input) + nx_polygon (closed
contour output). No new substrate primitives needed.
Manifold expectation: a well-formed closed STL produces a soup
where every endpoint is shared by EXACTLY two segments. The
walk terminates by returning to the start vertex. Non-manifold
or open-mesh input produces dangling chains and gets flagged
via NX_SLICE_CONTOUR_ERR_OPEN.
license_tier: ORIGINAL
dependencies 3 imports · 19 importers
diagram shows first 10 each side; +0 more imports, +9 more importers in the complete lists below.
imports: nx_syscalls.nxnx_polygon.nxnx_slice_plane.nx
imported by: nx_bedmesh_emit_test.nxnx_cad_exceed.nxnx_cad_prims2_test.nxnx_cad_test.nxnx_csg_fillet_test.nxnx_csg_scene_gate.nxnx_csg_test.nxnx_csg_torus_test.nxnx_dcc_slice_watertight_gate.nxnx_gcode_arc_test.nxnx_gcode_brim_test.nxnx_gcode_emit.nxnx_gcode_emit_test.nxnx_print_e2e_gate.nxnx_slice_auto_supports.nxnx_slice_contour_test.nxnx_slice_layer_probe.nxnx_slice_pipeline.nxnx_underridge_cleaner_gate.nx
structs
| 60 | struct NxSliceContours |
consts
| 47 | const NX_SLICE_CONTOUR_OK: i64 = 0 |
| 48 | const NX_SLICE_CONTOUR_ERR_OPEN: i64 = 1 |
| 49 | const NX_SLICE_CONTOUR_ERR_EMPTY: i64 = 2 |
| 68 | const NX_SLICE_CONTOURS_BYTES: i64 = 40 |
functions
| 51 | func nx_slice_contour_verdict_name(v: i64) -> *u8 |
| 70 | func nx_slice_contours_new(capacity: i64) -> *NxSliceContours |
| 80 | func nx_slice_contours_get(c: *NxSliceContours, i: i64) -> *NxPolygon |
| 85 | func nx_slice_contours_put(c: *NxSliceContours, i: i64, p: *NxPolygon) -> i64 |
| 93 | func nx_slice_seg_x1(s: *NxSliceSoup, i: i64) -> i64 |
| 97 | func nx_slice_seg_y1(s: *NxSliceSoup, i: i64) -> i64 |
| 101 | func nx_slice_seg_x2(s: *NxSliceSoup, i: i64) -> i64 |
| 105 | func nx_slice_seg_y2(s: *NxSliceSoup, i: i64) -> i64 |
| 118 | func nx_slice_find_neighbour(soup: *NxSliceSoup, visited: *u8, called by 1: nx_slice_walk_one calls 4: nx_slice_seg_x1nx_slice_seg_y1nx_slice_seg_x2nx_slice_seg_y2 |
| 153 | func nx_slice_walk_one(soup: *NxSliceSoup, visited: *u8, |
| 234 | func nx_slice_contour_build(soup: *NxSliceSoup) -> *NxSliceContours |