From f334ae797bb155f8f5c6b3153014b765971a493a Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Fri, 25 Feb 2022 13:56:09 -0500 Subject: [PATCH] add pref for normals length and color --- release.md | 7 ++++--- src/main/mesh.js | 26 +++++++++++++++++++++++--- src/mesh/api.js | 5 +++++ src/mesh/build.js | 29 ++++++++++++++++++++++++----- src/mesh/model.js | 2 +- src/mesh/util.js | 22 ++++++++++++++++++++-- web/mesh/index.css | 13 +++++++++++++ 7 files changed, 90 insertions(+), 14 deletions(-) diff --git a/release.md b/release.md index ae6c9352..fa207deb 100644 --- a/release.md +++ b/release.md @@ -22,12 +22,13 @@ * `P` limit non-manifold solution search depth (parameterize) * `P` refactor slicers to use single improved slice core (cnc tbd) * `P` template vars: nozzles used and layers until next use (IDEX) -* `-` improved vertex replacement +* `-` improved vertex replacement and widget update matrix tracking * `-` workflow to edit in M:T and bounce back / replace vertices * `-` tighten export dialogs (reduce size for smaller screens) ## Mesh:Tool -* `-` face selection and matching preferences -* `-` add prefs for normal length, maybe color picker +* `C` add preferences for normal length and color +* `-` add preferences for face selection and matching * `-` svg and image import conversion (share code with Kiri:Moto) +* `-` welcome help menu diff --git a/src/main/mesh.js b/src/main/mesh.js index e2503446..8c4b813a 100644 --- a/src/main/mesh.js +++ b/src/main/mesh.js @@ -525,15 +525,35 @@ function set_darkmode(dark) { prefs.save(); } +function set_normals_length(length) { + let { prefs } = mesh.api; + prefs.map.normals.length = length || 1; + prefs.save(); +} + +function set_normals_color(color) { +console.log({color}); + let { prefs } = mesh.api; + let { map } = prefs; + if (map.space.dark) { + map.normals.color_dark = color || 0; + } else { + map.normals.color_lite = color || 0; + } + prefs.save(); +} + // bind functions to topics broker.listeners({ + edit_split, load_files, - space_init, - space_load, object_matrix, object_destroy, + space_init, + space_load, set_darkmode, - edit_split + set_normals_color, + set_normals_length, }); // remove version cache bust from url diff --git a/src/mesh/api.js b/src/mesh/api.js index f6ad11b9..8eb02e12 100644 --- a/src/mesh/api.js +++ b/src/mesh/api.js @@ -504,6 +504,11 @@ const prefs = { dark: false, select: [] }, + normals: { + length: 0.5, + color_lite: 0xff0000, + color_dark: 0x00ffff + } }, // look for changes in pref signature diff --git a/src/mesh/build.js b/src/mesh/build.js index 1b32fb4e..54e4cd2b 100644 --- a/src/mesh/build.js +++ b/src/mesh/build.js @@ -178,13 +178,16 @@ gapp.broker.subscribe("mesh.log", log.emit); // bind settings endpoint to api api.settings = function() { - let { prefs } = api; - let { space } = prefs.map; - modal.show('settings', h.div({ class: "settings" }, [ + const { util } = mesh; + const { prefs } = api; + const { normals, space } = prefs.map; + const { dark } = space; + + const col1 = h.div([ h.label('dark mode'), h.input({ type: "checkbox", onchange: ev => call.set_darkmode(ev.target.checked), - [ space.dark ? 'checked' : 'unchecked' ] : 1 + [ dark ? 'checked' : 'unchecked' ] : 1 }), h.label('auto floor'), h.input({ type: "checkbox", @@ -196,7 +199,23 @@ api.settings = function() { onchange: ev => prefs.save( space.center = !space.center ), [ space.center !== false ? 'checked' : 'unchecked' ] : 1 }), - ])); + ]); + + const col2 = h.div([ + h.label(''), + h.label('normals'), + h.label('length'), + h.input({ type: "text", size: 5, value: normals.length, + onchange: ev => call.set_normals_length(ev.target.value) + }), + h.label('color'), + h.input({ type: "text", size: 5, + value: util.toHexRGB(dark ? normals.color_dark : normals.color_lite), + onchange: ev => call.set_normals_color(util.fromHexRGB(ev.target.value)) + }), + ]); + + modal.show('settings', h.div({ class: "settings" }, [ col1, col2 ] )); } // create html elements diff --git a/src/mesh/model.js b/src/mesh/model.js index a8947fd5..cd0841b4 100644 --- a/src/mesh/model.js +++ b/src/mesh/model.js @@ -358,7 +358,7 @@ mesh.model = class MeshModel extends mesh.object { this._norm = undefined; } if (bool) { - this.mesh.add(this._norm = mesh.util.faceNormals(this.mesh, { size: 0.5 })); + this.mesh.add(this._norm = mesh.util.faceNormals(this.mesh)); } } diff --git a/src/mesh/util.js b/src/mesh/util.js index 8a118f7c..004336ea 100644 --- a/src/mesh/util.js +++ b/src/mesh/util.js @@ -25,6 +25,21 @@ const util = exports({ return uid.join('-'); }, + toHexRGB(v) { + return [ + ((v >> 16) & 0xff).toString(16).padStart(2,0), + ((v >> 8) & 0xff).toString(16).padStart(2,0), + ((v >> 0) & 0xff).toString(16).padStart(2,0) + ].join(''); + }, + + fromHexRGB(v) { + return 0 + + parseInt(v.substring(0,2), 16) << 16 | + parseInt(v.substring(2,4), 16) << 8 | + parseInt(v.substring(4,6), 16); + }, + // add comma separator to 1000s comma(val) { let str = val.toString().split("."); @@ -169,10 +184,13 @@ const util = exports({ const _v1 = new THREE.Vector3(); const _v2 = new THREE.Vector3(); const _normalMatrix = new THREE.Matrix3(); - const defcolor = mesh.api.prefs.map.space.dark ? 0x00ffff : 0xff0000; + const prefs = mesh.api.prefs.map; + const norms = prefs.normals; + const defcolor = prefs.space.dark ? norms.color_dark : norms.color_lite; + const normlen = norms.length || 1; class FaceNormalsHelper extends THREE.LineSegments { - constructor(object, size = opt.size || 1, color = opt.color || defcolor) { + constructor(object, size = opt.size || normlen, color = opt.color || defcolor) { const objGeometry = object.geometry; const nNormals = objGeometry.attributes.position.count / 3; const geometry = new THREE.BufferGeometry(); diff --git a/web/mesh/index.css b/web/mesh/index.css index d54abb1f..9506321e 100644 --- a/web/mesh/index.css +++ b/web/mesh/index.css @@ -270,12 +270,25 @@ button:hover { /** settings dialog **/ .settings { + gap: 5px; +} + +.settings > div { display: grid; grid: min-content 1fr / min-content 1fr; white-space: nowrap; align-items: center; } +.settings label { + padding: 0 5px 0 3px; +} + +.settings input { + font-family: monospace; + text-align: center; +} + /** spinner animation **/ @keyframes spinner {