From 04c6c7f18ac81e5909d1201e5b0f6a6288f6ec2b Mon Sep 17 00:00:00 2001 From: johnathanweidman <67694158+johnathanweidman@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:34:33 -0500 Subject: [PATCH] Add more options for litho --- package-lock.json | 13 ++- package.json | 1 + src/components/ColorPicker.svelte | 13 ++- src/routes/+page.svelte | 150 ++++++++++++++++++------------ 4 files changed, 110 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4cd7f37..58d1ccb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "my-app", + "name": "glazer", "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "my-app", + "name": "glazer", "version": "0.0.1", "dependencies": { "fluent-svelte": "^1.6.0", @@ -13,6 +13,7 @@ "p5": "^1.9.0", "p5-svelte": "^3.1.2", "svelte-awesome-color-picker": "^3.0.4", + "svelte-heros-v2": "^1.2.0", "three": "^0.160.1" }, "devDependencies": { @@ -3551,6 +3552,14 @@ } } }, + "node_modules/svelte-heros-v2": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/svelte-heros-v2/-/svelte-heros-v2-1.2.0.tgz", + "integrity": "sha512-1Hxv/FvzF0G2wT6InlLe25KgXdXY3Qz9nVNP4Wyyjxo1R/P6Be3kNRnPCFs2bWCZlLu+1OGkVSy/CrhLjxfUxg==", + "peerDependencies": { + "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0" + } + }, "node_modules/svelte-hmr": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", diff --git a/package.json b/package.json index df7359d..d32d85d 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "p5": "^1.9.0", "p5-svelte": "^3.1.2", "svelte-awesome-color-picker": "^3.0.4", + "svelte-heros-v2": "^1.2.0", "three": "^0.160.1" } } diff --git a/src/components/ColorPicker.svelte b/src/components/ColorPicker.svelte index 009d02c..baa7b64 100644 --- a/src/components/ColorPicker.svelte +++ b/src/components/ColorPicker.svelte @@ -1,20 +1,25 @@
+ {#if removable} + + {/if}



-
+
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 140c374..627b150 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -5,28 +5,58 @@ import mixbox from 'mixbox'; import {imageToMesh, saveSTL } from '../lib/Litho.js'; import ColorPicker from '../components/ColorPicker.svelte'; + import * as Icon from 'svelte-heros-v2'; + /** + * @type {string | ArrayBuffer | null} + */ let currentFile = null; let redrawFn = ()=>{}; let final = null; - let base_color = ['black']; - let stlWidth = 100 - let stlHeight = 100 + let base_color = ['black', 1]; let thickness = 2; let layerHeight = .08; - let stlMinThickness = .32; - let layers = Math.round(thickness/layerHeight); + let use_gray = true; + /** + * @type {{ resize: (arg0: number, arg1: number) => void; loadPixels: () => void; width: number; height: any; pixels: any[]; } | null} + */ + let img = null; + /** + * @type {{ resize: (arg0: number, arg1: number) => void; loadPixels: () => void; pixels: string | any[]; updatePixels: () => void; canvas: any; } | null} + */ + let copy = null; + let range = use_gray ? 255 : 360 // rgb vs hue ranges + let final_w = 600 // scaling factor for images, use 2 or more if it takes too long to process + let layer = 1 + let total = Date.now() + /** + /** + * @type {null} + */ let mesh = null; - - + let lithoSettings = { + litophaneWidth: 100, + thickness: 2, + minThickness: .32 + } + let layers = Math.round(lithoSettings.thickness/layerHeight); + let subd = Number(range)/Number(layers) let colors = [ ['red', .2, 4], ['yellow', .2 , 7], ['white', .8, 18], ] + const remove = (/** @type {(string | number)[]} */ color) =>{ + colors = colors.filter((c)=> color !== c) + } + + const addColor = ()=>{ + colors = [ ...colors, []]; + } $: { + // @ts-ignore redrawFn(currentFile); layers = Math.round(thickness/layerHeight); } @@ -45,93 +75,85 @@ reader.readAsDataURL(file); } - const sketch = (p5) => { - let img = null; - let copy = null; - let use_gray = true; - let range = use_gray ? 255 : 360 // rgb vs hue ranges + const sketch = (p5) => { + let current_value = null; + let orig_color = p5.color(base_color[0]) + let current_color = base_color - let final_w = 600 // scaling factor for images, use 2 or more if it takes too long to process - // let layers = 21 // stl model layers - let layer = 1 - let total = Date.now() - let subd = null; - let orig_color = null; - let result; - let current_value = null; - let current_color = null; + + let resetColors = () =>{ + orig_color = p5.color(base_color[0]) + current_color = base_color + } - const preload = () => { + p5.preload = () => { img = p5.loadImage(currentFile) copy = p5.loadImage(currentFile) } - function setup(){ - subd = parseInt(range/layers) - img.resize(final_w, 0); - copy.resize(final_w, 0); - img.loadPixels() - copy.loadPixels() + p5.setup = () => { + if(img && copy){ + img.resize(final_w, 0); + copy.resize(final_w, 0); + img.loadPixels() + copy.loadPixels() + } + p5.createCanvas(img.width*2 + 200, img.height, 'WEBGL'); - redrawFn = () => { - layer = 1; - p5.blend(0, 0, final_w, img.height, 0, 0, final_w, img.height, 'REPLACE') - p5.redraw() - p5.loop() - + redrawFn = (/** @type {any} */ file) => { + if(file){ + layer = 1; + p5.blend(0, 0, final_w, img.height, 0, 0, final_w, img.height, 'REPLACE') + resetColors(); + p5.redraw() + p5.loop() + } } } - const draw = () => { + p5.draw = () => { if(layer <= layers) { - let thresh = parseInt(subd * (layer - 1)) // threshold to change pixels\ - + let thresh = subd * (layer - 1) // threshold to change pixels\ for( let i=0 ; i < copy.pixels.length; i+=4){ - if (img.pixels[i + 3] == 0) continue; // skip on transparent pixels for png files - if (layer == 1) { // the origin color for the color mix. After the first layer, it is the current image's color - orig_color = p5.color([base_color[0]]) - current_color = [base_color[0], 1 ] - } else { - orig_color = p5.color(copy.pixels[i], copy.pixels[i + 1], copy.pixels[i + 2]) + if (img?.pixels[i + 3] == 0) continue; // skip on transparent pixels for png files + + if (layer !== 1) { // the origin color for the color mix. After the first layer, it is the current image's color + orig_color = p5.color(copy?.pixels[i], copy?.pixels[i + 1], copy?.pixels[i + 2]) } if (use_gray) { - current_value = (img.pixels[i] + img.pixels[i + 1] + img.pixels[i + 2])/3 + current_value = (img?.pixels[i] + img?.pixels[i + 1] + img?.pixels[i + 2])/3 } else { - let c = p5.color(img.pixels[i], img.pixels[i + 1], img.pixels[i + 2]) + let c = p5.color(img?.pixels[i], img?.pixels[i + 1], img?.pixels[i + 2]) current_value = p5.hue(c) } if(current_value >= thresh){ - current_color = colors.find(color => color[2] == layer) || current_color - result = mixbox.lerp(orig_color.levels, p5.color(current_color[0]).levels, current_color[1]) // color mix using mixbox for accurate pigment mixing results + current_color = colors.find(color => color[2] == layer) || current_color || base_color + let result = mixbox.lerp(orig_color.levels, p5.color(current_color[0]).levels, current_color[1]) // color mix using mixbox for accurate pigment mixing results + // @ts-ignore copy.pixels[i + 0] = result[0] + // @ts-ignore copy.pixels[i + 1] = result[1] + // @ts-ignore copy.pixels[i + 2] = result[2] } } - copy.updatePixels() + copy?.updatePixels() p5.image(copy, 0, 0) p5.image(img, img.width + 20, 0) layer++ } else { console.log("Took:" + (Date.now() - total)/1000.0 + "s") final = copy.canvas; - mesh = imageToMesh(final) + mesh = imageToMesh(final, lithoSettings) p5.noLoop() } } - - - p5.preload = preload; - p5.setup = setup; - p5.draw = draw; - }; -