diff --git a/SUB Control/README.md b/SUB Control/README.md index 202d282..3c5c185 100644 --- a/SUB Control/README.md +++ b/SUB Control/README.md @@ -18,6 +18,9 @@ to zoom. A cached STL copy is stored locally under the ignored `runtime/` directory so the model can be restored on the next launch. STEP/STP CAD solids must first be tessellated/exported as STL because the embedded renderer intentionally does not include a full CAD kernel. +Binary and ASCII STL faces are preserved in full; large assemblies are not +rendered by skipping triangles. Imports are limited to 30 MB to keep startup +and interactive orbiting responsive. ## Safety first diff --git a/SUB Control/web/model-viewer.js b/SUB Control/web/model-viewer.js index 39c6625..fd3b654 100644 --- a/SUB Control/web/model-viewer.js +++ b/SUB Control/web/model-viewer.js @@ -4,7 +4,8 @@ const ctx = canvas.getContext('2d'); let vertices = null, frame = 0, yaw = 0, pitch = 0, zoom = 1; let dragging = false, lastX = 0, lastY = 0; - const renderScale = .62; + // Still below native resolution, but high enough for clean assembly contours. + const renderScale = .82; function parseStl(buffer) { const view = new DataView(buffer); @@ -12,8 +13,7 @@ const binaryCount = buffer.byteLength >= 84 ? view.getUint32(80, true) : 0; const isBinary = binaryCount > 0 && 84 + binaryCount * 50 <= buffer.byteLength; if (isBinary) { - const stride = Math.max(1, Math.ceil(binaryCount / 14000)); - for (let t = 0; t < binaryCount; t += stride) { + for (let t = 0; t < binaryCount; t++) { const offset = 84 + t * 50 + 12; for (let v = 0; v < 3; v++) { raw.push(view.getFloat32(offset + v * 12, true)); @@ -25,8 +25,7 @@ const text = new TextDecoder().decode(buffer); const matches = [...text.matchAll(/vertex\s+([-+\deE.]+)\s+([-+\deE.]+)\s+([-+\deE.]+)/gi)]; if (matches.length < 3) throw new Error('This file does not contain a readable STL mesh'); - const stride = Math.max(1, Math.ceil(matches.length / 42000)); - for (let i = 0; i + 2 < matches.length; i += 3 * stride) { + for (let i = 0; i + 2 < matches.length; i += 3) { for (let j = 0; j < 3; j++) raw.push(+matches[i+j][1], +matches[i+j][2], +matches[i+j][3]); } } @@ -53,16 +52,19 @@ return [rx,y*cosP-rz*sinP]; }; maskCtx.fillStyle='#fff'; + maskCtx.beginPath(); for(let i=0;i