From 7c99dfc5fcdc40add7762035e51369352a85d682 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sat, 29 Nov 2025 23:27:39 -0500 Subject: [PATCH] implement most of op.area surface linear --- src/kiri/mode/cam/op-area.js | 127 +++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 4 deletions(-) diff --git a/src/kiri/mode/cam/op-area.js b/src/kiri/mode/cam/op-area.js index dff124ac..14e1ed9b 100644 --- a/src/kiri/mode/cam/op-area.js +++ b/src/kiri/mode/cam/op-area.js @@ -2,8 +2,8 @@ import { CamOp } from './op.js'; import { Tool } from './tool.js'; -import { generate as Topo } from './topo3.js'; import { newSlice } from '../../core/slice.js'; +import { newPoint } from '../../../geo/point.js'; import { newPolygon } from '../../../geo/polygon.js'; import { polygons as POLY } from '../../../geo/polygons.js'; import { util as base_util } from '../../../geo/base.js'; @@ -11,6 +11,10 @@ import { calc_normal, calc_vertex } from '../../../geo/paths.js'; import { CAM } from './driver-be.js'; const DEG2RAG = Math.PI / 180; +const clib = self.ClipperLib; +const ctyp = clib.ClipType; +const ptyp = clib.PolyType; +const cfil = clib.PolyFillType; class OpArea extends CamOp { constructor(state, op) { @@ -31,8 +35,6 @@ class OpArea extends CamOp { let zTop = ov_topz ? workarea.bottom_stock + ov_topz : workarea.top_stock; let zBottom = ov_botz ? workarea.bottom_stock + ov_botz : workarea.bottom_part; - console.log({ workarea, zTop, zBottom }); - setToolDiam(toolDiam); // selected area polygons: surfaces and edges @@ -195,11 +197,72 @@ class OpArea extends CamOp { if (mode === 'surface') { let { sr_type, sr_angle, tolerance } = op; + let resolution = tolerance || 0.05; + let raster = await self.get_raster_gpu({ mode: "tracing", resolution }); + let paths = []; + + // prepare paths if (sr_type === 'linear') { - console.log({ sr_angle }); + // scan the area bounding box with rays at defined angle + let scan = scanBoxAtAngle(bounds, sr_angle * DEG2RAG, toolOver); + let lines = scan.map(line => { + let { a, b } = line; + return [ newPoint(a.x, a.y, 0).toClipper(), newPoint(b.x, b.y, 0).toClipper() ] + }); + // use clipper to clip lines to the area polygon + let clip = new clib.Clipper(); + let ctre = new clib.PolyTree(); + clip.AddPaths(lines, ptyp.ptSubject, false); + clip.AddPaths(POLY.toClipper([ area ]), ptyp.ptClip, true); + if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftEvenOdd)) { + for (let node of ctre.m_AllPolys) { + paths.push(POLY.fromClipperNode(node, 0)); + } + } + // convert resulting poly lines to raster float32 array groups + paths = paths.map(poly => poly.points.map(p => [ p.x, p.y ]).flat().toFloat32()); } else if (sr_type === 'offset') { + // progressive inset from perimeter + console.log({ sr_offset: toolOver }); + } + // prepare tool mesh points + let toolBounds = new THREE.Box3() + .expandByPoint({ x: -toolDiam/2, y: -toolDiam/2, z: 0 }) + .expandByPoint({ x: toolDiam/2, y: toolDiam/2, z: 0 }); + let toolPos = areaTool.generateProfile(resolution).profile.slice(); + for (let i=0; i