mirror of
https://github.com/gittrahan/support-fins.git
synced 2026-10-19 02:10:52 -05:00
engine: a low-edge row is blocked by any row that can build within a brim width, behind the edge too (a tilted cube at X60Z30 got a second squat wall 1.6 mm from main's, one fused slab); only rows in the low band itself don't count; test pins no fused squat brims on the slab and that cube (review)
This commit is contained in:
1 parent
92bf9d1e6c
commit
7ef4cfa4e5
4 files changed
+68
-10
No files matched your search
+2
-2
@@ -97,8 +97,8 @@ welts.
|
||||
toward the plate (a curved face lying on the bed), no wall fits under the squat floor
|
||||
(0.6 mm wall + gap), and Auto's rows land on a pitch that ignores it. So the edge of
|
||||
that band -- the first row position where a squat wall and its brim clear the part --
|
||||
gets a row when no row stands within a brim width (5 mm) of it (`lowEdges` in
|
||||
`prop/tracks.js`). Added, never moved: moving a row onto the edge lost real walls. Bands
|
||||
gets a row when no row that can build stands within a brim width (5 mm) of it
|
||||
(`lowEdges` in `prop/tracks.js`; a row inside the band never builds, so it doesn't count). Added, never moved: moving a row onto the edge lost real walls. Bands
|
||||
under `lowBandMin` (1 mm) are sampling dips, not the plate.
|
||||
- **Scale-aware profile.** The prototype's foot/chamfer/tip are fixed, which degenerates
|
||||
into a 14 mm splayed sheet when the overhang sits low. Foot width must scale with wall
|
||||
|
||||
+3
-1
@@ -75,7 +75,9 @@ of bow) lying on the plate gets a wall at **each edge of its low band** (where t
|
||||
underside climbs past the squat floor, ~14.6 mm out) at sparse, default and dense.
|
||||
Main put the nearest at 23.4 mm, ~9 mm of near-flat underside bare on each side
|
||||
(a customer's DRO housing on its bowed back; at the default coverage one side got
|
||||
nothing). The row is added beside the layout, never moved into it.
|
||||
nothing). The row is added beside the layout, never moved into it, and **no two
|
||||
squat brims fuse** -- on the slab, and on a 40 mm cube at X60Z30 sparse, where the
|
||||
first version added a squat wall 1.6 mm from the one main builds (review).
|
||||
|
||||
**`pad.test.js`** -- the bed pad styles (FIN-SPEC "Bed pad styles"):
|
||||
- **Sure hold** is a smooth oval that conforms under a tilted part's flank, stays
|
||||
|
||||
+52
-1
@@ -4,7 +4,7 @@
|
||||
// housing on its bowed back at X-90: at the default coverage one side got no row
|
||||
// at all and the other its first at 18 mm). The row nearest the band goes at
|
||||
// its edge -- ADDED, never moved, so every row that built before still does.
|
||||
import { buildTopology, analyze, fins, prop, isClosed, assert } from './_util.js';
|
||||
import { buildTopology, analyze, fins, prop, block, isClosed, rotX, assert } from './_util.js';
|
||||
|
||||
const { PROP } = prop;
|
||||
const I = [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
||||
@@ -47,6 +47,32 @@ const wallYs = (tris, coverage) => {
|
||||
return b.props.map((q) => q.line.reduce((s, p) => s + p[1], 0) / q.line.length - res.offset.y).sort((a, c) => a - c);
|
||||
};
|
||||
|
||||
const build = (tris, rot, coverage) => {
|
||||
const topo = topoOf(tris), res = analyze(topo, 45, rot);
|
||||
return fins.buildFins(topo, res, rot, { mode: 'auto', bedPad: true, tines: true, coverage });
|
||||
};
|
||||
|
||||
// Two squat walls whose brims (2 x squatBrimW wide) overlap: parallel, closer
|
||||
// than a brim width, and running side by side for some length. One fused slab.
|
||||
function fusedSquats(b) {
|
||||
const sq = b.props.filter((q) => q.squat);
|
||||
const out = [];
|
||||
for (let i = 0; i < sq.length; i++) for (let j = i + 1; j < sq.length; j++) {
|
||||
const A = sq[i].line, B = sq[j].line;
|
||||
const a0 = A[0], a1 = A[A.length - 1];
|
||||
let ux = a1[0] - a0[0], uy = a1[1] - a0[1];
|
||||
const un = Math.hypot(ux, uy); ux /= un; uy /= un;
|
||||
const b0 = B[0], b1 = B[B.length - 1];
|
||||
const vx = b1[0] - b0[0], vy = b1[1] - b0[1], vn = Math.hypot(vx, vy);
|
||||
if (Math.abs(ux * vy - uy * vx) / vn > 0.1) continue; // not parallel
|
||||
const off = Math.abs((b0[0] - a0[0]) * -uy + (b0[1] - a0[1]) * ux);
|
||||
const s = (p) => (p[0] - a0[0]) * ux + (p[1] - a0[1]) * uy;
|
||||
const lap = Math.min(un, Math.max(s(b0), s(b1))) - Math.max(0, Math.min(s(b0), s(b1)));
|
||||
if (off < 2 * PROP.squatBrimW && lap > 1) out.push(`${off.toFixed(2)} mm apart over ${lap.toFixed(1)} mm`);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Deno.test('low edge: the bowed slab is a closed solid', () => {
|
||||
assert(isClosed(bowedSlab()), 'bowedSlab is not closed');
|
||||
});
|
||||
@@ -64,3 +90,28 @@ Deno.test('low edge: a bowed face on the bed gets a wall at each edge of its low
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Deno.test('low edge: no two squat brims fuse -- the bowed slab, and a tilted cube whose old squat wall stands behind the edge', () => {
|
||||
for (const cov of [0, 0.5, 1]) {
|
||||
const f = fusedSquats(build(bowedSlab(), I, cov));
|
||||
assert(!f.length, `bowed slab cov ${cov}: fused squat walls ${f}`);
|
||||
}
|
||||
// the sweep's cube35 at X60Z30, sparse: the first version added a squat wall
|
||||
// 1.6 mm from the one main builds over a PART row behind the edge
|
||||
const d = 35 * Math.PI / 180, c = Math.cos(d), sn = Math.sin(d);
|
||||
const raw = block(-20, 20, -20, 20, -20, 20);
|
||||
let minZ = Infinity;
|
||||
for (let i = 0; i < raw.length; i += 3) {
|
||||
const y = raw[i + 1], z = raw[i + 2];
|
||||
raw[i + 1] = y * c - z * sn; raw[i + 2] = y * sn + z * c;
|
||||
minZ = Math.min(minZ, raw[i + 2]);
|
||||
}
|
||||
for (let i = 2; i < raw.length; i += 3) raw[i] -= minZ;
|
||||
const z30 = Math.PI / 6, rz = [Math.cos(z30), Math.sin(z30), 0, -Math.sin(z30), Math.cos(z30), 0, 0, 0, 1];
|
||||
const rx = rotX(60), rot = new Array(9).fill(0); // rotZ(30) * rotX(60), col-major
|
||||
for (let col = 0; col < 3; col++) for (let r = 0; r < 3; r++) for (let k = 0; k < 3; k++) rot[col * 3 + r] += rz[k * 3 + r] * rx[col * 3 + k];
|
||||
const b = build(raw, rot, 0);
|
||||
assert(b.props.some((q) => q.squat), 'the tilted cube lost its squat wall');
|
||||
const f = fusedSquats(b);
|
||||
assert(!f.length, `tilted cube: fused squat walls ${f}`);
|
||||
});
|
||||
+11
-6
@@ -562,16 +562,21 @@ function lowEdges(probe, vLo, vHi) {
|
||||
if (above >= 0) edges.push({ v: vs[above], dir: +1 });
|
||||
k = j;
|
||||
}
|
||||
// a row's own class, so lowEdgeRows can tell a row behind an edge that still
|
||||
// builds (a PART row) from one in the band that never will
|
||||
edges.low = (v) => cls[Math.max(0, Math.min(cls.length - 1, Math.round((v - vLo) / step)))] === 'low';
|
||||
return edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* rowOffsets' rows plus a row at each low edge (lowEdges) with no row within a
|
||||
* brim width (2 x squatBrimW) on its standing side, or within `near` behind it.
|
||||
* Only ever ADDED: the layout's rows are a guess at where a wall builds, the
|
||||
* edge scan is a coarser one, and moving a row onto the edge lost real walls
|
||||
* (the flat torus's 9-tine rim walls slid 1.3 mm in and failed the build). The
|
||||
* brim width keeps two squat brims from fusing.
|
||||
* brim width (2 x squatBrimW) of it -- either side, except a row IN the low band
|
||||
* behind it, which never builds. Only ever ADDED: the layout's rows are a guess
|
||||
* at where a wall builds, the edge scan is a coarser one, and moving a row onto
|
||||
* the edge lost real walls (the flat torus's 9-tine rim walls slid 1.3 mm in
|
||||
* and failed the build). The brim width keeps two squat brims from fusing: a
|
||||
* row behind the edge over a PART row still builds (a tilted cube at X60Z30
|
||||
* got a second squat wall 1.6 mm from it, one fused slab).
|
||||
*/
|
||||
function lowEdgeRows(rows, edges, near) {
|
||||
const out = [...rows];
|
||||
@@ -579,7 +584,7 @@ function lowEdgeRows(rows, edges, near) {
|
||||
for (const { v, dir } of edges) {
|
||||
const blocked = out.some((r) => {
|
||||
const d = (r - v) * dir;
|
||||
return d >= 0 ? d < brim : -d < near;
|
||||
return d >= 0 ? d < brim : -d < near || (-d < brim && !edges.low(r));
|
||||
});
|
||||
if (!blocked) out.push(v);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user