mirror of
https://github.com/gittrahan/support-fins.git
synced 2026-10-19 02:10:52 -05:00
grids: review fixes -- a pierce found on the fine grid reports the one the old 64x64 walk met first (9% of pierces moved up to 1.5 mm, and callers trim the station nearest it), buildFins drops its seated part when done, gridsize's comment counts cells right
This commit is contained in:
1 parent
d353ca302e
commit
0a01443560
4 files changed
+43
-4
No files matched your search
+2
-1
@@ -39,7 +39,7 @@ import { buildSwayBraces } from './sway.js';
|
||||
import { CUT, CUTOUT_PATTERNS } from './cutout.js';
|
||||
import { FIN } from './fins/config.js';
|
||||
import { buildPad, PAD } from './fins/pad.js';
|
||||
import { bedContact, seatedPartTris, seatingOf } from './fins/seating.js';
|
||||
import { bedContact, forgetSeated, seatedPartTris, seatingOf } from './fins/seating.js';
|
||||
import { lastResortWalls } from './fins/shortwalls.js';
|
||||
import { fillCoverage } from './fins/fill.js';
|
||||
import { buildPerpFins, PERP, propServesPatch, unservedAfterWedges, wedgeVeto } from './fins/wedges.js';
|
||||
@@ -121,6 +121,7 @@ export function applyTunables(t) {
|
||||
export function buildFins(topo, result, rot, opts = {}) {
|
||||
const built = buildFinsAndBraces(topo, result, rot, opts);
|
||||
crestPart(null); // the crest's part is only for this build (a Worker keeps no mesh)
|
||||
forgetSeated(topo); // nor the seated part: a page building inline would hold it
|
||||
// A piece of the part that starts in mid-air (a cut clean through, a loose
|
||||
// body) needs saying no matter what was placed: see floatingPieces.
|
||||
built.floating = floatingPieces(topo, result, rot);
|
||||
|
||||
@@ -29,6 +29,10 @@ export function seatedPartTris(topo, rot, offset) {
|
||||
return tris;
|
||||
}
|
||||
|
||||
/** Drop the cached copy: buildFins calls this when it finishes, so a page that
|
||||
* builds inline (Suggest's finalists) doesn't hold a seated part between builds. */
|
||||
export function forgetSeated(topo) { _seated.delete(topo); }
|
||||
|
||||
function seat(topo, rot, offset) {
|
||||
const { pos, nFaces } = topo;
|
||||
const { x: ox, y: oy, z: oz } = offset;
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
* over the part, so a cell's share of the mesh grew with the face count and every
|
||||
* query scanned it: a 250k-face figure put ~60 triangles in an average cell, and
|
||||
* with a big part's many stations those scans were ~80% of an Auto build (a
|
||||
* 768 mm figure, 197 s). Size the grid to the mesh instead: about FACES_PER_CELL
|
||||
* faces a cell, square cells in mm, never under 64 a side (the old grid, so a
|
||||
* 768 mm figure, 197 s). Size the grid to the mesh instead: as many cells as
|
||||
* faces / FACES_PER_CELL, square cells in mm, never under 64 a side (the old grid, so a
|
||||
* small part is bucketed no coarser than before) or above MAX_SIDE.
|
||||
*
|
||||
* Cells also stay at least MIN_CELL_MM wide. The box queries (nearestPart,
|
||||
|
||||
+35
-1
@@ -265,6 +265,36 @@ export function solidClearance(topo, rot, offset, verts, rMax = 0.45) {
|
||||
const clampA = (v) => Math.min(grid.NY - 1, Math.max(0, v));
|
||||
const clampB = (v) => Math.min(grid.NZ - 1, Math.max(0, v));
|
||||
|
||||
// The first part triangle wall triangle A pierces, in the coarse grid's cell
|
||||
// order -- the walk below with the box rejects, on the old 64 x 64 layout.
|
||||
const coarsePierce = (A, xLo, xHi, yLo, yHi, zLo, zHi) => {
|
||||
const g = grid.coarse, done = new Set();
|
||||
const cA = (v) => Math.min(g.NY - 1, Math.max(0, v));
|
||||
const cB = (v) => Math.min(g.NZ - 1, Math.max(0, v));
|
||||
const a0 = cA(Math.floor((yLo - rMax - g.minY) * g.sy)), a1 = cA(Math.floor((yHi + rMax - g.minY) * g.sy));
|
||||
const b0 = cB(Math.floor((zLo - rMax - g.minZ) * g.sz)), b1 = cB(Math.floor((zHi + rMax - g.minZ) * g.sz));
|
||||
for (let a = a0; a <= a1; a++) {
|
||||
for (let b = b0; b <= b1; b++) {
|
||||
const c = a * g.NZ + b;
|
||||
for (let i = g.start[c]; i < g.start[c + 1]; i++) {
|
||||
const f = g.items[i];
|
||||
if (done.has(f)) continue;
|
||||
done.add(f);
|
||||
const o = f * 9;
|
||||
if (Math.min(pos[o], pos[o + 3], pos[o + 6]) > xHi + rMax) continue;
|
||||
if (Math.max(pos[o], pos[o + 3], pos[o + 6]) < xLo - rMax) continue;
|
||||
if (Math.min(pos[o + 1], pos[o + 4], pos[o + 7]) > yHi + rMax) continue;
|
||||
if (Math.max(pos[o + 1], pos[o + 4], pos[o + 7]) < yLo - rMax) continue;
|
||||
if (Math.min(pos[o + 2], pos[o + 5], pos[o + 8]) > zHi + rMax) continue;
|
||||
if (Math.max(pos[o + 2], pos[o + 5], pos[o + 8]) < zLo - rMax) continue;
|
||||
const hit = triTriPierce(A, triVerts(pos, f));
|
||||
if (hit) return hit;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // unreachable: the fine walk found a pierce among the same candidates
|
||||
};
|
||||
|
||||
// un-rotate the solid's vertices into the mesh frame once
|
||||
const mv = new Array(verts.length);
|
||||
for (let i = 0; i < verts.length; i++) {
|
||||
@@ -352,8 +382,12 @@ export function solidClearance(topo, rot, offset, verts, rMax = 0.45) {
|
||||
// and edge-edge pair measures finite -- which is exactly how a wall
|
||||
// whose end cap ran 0.85mm into a part face was certified "0.167mm
|
||||
// clear" while the checker read 0.001.
|
||||
const pierce = triTriPierce(A, B);
|
||||
let pierce = triTriPierce(A, B);
|
||||
if (pierce) {
|
||||
// Which pierce is reported (callers trim the station nearest it)
|
||||
// depends on the order the cells are walked. Report the one the old
|
||||
// 64 x 64 walk met first, so the trim is the same at any grid size.
|
||||
if (g !== grid.coarse) pierce = coarsePierce(A, xLo, xHi, yLo, yHi, zLo, zHi);
|
||||
best = 0; bp = pierce; bq = pierce;
|
||||
a = a1 + 1; b = b1 + 1; t = mv.length; // nothing beats zero
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user