MCPcopy Create free account
hub / github.com/CNCKitchen/stlTexturizer / computeSmartResolution

Function computeSmartResolution

js/smartResolution.js:289–389  ·  view source on GitHub ↗
({ geometry, bounds, settings, texture })

Source from the content-addressed store, hash-verified

287
288 // Pre-compute per-triangle edges once — reused across all simulator calls.
289 const triEdges = computeTriEdges(geometry);
290
291 // Solve for the largest (coarsest) edge that keeps simulated tri count ≤
292 // budget. Start from the closed-form equilateral-cover estimate, then
293 // do up to 3 ratio corrections (sim count scales ~1/edge² so each step
294 // multiplies edge by sqrt(predicted/budget) until it converges).
295 let budgetEdge = Math.sqrt((TRIS_PER_AREA_GEOM * surfaceArea) / Math.max(triBudget, 1));
296 for (let step = 0; step < 3; step++) {
297 const simCount = simulateFromEdges(triEdges, budgetEdge);
298 if (simCount <= triBudget) break;
299 const correction = Math.sqrt(simCount / triBudget);
300 if (correction < 1.005) break; // converged
301 budgetEdge = budgetEdge * correction;
302 }
303 // Guarantee the budget actually holds. On near-uniform meshes (cube-like
304 // CAD tessellations) the simulated count is a step function of the edge —
305 // 12 × 4^k for the default cube — so the sqrt-ratio corrections above can
306 // stall between split thresholds and finish a few percent over budget.
307 // Walk coarser in 5% steps until the simulation fits; sim count is
308 // monotonically non-increasing in edge length, so this always terminates.
309 for (let step = 0; step < 24; step++) {
310 if (simulateFromEdges(triEdges, budgetEdge) <= triBudget) break;
311 budgetEdge *= 1.05;
312 }
313
314 // 5. Final edge: take the larger (coarser) of detail vs budget so neither
315 // constraint is violated.
316 let edge = Math.max(detailEdge, budgetEdge);
317 const budgetClamped = budgetEdge > detailEdge;
318
319 // Sanity clamp: never below 0.05 mm, never coarser than diag/50 (or the
320 // 5 mm slider absolute) — matches the legacy default's spirit.
321 const diag = Math.sqrt(bounds.size.x ** 2 + bounds.size.y ** 2 + bounds.size.z ** 2);
322 const lo = 0.05;
323 const hi = Math.min(5.0, diag / 50);
324 const preClamp = edge;
325 edge = Math.min(Math.max(edge, lo), Math.max(hi, lo));
326 const edgeClamped = edge !== preClamp;
327
328 // Round UP to 2 decimals so the slider value never violates the budget
329 // floor (rounding down by even 0.005 mm can push estimated triangles past
330 // the budget cap).
331 edge = Math.max(lo, Math.ceil(edge * 100) / 100);
332
333 // Estimated triangle count at the chosen edge length, via per-triangle
334 // simulation of the actual subdivision pattern.
335 const estTriangles = simulateFromEdges(triEdges, edge);
336
337 // Recommended Max Triangles for "minimum quality loss" decimation.
338 const recommendedMaxTri = computeRecommendedMaxTri({
339 pixelsPerEdge, pixMm, surfaceArea,
340 amplitude: settings.amplitude,
341 });
342
343 return {
344 edge,
345 diagnostics: {
346 pixelsPerEdge,

Callers 1

applySmartResolutionFunction · 0.90

Calls 6

analyzeTextureFunction · 0.90
computeSurfaceAreaFunction · 0.90
computeWorldPeriodFunction · 0.85
computeTriEdgesFunction · 0.85
simulateFromEdgesFunction · 0.85
computeRecommendedMaxTriFunction · 0.85

Tested by

no test coverage detected