From 022cdd0a738a97f5d2cef87db1abaab97448abc2 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Thu, 26 Nov 2020 23:18:28 -0500 Subject: [PATCH] checkpoint image import --- src/kiri/client.js | 33 ++++++++++++++++-------- src/kiri/init.js | 6 +---- src/kiri/main.js | 40 ++++++++++++++++++++++++++++- src/kiri/worker.js | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 17 deletions(-) diff --git a/src/kiri/client.js b/src/kiri/client.js index 5262f4f2..8b1a7be4 100644 --- a/src/kiri/client.js +++ b/src/kiri/client.js @@ -54,7 +54,7 @@ KIRI.work = { } }, - isSlicing : function() { + isSlicing: function() { let current = 0; for (let key in slicing) { current++; @@ -62,7 +62,7 @@ KIRI.work = { return current > 0; }, - restart : function() { + restart: function() { if (worker) { worker.terminate(); } @@ -93,7 +93,7 @@ KIRI.work = { }; }, - decimate : function(vertices, options, callback) { + decimate: function(vertices, options, callback) { let alert = KIRI.api.show.alert('processing model', 1000); vertices = vertices.buffer.slice(0); send("decimate", {vertices, options}, function(output) { @@ -102,25 +102,25 @@ KIRI.work = { }); }, - config : function(obj) { + config: function(obj) { send("config", obj, function(reply) { // console.log({config:reply}); }); }, - clear : function(widget) { + clear: function(widget) { send("clear", widget ? {id:widget.id} : {}, function(reply) { // console.log({clear:reply}); }); }, - snap : function(data) { + snap: function(data) { send("snap", data, function(reply) { // console.log({snap:reply}) }); }, - slice : function(settings, widget, callback) { + slice: function(settings, widget, callback) { let rotation = (Math.PI/180) * (settings.process.sliceRotation || 0); let centerz; let movez; @@ -160,7 +160,7 @@ KIRI.work = { }, [vertices]); }, - prepare : function(settings, update, done) { + prepare: function(settings, update, done) { send("prepare", { settings }, function(reply) { if (reply.progress) { update(reply.progress, reply.message, reply.layer); @@ -171,7 +171,7 @@ KIRI.work = { }); }, - export : function(settings, online, ondone) { + export: function(settings, online, ondone) { send("export", { settings }, function(reply) { if (reply.line) { online(reply.line); @@ -182,13 +182,13 @@ KIRI.work = { }); }, - colors : function(colors, max, done) { + colors: function(colors, max, done) { send("colors", { colors, max }, function(reply) { done(reply); }); }, - parse : function(args, progress, done) { + parse: function(args, progress, done) { // have to do this client side because DOMParser is not in workers if (args.type === 'svg') { const { settings, code, type } = args; @@ -214,6 +214,17 @@ KIRI.work = { done(KIRI.codec.decode(reply.parsed), reply.maxSpeed); } }); + }, + + image2mesh: function(data, progress, output) { + send("image2mesh", data, reply => { + if (reply.progress) { + progress(reply.progress); + } + if (reply.done) { + output(reply.done); + } + }, [ data.png ]); } }; diff --git a/src/kiri/init.js b/src/kiri/init.js index f5cfdf1b..d0448ff8 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -1125,10 +1125,6 @@ }); } - function deleteCatalogFile(e) { - CATALOG.deleteFile(e.target.getAttribute('del')); - } - function updateCatalog(files) { let table = UI.catalogList, list = []; @@ -1171,7 +1167,7 @@ del.setAttribute('del', name); del.setAttribute('title', "remove '"+name+"'"); - del.onclick = deleteCatalogFile; + del.onclick = () => { CATALOG.deleteFile(name) }; del.innerHTML = ''; size.setAttribute("disabled", true); diff --git a/src/kiri/main.js b/src/kiri/main.js index 9720450c..2a99348f 100644 --- a/src/kiri/main.js +++ b/src/kiri/main.js @@ -945,6 +945,38 @@ }); } + function loadImage(image) { + KIRI.client.image2mesh({settings, png:image}, progress => { + console.log({i2m_progress: progress}); + }, output => { + console.log({i2m_mesh: output}); + let {verts, index, vi, ii} = output; + + console.log({verts, index, vi, ii}); + + let mat = new THREE.MeshPhongMaterial({ + shininess: 0x101010, + specular: 0x101010, + transparent: true, + opacity: 1, + color: 0x999999, + side: THREE.DoubleSide + }); + + let geo = new THREE.BufferGeometry(); + geo.setAttribute('position', new THREE.BufferAttribute(verts, 3)); + geo.setIndex([...index]); // doesn't like the Uint32Array + geo.computeFaceNormals(); + geo.computeVertexNormals(); + + let mesh = new THREE.Mesh(geo, mat); + mesh.castShadow = true; + mesh.receiveShadow = true; + + SPACE.platform.world.add(mesh); + }); + } + /** ****************************************************************** * Selection Functions ******************************************************************* */ @@ -1695,6 +1727,7 @@ israw = lower.indexOf(".raw") > 0 || lower.indexOf('.') < 0, isstl = lower.indexOf(".stl") > 0, issvg = lower.indexOf(".svg") > 0, + ispng = lower.indexOf(".png") > 0, isgcode = lower.indexOf(".gcode") > 0 || lower.indexOf(".nc") > 0, isset = lower.indexOf(".b64") > 0 || lower.indexOf(".km") > 0; reader.file = files[i]; @@ -1717,9 +1750,14 @@ if (isgcode) loadCode(e.target.result, 'gcode'); if (issvg) loadCode(e.target.result, 'svg'); if (isset) settingsImport(e.target.result, true); + if (ispng) loadImage(e.target.result); if (--loaded === 0) platform.group_done(isgcode); }; - reader.readAsBinaryString(reader.file); + if (isstl || ispng) { + reader.readAsArrayBuffer(reader.file); + } else { + reader.readAsBinaryString(reader.file); + } } } diff --git a/src/kiri/worker.js b/src/kiri/worker.js index afab532e..7a38d76e 100644 --- a/src/kiri/worker.js +++ b/src/kiri/worker.js @@ -238,6 +238,70 @@ KIRI.worker = { console.log({invalid:data}); } send.done({config: update}); + }, + + image2mesh: function(info, send) { + let img = new png.PNG(); + img.parse(info.png, (err, output) => { + let { width, height, data } = output; + let { bedDepth, bedWidth } = info.settings.device; + let imageAspect = height / width; + let deviceAspect = bedDepth / bedWidth; + let div = 1; + if (imageAspect < deviceAspect) { + div = width / bedWidth; + } else { + div = height / bedDepth; + } + send.data({progress: { width, height }}); + let points = + width * height + // grid + height * 2 + // left/right + width * 2 - // top/bottom + 4 // base shared corners + ; + let lines = + ((height - 1) * (width - 1)) + // grid + ((height - 1) * (width )) + // grid + ((height ) * (width - 1)) + // grid + ((height * 3) - 2) + // left/right + ((width * 3) - 2) + // top/bottom + 1 // across base + ; + let verts = new Float32Array(points * 3); + let index = new Uint32Array(lines * 2); + let vi = 0; + let ii = 0; + let w2 = width / 2; + let h2 = height / 2; + for (let x = 0; x < width; x++) { + for (let y = 0; y < height; y++) { + let di = (x + width * y) * 4; + let r = data[di]; + let g = data[di+1]; + let b = data[di+2]; + let v = (r + g + b) / 3; + verts[vi++] = (-w2 + x) / div; + verts[vi++] = (h2 - y) / div; + verts[vi++] = ((255 - v) / 50); + if (x > 0 && y > 0) { + let p1 = (x - 1) * height + (y - 0); + let p2 = (x - 0) * height + (y - 1); + let p3 = (x - 0) * height + (y - 0); + let p4 = (x - 1) * height + (y - 1); + index[ii++] = p1; + index[ii++] = p2; + index[ii++] = p3; + index[ii++] = p1; + index[ii++] = p4; + index[ii++] = p2; + } + } + } + verts = verts.slice(0, vi); + index = index.slice(0, ii); + send.done({done: {verts, index, vi, ii}}); + }); } };