From 0cb2323aaf50dd849a5a7a0a31790bdc6ee4d65c Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Tue, 2 Nov 2021 11:58:00 -0400 Subject: [PATCH] add widget vertex replace. bump rev 3.1.D0 --- app.js | 1 + package.json | 2 +- src/kiri.js | 2 +- src/kiri/init.js | 1 + src/kiri/main.js | 32 +++++++++++++++++++++++ src/license.js | 2 +- src/moto/load-file.js | 60 +++++++++++++++++++++++++++++++++++++++++++ web/kiri/index.html | 3 ++- web/kiri/lang/en.js | 1 + 9 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 src/moto/load-file.js diff --git a/app.js b/app.js index 360df5e2..1aba7743 100644 --- a/app.js +++ b/app.js @@ -252,6 +252,7 @@ const script = { "moto/load-stl", "moto/load-svg", "moto/load-url", + "moto/load-file", "moto/db", "kiri/ui", "kiri/do", diff --git a/package.json b/package.json index 62fb3921..feab3504 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grid-apps", - "version": "3.0.34D", + "version": "3.1.0D", "description": "grid.space 3d slice & modeling tools", "author": "Stewart Allen ", "license": "MIT", diff --git a/src/kiri.js b/src/kiri.js index 1858456f..89d61ce4 100644 --- a/src/kiri.js +++ b/src/kiri.js @@ -6,7 +6,7 @@ if (!self.kiri) { let kiri = self.kiri = { - beta: 3034, + beta: 3100, driver: {}, // driver modules loader: [], // module loading: array of functions load: (fn) => kiri.loader.push(fn) diff --git a/src/kiri/init.js b/src/kiri/init.js index ac320eff..2846b6e0 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -2626,6 +2626,7 @@ $('render-solid').onclick = () => { API.view.wireframe(false, 0, 1); }; // mesh buttons $('mesh-heal').onclick = () => { API.widgets.heal() }; + $('mesh-swap').onclick = () => { API.widgets.replace() }; $('mesh-export-stl').onclick = () => { objectsExport('stl') }; $('mesh-export-obj').onclick = () => { objectsExport('obj') }; // context menu diff --git a/src/kiri/main.js b/src/kiri/main.js index 353d2cf1..9d7a0a30 100644 --- a/src/kiri/main.js +++ b/src/kiri/main.js @@ -401,6 +401,7 @@ for: forAllWidgets, load: Widget.loadFromCatalog, heal: healWidgets, + replace: replaceVertices, meshes: meshArray, opacity: setOpacity, annotate: (id) => { @@ -884,6 +885,37 @@ return out; } + function replaceVertices(vertices) { + let widgets = API.selection.widgets(true); + if (!widgets.length) { + return; + } + function onload(vertices) { + for (let w of widgets) { + let track = Object.clone(w.track); + let { scale, rot, pos } = track; + let roto = w.roto.slice(); + w.loadVertices(vertices); + for (let m of roto) { + w.mesh.geometry.applyMatrix4(m.clone()); + } + w._scale(scale.x, scale.y, scale.z); + } + platform.update(); + } + if (vertices) { + onload(vertices); + } else { + // dialog + $('load-file').onchange = function(event) { + MOTO.File.load(event.target.files[0]) + .then(data => onload(data[0].mesh)) + .catch(error => console.log({error})); + }; + $('load-file').click(); + } + } + function healWidgets() { let widgets = API.widgets.all(); let marker; diff --git a/src/license.js b/src/license.js index 7737b737..88cec1bd 100644 --- a/src/license.js +++ b/src/license.js @@ -3,7 +3,7 @@ let terms = { COPYRIGHT: "Copyright (C) Stewart Allen - All Rights Reserved", LICENSE: "See the license.md file included with the source distribution", - VERSION: "3.0.D34" + VERSION: "3.1.D0" }; if (typeof(module) === 'object') { diff --git a/src/moto/load-file.js b/src/moto/load-file.js new file mode 100644 index 00000000..136932e9 --- /dev/null +++ b/src/moto/load-file.js @@ -0,0 +1,60 @@ +'use strict'; + +(function() { + if (!self.moto) self.moto = {}; + if (self.moto.File) return; + + function load_data(data, file, ext) { + ext = ext || name.toLowerCase().split('.').pop(); + return new Promise((resolve, reject) => { + switch (ext) { + case "stl": + resolve([{ + mesh: new moto.STL().parse(data), file + }]); + break; + case "obj": + resolve(moto.OBJ.parse(data).map(m => { return {mesh: m.toFloat32(), file} })); + break; + case "3mf": + moto.TMF.parseAsync(data).then((meshes) => { + resolve(meshes.map(m => { + return { mesh: m.faces.toFloat32(), file } + })); + }); + break; + case "svg": + resolve(moto.SVG.parse(data).map(m => { return {mesh: m.toFloat32(), file} })); + break; + default: + reject(`unknown file type: "${ext}" from ${url}`); + break; + } + }); + } + + function load(file) { + return new Promise((resolve, reject) => { + let reader = new FileReader(); + let name = file.name; + let ext = name.toLowerCase().split('.').pop(); + reader.file = file; + reader.onloadend = function (event) { + load_data(event.target.result, name, ext) + .then(data => resolve(data)) + .catch(e => reject(e)); + }; + if (ext === 'stl') { + reader.readAsArrayBuffer(reader.file); + } else { + reader.readAsBinaryString(reader.file); + } + }); + } + + self.moto.File = { + load_data, + load + }; + +})(); diff --git a/web/kiri/index.html b/web/kiri/index.html index 05349a55..3d67298d 100644 --- a/web/kiri/index.html +++ b/web/kiri/index.html @@ -139,7 +139,8 @@ - + +
diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index ea11f669..0d5f31a9 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -57,6 +57,7 @@ kiri.lang['en-us'] = { rc_dupl: "duplicate", rc_focs: "set focus", rc_heal: "heal meshes", + rc_swap: "replace vertices", rc_xobj: "export OBJ", rc_xstl: "export STL",