From 43a083a93a38f412403292951d91229b2e6f70b8 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Thu, 18 Sep 2025 14:42:41 -0400 Subject: [PATCH] fix ray/line. add max inset visalization --- src/geo/base.js | 12 +++--- src/geo/polygon.js | 8 +--- src/geo/polygons.js | 1 + src/kiri/mode/fdm/post.js | 85 +++++++++++++++++++++++++++++++-------- 4 files changed, 78 insertions(+), 28 deletions(-) diff --git a/src/geo/base.js b/src/geo/base.js index d7ea18bf..5406d5ab 100644 --- a/src/geo/base.js +++ b/src/geo/base.js @@ -91,11 +91,11 @@ function area2(p1, p2, p3) { } function isCloseTo(v1, v2, dist) { - return Math.abs(v1 - v2) <= (dist || base.config.precision_merge); + return Math.abs(v1 - v2) <= (dist ?? base.config.precision_merge); } -function inCloseRange(val, min, max) { - return (isCloseTo(val, min) || val >= min) && (isCloseTo(val, max) || val <= max); +function inCloseRange(val, min, max, precisiom) { + return (isCloseTo(val, min, precisiom) || val >= min) && (isCloseTo(val, max, precisiom) || val <= max); } /** @@ -232,7 +232,7 @@ function intersect(p1, p2, p3, p4, test, parallelok) { /** * used by {@link rayIntersect} and {@link Polygon.trace} */ -function intersectRayLine(ro, s1, p1, p2, infinite) { +function intersectRayLine(ro, s1, p1, p2) { let keys = base.key, p1x = ro.x, p1y = ro.y, @@ -259,11 +259,11 @@ function intersectRayLine(ro, s1, p1, p2, infinite) { a = n1 / d; b = n2 / d; - if (infinite || (inCloseRange(b, 0, 1) && a >= 0)) { + if (inCloseRange(b, 0, 1, 0.00) && a >= 0) { let ip = newPoint( p1x + (a * s1x), p1y + (a * s1y), - p2.z || ro.z, + p2.z ?? ro.z, keys.NONE ); ip.dist = a; diff --git a/src/geo/polygon.js b/src/geo/polygon.js index 846515f9..e5a3d9a6 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -2042,13 +2042,9 @@ export class Polygon { // use expand / deflate technique instead if (opt.pump) { - let p2 = POLY.offset([this], opt.pump, { - z - }); + let p2 = POLY.offset([this], opt.pump, { z }); if (p2) { - p2 = POLY.offset(p2, -opt.pump, { - z - }); + p2 = POLY.offset(p2, -opt.pump, { z }); return p2; } return null; diff --git a/src/geo/polygons.js b/src/geo/polygons.js index fcbd1303..1d5c5212 100644 --- a/src/geo/polygons.js +++ b/src/geo/polygons.js @@ -871,6 +871,7 @@ export function fillArea(polys, angle, spacing, output, minLen, maxLen) { * @returns {Point[]} */ export function rayIntersect(start, slope, polygons, for_fill) { + throw "deprecated"; let i = 0, flat = [], points = [], diff --git a/src/kiri/mode/fdm/post.js b/src/kiri/mode/fdm/post.js index 415e9633..650eb3c6 100644 --- a/src/kiri/mode/fdm/post.js +++ b/src/kiri/mode/fdm/post.js @@ -175,7 +175,8 @@ function thin_type_3(params) { let simplifyChain = false; let shortenAtNexus = false; let shortenEdgeSpur = false; - let intersectChains = true; + let intersectChains = false; + let maxInsetBypass = true; let showNoodle = false; let showExtrusion = true; @@ -185,7 +186,7 @@ function thin_type_3(params) { let showChainInterpPoints = true; let showChainIntersect = false; let showNuMedLine = false; - let showMedLine = false; + let showMedLine = true; let showMedPoints = false; let showMedNormals = false; let showMedRadii = false; @@ -201,38 +202,90 @@ function thin_type_3(params) { let maxF = midR * 2; // max interior extrusion width let minSpur = offsetN * 1; + let insets = []; let inset; let dstep = minR / 4; + let dtotl = 0; top.gaps = remain; - if (true) { - let dtotl = 0; + if (maxInsetBypass || intersectChains) { inset = POLY.offset(noodle, -dstep, { join: ClipperLib.JoinType.jtRound, arc: (1/dstep) * 4 }); while (inset && inset.length) { dtotl += dstep; - let ps = POLY.flatten(inset); - for (let poly of ps) { - for (let p of poly.segment(minR).points) { - let d = dtotl * 0+0.05; - // let z = dtotl * 10; - if (showInsetPoints) - shells.append( newPolygon().centerCircle(p, d, 10).setZ(z) ); - } + for (let p of POLY.flatten(inset, [])) { + p.dtotl = dtotl; } + insets.push(inset); + let ps = POLY.flatten(inset); POLY.setZ(inset, z); shells.appendAll(inset); - if (true || dtotl >= maxR) { + if (intersectChains) { break; } - inset = POLY.expand(inset, -dstep); + // if (dtotl >= maxR * 3) { + // break; + // } + inset = POLY.offset(inset, -dstep, { + // join: ClipperLib.JoinType.jtRound, + // arc: (1/dstep) * 4 + minArea: 0 + }); } } - // shells.appendAll(noodle); - // return { last, gaps }; + // project from first inset and find greated offset intersection + if (maxInsetBypass) { + // shells.appendAll(noodle); + // return { last, gaps }; + let { intersectRayLine } = base.util; + let tests = insets.slice(1); + let source = POLY.flatten(insets[0], []); + console.log({ source, tests }); + for (let poly of source) { + // segment the smallest inset and test against all other insets + poly.segment(minR).forEachSegment((p1, p2) => { + let np1 = { x:(p1.x+p2.x)/2, y:(p1.y+p2.y)/2 }; + let len = pointDist(p1, p2); + let dx = (p1.x - p2.x) / len; + let dy = (p1.y - p2.y) / len; + let np2 = { x: np1.x + dy * 10, y: np1.y - dx * 10 }; + let max = { dtotl: poly.dtotl, dist: Infinity, maxd: Infinity }; + let term = false; + outer: for (let test of tests) { + for (let tpoly of POLY.flatten(test, [])) { + tpoly.forEachSegment((tp1, tp2) => { + let int = intersectRayLine(np1, { dx: dy, dy: -dx }, tp1, tp2); + if (int && int.dist > int.p1.poly.dtotl) { + return; + } + if (int && int.dist <= max.maxd && int.p1.poly.dtotl > max.dtotl) { + max.dtotl = int.p1.poly.dtotl; + max.dist = int.dist; + max.int = int; + } else if (int && int.dist <= max.maxd && int.p1.poly.dtotl === max.dtotl && int.dist < max.dist) { + max.dtotl = int.p1.poly.dtotl; + max.dist = int.dist; + max.int = int; + } + }); + if (term) { + break outer; + } + } + } + if (max.int) { + thin.push(new Point(np1.x, np1.y, z)); + thin.push(new Point(max.int.x, max.int.y, z)); + } + }); + } + + shells.appendAll(noodle); + return { last, gaps }; + } let pointMap = new Map(); let lineMap = new Map();