mirror of
https://github.com/CNCKitchen/stlTexturizer.git
synced 2026-04-07 22:11:32 +00:00
reduce preview edges
This commit is contained in:
+11
-4
@@ -26,6 +26,8 @@ let previewDebounce = null;
|
|||||||
// Boundary edge data texture for per-fragment falloff in bump-only preview
|
// Boundary edge data texture for per-fragment falloff in bump-only preview
|
||||||
let _boundaryEdgeTex = null;
|
let _boundaryEdgeTex = null;
|
||||||
let _boundaryEdgeCount = 0;
|
let _boundaryEdgeCount = 0;
|
||||||
|
let _falloffDirty = true; // recompute falloff on next updateFaceMask
|
||||||
|
let _falloffGeometry = null; // geometry the falloff was last computed for
|
||||||
|
|
||||||
// ── Exclusion state ───────────────────────────────────────────────────────────
|
// ── Exclusion state ───────────────────────────────────────────────────────────
|
||||||
let excludedFaces = new Set(); // triangle indices in currentGeometry
|
let excludedFaces = new Set(); // triangle indices in currentGeometry
|
||||||
@@ -331,11 +333,11 @@ function wireEvents() {
|
|||||||
linkSlider(rotationSlider, rotationVal, v => { settings.rotation = v; return Math.round(v); });
|
linkSlider(rotationSlider, rotationVal, v => { settings.rotation = v; return Math.round(v); });
|
||||||
linkSlider(amplitudeSlider, amplitudeVal, v => { settings.amplitude = v; checkAmplitudeWarning(); return v.toFixed(2); });
|
linkSlider(amplitudeSlider, amplitudeVal, v => { settings.amplitude = v; checkAmplitudeWarning(); return v.toFixed(2); });
|
||||||
amplitudeVal.addEventListener('change', checkAmplitudeWarning);
|
amplitudeVal.addEventListener('change', checkAmplitudeWarning);
|
||||||
linkSlider(boundaryFalloffSlider, boundaryFalloffVal, v => { settings.boundaryFalloff = v; return v.toFixed(1); });
|
linkSlider(boundaryFalloffSlider, boundaryFalloffVal, v => { settings.boundaryFalloff = v; _falloffDirty = true; return v.toFixed(1); });
|
||||||
linkSlider(refineLenSlider, refineLenVal, v => { settings.refineLength = v; return v.toFixed(2); }, false);
|
linkSlider(refineLenSlider, refineLenVal, v => { settings.refineLength = v; return v.toFixed(2); }, false);
|
||||||
linkSlider(maxTriSlider, maxTriVal, v => { settings.maxTriangles = v; return formatM(v); }, false);
|
linkSlider(maxTriSlider, maxTriVal, v => { settings.maxTriangles = v; return formatM(v); }, false);
|
||||||
linkSlider(bottomAngleLimitSlider, bottomAngleLimitVal, v => { settings.bottomAngleLimit = v; return v; });
|
linkSlider(bottomAngleLimitSlider, bottomAngleLimitVal, v => { settings.bottomAngleLimit = v; _falloffDirty = true; return v; });
|
||||||
linkSlider(topAngleLimitSlider, topAngleLimitVal, v => { settings.topAngleLimit = v; return v; });
|
linkSlider(topAngleLimitSlider, topAngleLimitVal, v => { settings.topAngleLimit = v; _falloffDirty = true; return v; });
|
||||||
linkSlider(seamBlendSlider, seamBlendVal, v => { settings.mappingBlend = v; return v.toFixed(2); });
|
linkSlider(seamBlendSlider, seamBlendVal, v => { settings.mappingBlend = v; return v.toFixed(2); });
|
||||||
linkSlider(seamBandWidthSlider, seamBandWidthVal, v => { settings.seamBandWidth = v; return v.toFixed(2); });
|
linkSlider(seamBandWidthSlider, seamBandWidthVal, v => { settings.seamBandWidth = v; return v.toFixed(2); });
|
||||||
symmetricDispToggle.addEventListener('change', () => {
|
symmetricDispToggle.addEventListener('change', () => {
|
||||||
@@ -796,6 +798,7 @@ function handlePlaceOnFaceClick(e) {
|
|||||||
|
|
||||||
function refreshExclusionOverlay() {
|
function refreshExclusionOverlay() {
|
||||||
if (!currentGeometry) return;
|
if (!currentGeometry) return;
|
||||||
|
_falloffDirty = true;
|
||||||
if (selectionMode) {
|
if (selectionMode) {
|
||||||
// Include Only mode: tint the complement (non-selected faces) with a pastel blue
|
// Include Only mode: tint the complement (non-selected faces) with a pastel blue
|
||||||
// so the model stays visible against the dark background before any faces are painted.
|
// so the model stays visible against the dark background before any faces are painted.
|
||||||
@@ -1146,8 +1149,12 @@ function updateFaceMask(geometry) {
|
|||||||
addFaceNormals(geometry);
|
addFaceNormals(geometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_falloffDirty || geometry !== _falloffGeometry) {
|
||||||
computeBoundaryFalloffAttr(geometry, maskArr);
|
computeBoundaryFalloffAttr(geometry, maskArr);
|
||||||
computeBoundaryEdges(geometry, maskArr);
|
computeBoundaryEdges(geometry, maskArr);
|
||||||
|
_falloffDirty = false;
|
||||||
|
_falloffGeometry = geometry;
|
||||||
|
}
|
||||||
syncBoundaryEdgeUniforms();
|
syncBoundaryEdgeUniforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1388,7 +1395,7 @@ function computeBoundaryEdges(geometry, userMaskArr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_EDGES = 512;
|
const MAX_EDGES = 64;
|
||||||
const edges = [];
|
const edges = [];
|
||||||
for (const [key, faces] of edgeFaces) {
|
for (const [key, faces] of edgeFaces) {
|
||||||
if (edges.length >= MAX_EDGES) break;
|
if (edges.length >= MAX_EDGES) break;
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ const fragmentShader = /* glsl */`
|
|||||||
// compute the distance from each pixel to the nearest boundary edge.
|
// compute the distance from each pixel to the nearest boundary edge.
|
||||||
if (useDisplacement == 0 && boundaryFalloffDist > 0.001 && boundaryEdgeCount > 0) {
|
if (useDisplacement == 0 && boundaryFalloffDist > 0.001 && boundaryEdgeCount > 0) {
|
||||||
float minDist = boundaryFalloffDist;
|
float minDist = boundaryFalloffDist;
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int i = 0; i < 64; i++) {
|
||||||
if (i >= boundaryEdgeCount) break;
|
if (i >= boundaryEdgeCount) break;
|
||||||
float uA = (float(i * 2) + 0.5) / boundaryEdgeTexWidth;
|
float uA = (float(i * 2) + 0.5) / boundaryEdgeTexWidth;
|
||||||
float uB = (float(i * 2 + 1) + 0.5) / boundaryEdgeTexWidth;
|
float uB = (float(i * 2 + 1) + 0.5) / boundaryEdgeTexWidth;
|
||||||
@@ -258,7 +258,7 @@ const fragmentShader = /* glsl */`
|
|||||||
float abLen2 = dot(ab, ab);
|
float abLen2 = dot(ab, ab);
|
||||||
float t = clamp(dot(vModelPos - ea, ab) / max(abLen2, 1e-10), 0.0, 1.0);
|
float t = clamp(dot(vModelPos - ea, ab) / max(abLen2, 1e-10), 0.0, 1.0);
|
||||||
float d = length(vModelPos - (ea + t * ab));
|
float d = length(vModelPos - (ea + t * ab));
|
||||||
minDist = min(minDist, d);
|
if (d < minDist) { minDist = d; if (d < 1e-4) break; }
|
||||||
}
|
}
|
||||||
maskBlend *= clamp(minDist / boundaryFalloffDist, 0.0, 1.0);
|
maskBlend *= clamp(minDist / boundaryFalloffDist, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user