Repository navigation
Conversation
vespakoen
marked this pull request as ready for review
October 17, 2026 10:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
note: vibe coded with chatgpt astra xhigh
Remove Boost from OpenCAMLib's source and build dependencies, replace its graph and TSP implementations with code maintained in the project, and reduce copying and temporary allocations throughout cutter execution. Add parallel processing of independent adaptive path spans and fix OpenMP runtime loading on macOS.
The main performance changes are a KD-tree that copies each triangle once and visits query candidates directly, cheaper waterline interval/contact handling, and parallel adaptive path drop-cutter. Cutter contact equations, sampling defaults, and adaptive flatness criteria are retained.
Algorithms and data structures
src/common/halfedgediagram.hpp)HEDIGraphbacked by Boost's adjacency list.out_edges_view()supports traversal without allocating a snapshot.src/algo/{simple_weave,smart_weave,weave}.cpp)src/algo/tsp.hpp)src/common/{kdtree,kdnode}.hpp)visit()/visit_cutter_overlap()invoke callbacks on tree-owned triangles. The default batch/point drop-cutter and batch/fiber push-cutter execution paths use these visitors. Existing owning search APIs remain available. Preserve hi-before-lo traversal and candidate order, including equal-height contact selection.BOOST_FOREACH,boost::tie, and Boost floating-point classification.std::tie, andstd::isnan, using the existing C++14 toolchain.ocl::hedistands for half-edge diagram. It is the existing OpenCAMLib abstraction, now implemented directly in the project. Storage, adjacency operations, and traversal can be tuned locally without depending on Boost Graph.Allocation and ownership changes
Interval::updateLower()/updateUpper(), eliminating temporary heap objects.Triangle::zslice_verts().CLPointandFibercopies. Use stack objects for the adaptive-waterline sampling line/span.AdaptiveWaterline, leaked contact objects inBatchPushCutter::getCLPoints(), and the heap-allocated empty vector inOperation::getCLPoints(). The base getter still returns an empty vector; derived getters continue returning their results.swap().OpenMP: what is new and what changed
AdaptivePathDropCuttermin(requested threads, span count)workers. Each span owns its output; concatenate in original path order. A const point-drop query uses the shared read-only KD-tree and returns a local call count, combined with an OpenMP reduction. A single span remains serial.BatchDropCutter/ uniformPathDropCutterBatchPushCutter/ uniformWaterlineAdaptiveWaterlinesetThreads(1). Recursive refinement within each direction remains serial.Thread counts are scoped with
num_threads(...)instead of changing the calling thread's OpenMP default withomp_set_num_threads().setThreads(0)is normalized to one. OpenMP was already enabled by default and remains optional:USE_OPENMP=OFFkeeps serial execution, and Emscripten builds continue to disable it. Weave construction and TSP remain serial.Build, packaging, and compatibility
--install-boost,--install-boost-from-repo, and--boost-prefixinstaller flags are removed.libomploading. Native builds usebrew install libomp; cross-compilation still fetches the target architecture's bottle, relocates its dylib ID to@rpath/libomp.dylib, and re-signs it. Raw bottles retain Homebrew placeholder paths until relocated. The default macOS target architecture now follows the host.BUILD_TESTING=OFFopts out). Add the optional cutter benchmark (BUILD_BENCHMARKS=ON) and comparison script, including cylindrical, ball, bull, cone, and composite cutter selection.HEDIGraph<VertexProps, EdgeProps, FaceProps>and thehedidescriptor types. TSP tour order may differ when distances tie; its closed-tour and approximation guarantees are retained.Full original-Boost-to-current comparison
Every before measurement below is the original Boost implementation at
93c3cf3; every after measurement is the current implementation, including the latest allocation and composite-cutter changes. These are fresh direct comparisons of the complete PR.Both libraries and benchmark drivers use AppleClang 21 on macOS ARM64. Libraries are Release builds with
-O3, thin LTO, and the same OpenMP runtime; the original uses Boost 1.87.0. Each value is the median of five alternating before/after samples. Toolpath times include KD-tree setup, execution, output collection, and destruction; STL loading is excluded. Speedup is before time divided by after time.Common fixture: sampling 0.1, waterline Z=1, and 25 horizontal drop-cutter spans at Z=-1 across the model bounds. Adaptive minimum-sampling defaults are retained.
setThreadsandOMP_NUM_THREADSboth use the reported count, withOMP_DYNAMIC=FALSE. The four-thread adaptive-path results include the benefit of newly parallel spans; the original ran those spans serially. Adaptive waterline has two independent directions and therefore uses at most two workers in the current implementation.Cylindrical cutter:
CylCutter(4, 20).Tux (
gnu_tux_mod.stl):Sphere-on-plate (
sphere_on_plate.stl):Composite cutter:
CylConeCutter(2, 4, 0.7); the angle is in radians.Tux (
gnu_tux_mod.stl):Sphere-on-plate (
sphere_on_plate.stl):Focused weave and TSP workloads, also measured directly against the original Boost implementation:
Each microbenchmark sample averages 20 SimpleWeave runs, 100 SmartWeave runs, or 20 TSP runs; the table reports the median of five alternating samples. Weave workloads include fiber creation, graph construction/traversal, and output collection. The TSP workload uses the same 1,500 points generated with a fixed seed in both builds. These results are local measurements for the stated fixtures; model geometry and available cores affect speedup.
Validation
To reproduce toolpath comparisons, build the same benchmark driver against each revision's own headers/library and run:
export OMP_DYNAMIC=FALSE python3 benchmarks/compare.py build/before/cutter_benchmark build/after/cutter_benchmark stl/gnu_tux_mod.stl stl/sphere_on_plate.stl --threads 1 4 --repetitions 5 --cutter cyl --output build/cyl-comparison.json python3 benchmarks/compare.py build/before/cutter_benchmark build/after/cutter_benchmark stl/gnu_tux_mod.stl stl/sphere_on_plate.stl --threads 1 4 --repetitions 5 --cutter cyl-cone --output build/composite-comparison.jsonUse the same compiler, optimization settings, OpenMP runtime, and
OMP_DYNAMIC=FALSEfor both builds.BUILD_BENCHMARKS=ONbuilds the driver on the current branch; the original revision needs the same driver compiled separately against its Boost-enabled library.