diff --git a/index.html b/index.html index 9f55a4b..9aa6830 100644 --- a/index.html +++ b/index.html @@ -296,8 +296,8 @@ @@ -345,11 +345,9 @@

License & Terms

diff --git a/js/i18n.js b/js/i18n.js index 028e2bf..dbf397b 100644 --- a/js/i18n.js +++ b/js/i18n.js @@ -15,7 +15,7 @@ export const TRANSLATIONS = { // Viewport footer 'ui.wireframe': 'Wireframe', 'ui.controlsHint': 'Left drag: orbit \u00a0·\u00a0 Right drag: pan \u00a0·\u00a0 Scroll: zoom', - 'ui.meshInfo': '{n} triangles · {mb} MB', + 'ui.meshInfo': '{n} triangles · {mb} MB · {sx} × {sy} × {sz} mm', // Load STL button 'ui.loadStl': 'Load STL\u2026', @@ -127,11 +127,9 @@ export const TRANSLATIONS = { // License popup 'license.btn': 'License & Terms', 'license.title': 'License & Terms', - 'license.item1': 'This tool is open-source \u2014 view & contribute on GitHub.', - 'license.item2': 'Free to use for any purpose, including commercial work (e.g., texturing STLs for clients or products).', - 'license.item3': 'Attribution is appreciated but not required when using this tool as-is.', - 'license.item4': 'You may not sell or commercially redistribute this tool itself.', - 'license.item5': 'Forks or derivative works must credit CNC Kitchen by name and link to cnckitchen.store.', + 'license.item1': 'Free to use for any purpose, including commercial work (e.g., texturing STLs for clients or products).', + 'license.item2': 'Attribution is appreciated but not required when using this tool as-is.', + 'license.item3': 'Want to support this tool and our work? Check out our online store!', // Sponsor modal 'sponsor.title': 'Thanks for using CNC Kitchen STL Texturizer!', @@ -162,7 +160,7 @@ export const TRANSLATIONS = { // Viewport footer 'ui.wireframe': 'Drahtgitter', 'ui.controlsHint': 'Linke Maustaste: Drehen \u00a0·\u00a0 Rechte Maustaste: Verschieben \u00a0·\u00a0 Mausrad: Zoomen', - 'ui.meshInfo': '{n} Dreiecke · {mb} MB', + 'ui.meshInfo': '{n} Dreiecke · {mb} MB · {sx} × {sy} × {sz} mm', // Load STL button 'ui.loadStl': 'STL laden\u2026', @@ -274,11 +272,9 @@ export const TRANSLATIONS = { // License popup 'license.btn': 'Lizenz & Nutzung', 'license.title': 'Lizenz & Nutzungsbedingungen', - 'license.item1': 'Dieses Tool ist Open Source \u2014 auf GitHub ansehen & beitragen.', - 'license.item2': 'Kostenlos nutzbar f\u00fcr jeden Zweck, auch f\u00fcr kommerzielle Arbeit (z.B. Texturierung von STLs f\u00fcr Kunden oder Produkte).', - 'license.item3': 'Namensnennung wird gesch\u00e4tzt, ist aber bei der Nutzung dieses Tools nicht erforderlich.', - 'license.item4': 'Das Tool selbst darf nicht verkauft oder kommerziell weitervertrieben werden.', - 'license.item5': 'Forks oder abgeleitete Werke m\u00fcssen CNC Kitchen namentlich nennen und auf cnckitchen.store verlinken.', + 'license.item1': 'Kostenlos nutzbar f\u00fcr jeden Zweck, auch f\u00fcr kommerzielle Arbeit (z.B. Texturierung von STLs f\u00fcr Kunden oder Produkte).', + 'license.item2': 'Namensnennung wird gesch\u00e4tzt, ist aber bei der Nutzung dieses Tools nicht erforderlich.', + 'license.item3': 'M\u00f6chtest du dieses Tool und unsere Arbeit unterst\u00fctzen? Schau in unserem Online-Shop vorbei!', // Sponsor modal 'sponsor.title': 'Danke f\u00fcr die Nutzung des CNC Kitchen STL Texturizers!', diff --git a/js/main.js b/js/main.js index 3da43ce..59a29f3 100644 --- a/js/main.js +++ b/js/main.js @@ -31,7 +31,7 @@ let exclusionTool = null; // 'brush' | 'bucket' | null let eraseMode = false; let brushIsRadius = false; let brushRadius = 5.0; -let bucketThreshold = 30; +let bucketThreshold = 20; let isPainting = false; let selectionMode = false; // false = exclude painted faces; true = include only painted faces let _lastHoverTriIdx = -1; // last triangle index used for hover preview @@ -415,7 +415,7 @@ function wireEvents() { _lastHoverTriIdx = -1; // invalidate hover so next mousemove re-computes }); exclThresholdVal.addEventListener('change', () => { - bucketThreshold = Math.max(0, Math.min(180, parseFloat(exclThresholdVal.value) || 30)); + bucketThreshold = Math.max(0, Math.min(180, parseFloat(exclThresholdVal.value) || 20)); exclThresholdSlider.value = bucketThreshold; exclThresholdVal.value = bucketThreshold; _lastHoverTriIdx = -1; @@ -758,7 +758,10 @@ function loadDefaultCube() { const triCount = getTriangleCount(geo); const mb = ((geo.attributes.position.array.byteLength) / 1024 / 1024).toFixed(2); - meshInfo.textContent = t('ui.meshInfo', { n: triCount.toLocaleString(), mb }); + const sx = currentBounds.size.x.toFixed(2); + const sy = currentBounds.size.y.toFixed(2); + const sz = currentBounds.size.z.toFixed(2); + meshInfo.textContent = t('ui.meshInfo', { n: triCount.toLocaleString(), mb, sx, sy, sz }); exportBtn.disabled = (activeMapEntry === null); updatePreview(); @@ -838,7 +841,10 @@ async function handleSTL(file) { const triCount = getTriangleCount(geometry); const mb = ((geometry.attributes.position.array.byteLength) / 1024 / 1024).toFixed(2); - meshInfo.textContent = t('ui.meshInfo', { n: triCount.toLocaleString(), mb }); + const sx = bounds.size.x.toFixed(2); + const sy = bounds.size.y.toFixed(2); + const sz = bounds.size.z.toFixed(2); + meshInfo.textContent = t('ui.meshInfo', { n: triCount.toLocaleString(), mb, sx, sy, sz }); exportBtn.disabled = (activeMapEntry === null); updatePreview(); diff --git a/js/viewer.js b/js/viewer.js index c1918fe..a880796 100644 --- a/js/viewer.js +++ b/js/viewer.js @@ -24,17 +24,15 @@ function buildAxesIndicator(size) { const pts = [new THREE.Vector3(0, 0, 0), dir.clone().multiplyScalar(r * 0.78)]; const line = new THREE.Line( new THREE.BufferGeometry().setFromPoints(pts), - new THREE.LineBasicMaterial({ color: hex, depthTest: false, transparent: true, opacity: 0.9 }), + new THREE.LineBasicMaterial({ color: hex, transparent: true, opacity: 0.9 }), ); - line.renderOrder = 999; group.add(line); // Cone arrowhead const cone = new THREE.Mesh( new THREE.ConeGeometry(r * 0.07, r * 0.22, 8), - new THREE.MeshBasicMaterial({ color: hex, depthTest: false }), + new THREE.MeshBasicMaterial({ color: hex }), ); - cone.renderOrder = 999; cone.position.copy(dir.clone().multiplyScalar(r * 0.89)); cone.quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir); group.add(cone); @@ -49,9 +47,8 @@ function buildAxesIndicator(size) { ctx.textBaseline = 'middle'; ctx.fillText(label, 32, 32); const sprite = new THREE.Sprite( - new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(c), depthTest: false }), + new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(c) }), ); - sprite.renderOrder = 999; sprite.position.copy(dir.clone().multiplyScalar(r * 1.18)); sprite.scale.set(r * 0.32, r * 0.32, 1); group.add(sprite); @@ -79,9 +76,8 @@ function buildDimensionLabel(text, hex, worldW, worldH) { ctx.fillText(text, 128, 32); const mesh = new THREE.Mesh( new THREE.PlaneGeometry(worldW, worldH), - new THREE.MeshBasicMaterial({ map: new THREE.CanvasTexture(c), transparent: true, depthTest: false, side: THREE.DoubleSide }), + new THREE.MeshBasicMaterial({ map: new THREE.CanvasTexture(c), transparent: true, side: THREE.DoubleSide }), ); - mesh.renderOrder = 998; return mesh; } @@ -98,9 +94,8 @@ function buildDimensions(box, groundZ, scale) { const addLine = (pts, hex) => { const line = new THREE.Line( new THREE.BufferGeometry().setFromPoints(pts), - new THREE.LineBasicMaterial({ color: hex, depthTest: false, transparent: true, opacity: 0.75 }), + new THREE.LineBasicMaterial({ color: hex, transparent: true, opacity: 0.75 }), ); - line.renderOrder = 997; group.add(line); }; diff --git a/textures/wood.jpg b/textures/wood.jpg index 055bb43..d0a2d61 100644 Binary files a/textures/wood.jpg and b/textures/wood.jpg differ