From 9b0995c22de02a46eea05505dff16f8b80703957 Mon Sep 17 00:00:00 2001 From: CNCKitchen Date: Wed, 18 Mar 2026 15:33:17 +0100 Subject: [PATCH] Refactor code structure for improved readability and maintainability --- LICENSE | 21 +++++++++ README.md | 62 ++++++++++++++++++++++++++ index.html | 2 +- js/i18n.js | 16 +++---- js/presetTextures.js | 24 +++++----- basket.jpg => textures/basket.jpg | Bin brick.jpg => textures/brick.jpg | Bin bubble.jpg => textures/bubble.jpg | Bin crystal.jpg => textures/crystal.jpg | Bin header.jpg => textures/header.jpg | Bin hexagon.jpg => textures/hexagon.jpg | Bin knitting.jpg => textures/knitting.jpg | Bin knurling.jpg => textures/knurling.jpg | Bin leather.jpg => textures/leather.jpg | Bin leather2.jpg => textures/leather2.jpg | Bin melt.jpg => textures/melt.jpg | Bin noise.jpg => textures/noise.jpg | Bin rhombic.jpg => textures/rhombic.jpg | Bin weave.jpg => textures/weave.jpg | Bin wood.jpg => textures/wood.jpg | Bin 20 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 LICENSE create mode 100644 README.md rename basket.jpg => textures/basket.jpg (100%) rename brick.jpg => textures/brick.jpg (100%) rename bubble.jpg => textures/bubble.jpg (100%) rename crystal.jpg => textures/crystal.jpg (100%) rename header.jpg => textures/header.jpg (100%) rename hexagon.jpg => textures/hexagon.jpg (100%) rename knitting.jpg => textures/knitting.jpg (100%) rename knurling.jpg => textures/knurling.jpg (100%) rename leather.jpg => textures/leather.jpg (100%) rename leather2.jpg => textures/leather2.jpg (100%) rename melt.jpg => textures/melt.jpg (100%) rename noise.jpg => textures/noise.jpg (100%) rename rhombic.jpg => textures/rhombic.jpg (100%) rename weave.jpg => textures/weave.jpg (100%) rename wood.jpg => textures/wood.jpg (100%) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fa9381d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 CNCKitchen (Stefan Elitz) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..169f3a4 --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# STL Texturizer + +A browser-based tool for applying surface displacement textures to STL files — no installation required. + +Load any `.stl` file, pick a texture, tune the parameters, and export a new displaced STL ready for slicing. + +## Features + +- **Texture presets** — 12 built-in seamless textures (basket, brick, bubble, crystal, hexagon, knitting, knurling, leather, weave, wood, noise, and more) +- **Custom textures** — upload your own image as a displacement map +- **Projection modes** — Triplanar, Cubic (Box), Cylindrical, Spherical, Planar XY/XZ/YZ +- **UV transform** — independent U/V scale, offset, and rotation controls +- **Displacement amplitude** — fine-tune depth from subtle grain to deep relief +- **Surface mask** — skip horizontal top/bottom faces to keep flat surfaces clean +- **Surface exclusions / inclusions** — paint individual faces with a brush or bucket-fill to exclude or exclusively include them from displacement +- **Live preview** — real-time textured 3D preview with orbit/pan/zoom controls +- **Mesh subdivision** — auto-subdivides coarse geometry before displacement for smoother results +- **Export** — downloads a new binary STL with displacement baked in +- **Light / Dark theme** — persisted per browser +- **Multilingual** — English and German UI + +## Usage + +1. Open `index.html` in a modern browser (Chrome, Edge, Firefox, Safari). +2. Drop an STL file onto the viewport or click **Load STL…**. +3. Select a texture preset from the sidebar (or upload a custom image). +4. Adjust projection mode, UV scale, offset, rotation, and amplitude. +5. Optionally mask or exclude surfaces with the brush/fill tools. +6. Click **Export STL** to download the displaced mesh. + +> **Note:** All processing runs entirely in the browser — no data is uploaded to any server. + +## Project Structure + +``` +index.html # Main entry point +style.css # Styles (light/dark theme) +textures/ # Built-in JPG displacement map images +js/ + main.js # App bootstrap & UI wiring + viewer.js # Three.js scene / camera / controls + stlLoader.js # Binary & ASCII STL parser + presetTextures.js # Built-in texture presets + custom upload + previewMaterial.js# Three.js material for live preview + mapping.js # UV projection logic + displacement.js # Vertex displacement baking + subdivision.js # Mesh subdivision + decimation.js # QEM mesh decimation + exclusion.js # Face exclusion / inclusion painting + exporter.js # Binary STL export + i18n.js # Translations (EN / DE) +``` + +## Dependencies + +Loaded via CDN — no build step needed: + +- [Three.js](https://threejs.org/) v0.170.0 + +## License + +MIT — see [LICENSE](LICENSE). diff --git a/index.html b/index.html index f4a7fb9..0ddaa87 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,7 @@ // Apply saved theme before first paint to avoid flash (function() { const t = localStorage.getItem('stlt-theme'); - if (t === 'light') document.documentElement.setAttribute('data-theme', 'light'); + if (t !== 'dark') document.documentElement.setAttribute('data-theme', 'light'); })(); // Apply saved language before first paint to avoid flash (function() { diff --git a/js/i18n.js b/js/i18n.js index dc39a6d..3516813 100644 --- a/js/i18n.js +++ b/js/i18n.js @@ -102,8 +102,8 @@ export const TRANSLATIONS = { 'progress.subdividing': 'Subdividing mesh\u2026', 'progress.applyingDisplacement': 'Applying displacement to {n} triangles\u2026', 'progress.displacingVertices': 'Displacing vertices\u2026', - 'progress.decimatingTo': 'Decimating {from} \u2192 {to} triangles\u2026', - 'progress.decimating': 'Decimating: {cur} \u2192 {to} triangles', + 'progress.decimatingTo': 'Simplifying {from} \u2192 {to} triangles\u2026', + 'progress.decimating': 'Simplifying: {cur} \u2192 {to} triangles', 'progress.writingStl': 'Writing STL\u2026', 'progress.done': 'Done!', 'progress.processing': 'Processing\u2026', @@ -212,7 +212,7 @@ export const TRANSLATIONS = { // Export section 'sections.export': 'Export \u24d8', - 'tooltips.export': 'Kleinere Kantenl\u00e4nge = feineres Verschiebungsdetail. Die Ausgabe wird dann auf das Dreieckslimit dezimiert.', + 'tooltips.export': 'Kleinere Kantenl\u00e4nge = mehr Texturdetails. Die Ausgabe wird dann auf das Dreieckslimit vereinfacht.', 'labels.resolution': 'Aufl\u00f6sung', 'tooltips.resolution': 'Kanten l\u00e4nger als dieser Wert werden beim Export unterteilt', 'labels.outputTriangles': 'Max Dreiecke', @@ -221,11 +221,11 @@ export const TRANSLATIONS = { 'ui.exportStl': 'STL exportieren', // Export progress stages - 'progress.subdividing': 'Netz wird unterteilt\u2026', - 'progress.applyingDisplacement': 'Verschiebung auf {n} Dreiecke anwenden\u2026', - 'progress.displacingVertices': 'Vertices werden verschoben\u2026', - 'progress.decimatingTo': '{from} \u2192 {to} Dreiecke dezimieren\u2026', - 'progress.decimating': 'Dezimieren: {cur} \u2192 {to} Dreiecke', + 'progress.subdividing': 'Netz wird verfeinert\u2026', + 'progress.applyingDisplacement': 'Textur auf {n} Dreiecke anwenden\u2026', + 'progress.displacingVertices': 'Punkte werden verschoben\u2026', + 'progress.decimatingTo': '{from} \u2192 {to} Dreiecke vereinfachen\u2026', + 'progress.decimating': 'Vereinfachen: {cur} \u2192 {to} Dreiecke', 'progress.writingStl': 'STL schreiben\u2026', 'progress.done': 'Fertig!', 'progress.processing': 'Verarbeitung\u2026', diff --git a/js/presetTextures.js b/js/presetTextures.js index 9ec2d19..2b8ffa6 100644 --- a/js/presetTextures.js +++ b/js/presetTextures.js @@ -14,18 +14,18 @@ function makeCanvas(size = SIZE) { // ── Image-based presets ─────────────────────────────────────────────────────── const IMAGE_PRESETS = [ - { name: 'Basket', url: 'basket.jpg' }, - { name: 'Brick', url: 'brick.jpg' }, - { name: 'Bubble', url: 'bubble.jpg' }, - { name: 'Crystal', url: 'crystal.jpg' }, - { name: 'Hexagon', url: 'hexagon.jpg' }, - { name: 'Knitting', url: 'knitting.jpg' }, - { name: 'Knurling', url: 'knurling.jpg' }, - { name: 'Leather', url: 'leather.jpg' }, - { name: 'Leather 2', url: 'leather2.jpg' }, - { name: 'Weave', url: 'weave.jpg' }, - { name: 'Wood', url: 'wood.jpg' }, - { name: 'Noise', url: 'noise.jpg' }, + { name: 'Basket', url: 'textures/basket.jpg' }, + { name: 'Brick', url: 'textures/brick.jpg' }, + { name: 'Bubble', url: 'textures/bubble.jpg' }, + { name: 'Crystal', url: 'textures/crystal.jpg' }, + { name: 'Hexagon', url: 'textures/hexagon.jpg' }, + { name: 'Knitting', url: 'textures/knitting.jpg' }, + { name: 'Knurling', url: 'textures/knurling.jpg' }, + { name: 'Leather', url: 'textures/leather.jpg' }, + { name: 'Leather 2', url: 'textures/leather2.jpg' }, + { name: 'Weave', url: 'textures/weave.jpg' }, + { name: 'Wood', url: 'textures/wood.jpg' }, + { name: 'Noise', url: 'textures/noise.jpg' }, ]; function loadImagePreset({ name, url }) { diff --git a/basket.jpg b/textures/basket.jpg similarity index 100% rename from basket.jpg rename to textures/basket.jpg diff --git a/brick.jpg b/textures/brick.jpg similarity index 100% rename from brick.jpg rename to textures/brick.jpg diff --git a/bubble.jpg b/textures/bubble.jpg similarity index 100% rename from bubble.jpg rename to textures/bubble.jpg diff --git a/crystal.jpg b/textures/crystal.jpg similarity index 100% rename from crystal.jpg rename to textures/crystal.jpg diff --git a/header.jpg b/textures/header.jpg similarity index 100% rename from header.jpg rename to textures/header.jpg diff --git a/hexagon.jpg b/textures/hexagon.jpg similarity index 100% rename from hexagon.jpg rename to textures/hexagon.jpg diff --git a/knitting.jpg b/textures/knitting.jpg similarity index 100% rename from knitting.jpg rename to textures/knitting.jpg diff --git a/knurling.jpg b/textures/knurling.jpg similarity index 100% rename from knurling.jpg rename to textures/knurling.jpg diff --git a/leather.jpg b/textures/leather.jpg similarity index 100% rename from leather.jpg rename to textures/leather.jpg diff --git a/leather2.jpg b/textures/leather2.jpg similarity index 100% rename from leather2.jpg rename to textures/leather2.jpg diff --git a/melt.jpg b/textures/melt.jpg similarity index 100% rename from melt.jpg rename to textures/melt.jpg diff --git a/noise.jpg b/textures/noise.jpg similarity index 100% rename from noise.jpg rename to textures/noise.jpg diff --git a/rhombic.jpg b/textures/rhombic.jpg similarity index 100% rename from rhombic.jpg rename to textures/rhombic.jpg diff --git a/weave.jpg b/textures/weave.jpg similarity index 100% rename from weave.jpg rename to textures/weave.jpg diff --git a/wood.jpg b/textures/wood.jpg similarity index 100% rename from wood.jpg rename to textures/wood.jpg