diff --git a/release.md b/release.md index 3a709191..6bcf7a51 100644 --- a/release.md +++ b/release.md @@ -27,6 +27,7 @@ Full docs @ https://docs.grid.space/projects/kiri-moto * `-` parameterize svg and image import * `-` undo / redo for some operations * `-` show camera focal point +* `-` better Z split snapping and split at defined Z index # Release 3.3 (2022-04-01) diff --git a/src/mesh/api.js b/src/mesh/api.js index e5e21ac8..ad8d8be7 100644 --- a/src/mesh/api.js +++ b/src/mesh/api.js @@ -59,43 +59,48 @@ const selection = { // @param group {MeshObject[]} set(objects, toolist) { - selected = objects; + // flatten groups into model lists when present + selected = objects.map(o => o.models ? o.models : o).flat(); tools = toolist || []; util.defer(selection.update); }, // @param group {MeshObject} - add(object, tool) { - // pendantic code necessary to minimize re-entrant api calls + add(object, tool = mode.is([ modes.tool ])) { + // when group added, add group models instead if (object.models) { - // if group, remove discrete selected members for (let m of object.models) { - if (selected.contains(m)) { - selection.remove(m); - tools.remove(m); + selected.addOnce(m); + if (tool) { + tools.addOnce(m); } } } else { - // if model, remove selcted group - if (selected.contains(object.group)) { - selection.remove(object.group); - tools.remove(object.group); + selected.addOnce(object); + if (tool) { + tools.addOnce(object); } } - selected.addOnce(object); - if (tool) tools.addOnce(object); util.defer(selection.update); }, // @param group {MeshObject} remove(object) { - selected.remove(object); + if (object.models) { + for (let m of object.models) { + selected.remove(m); + tools.remove(m); + } + } else { + selected.remove(object); + tools.remove(object); + } util.defer(selection.update); }, // remove all delete() { - for (let s of selection.list()) { + for (let s of selection.list(true)) { selection.remove(s); tools.remove(s); s.showBounds(false); @@ -104,13 +109,19 @@ const selection = { }, // @param group {MeshObject} - toggle(object, tool) { + toggle(object, tool = mode.is([ modes.tool ])) { + if (object.models) { + for (let m of object.models) { + if (selected.contains(m)) { + return selection.remove(object); + } + } + return selection.add(object, tool); + } if (selected.contains(object)) { selection.remove(object); - tools.remove(object); } else { - selection.add(object); - if (tool) tools.addOnce(object); + selection.add(object, tool); } }, diff --git a/src/mesh/build.js b/src/mesh/build.js index 465ca08f..05b987c5 100644 --- a/src/mesh/build.js +++ b/src/mesh/build.js @@ -437,9 +437,7 @@ function ui_build() { .map(g => h.div([ h.button({ _: g.name || `group`, title: g.id, class: [ "group", selHas(g) ? 'selected' : undefined ], - onclick(e) { - e.shiftKey ? selection.toggle(g) : selection.set([g]) - } + onclick(e) { selection.toggle(g) } }), h.div({ class: "vsep" }), h.div({ class: "models"}, @@ -447,12 +445,7 @@ function ui_build() { g.models.map(m => [ h.button({ _: m.file || m.id, class: [ selHas(m) ? 'selected' : undefined ], - onclick(e) { - let sel = selection.list(); - e.shiftKey || (sel.length === 1 && m === sel[0]) ? - selection.toggle(m) : - selection.set([m]) - } + onclick(e) { selection.toggle(m) } }), h.button({ class: [ 'square' ], @@ -532,7 +525,7 @@ function ui_build() { let g_pos = util.average(s_grp.map(g => g.object.position)); let g_rot = util.average(s_grp.map(g => g.object.rotation)); let g_id = s_grp.map(g => g.id).join(' '); - let h_grp = sblock('group', g_id, grid( + let h_grp = sblock('orient', g_id, grid( util.extract(g_pos, map), util.extract(g_rot).map(r => (r * rad).round(2).toFixed(map.fixed)), und, und, 'group' @@ -541,17 +534,17 @@ function ui_build() { let m_pos = util.average(s_mdl.map(m => m.object.position)); let m_rot = util.average(s_mdl.map(m => m.object.rotation)); let m_id = s_mdl.map(m => m.id).join(' '); - let h_mdl = sblock('model', m_id, grid( - util.extract(m_pos, map), - util.extract(m_rot, map) - )); + // let h_mdl = sblock('model', m_id, grid( + // util.extract(m_pos, map), + // util.extract(m_rot, map) + // )); let bounds = util.bounds(s_mdl); - let h_bnd = sblock('box', m_id, grid( - util.extract(bounds.min, map), - util.extract(bounds.max, map), - [ "min", "max" ] - )); + // let h_bnd = sblock('bounds', m_id, grid( + // util.extract(bounds.min, map), + // util.extract(bounds.max, map), + // [ "min", "max" ] + // )); let h_ara = sblock('span', m_id, grid( util.extract(bounds.center, map), util.extract(bounds.size, map), @@ -591,8 +584,8 @@ function ui_build() { // bind elements to selectlist div let bound = h.bind(selectlist, [ ...h_grp, - ...h_mdl, - ...h_bnd, + // ...h_mdl, + // ...h_bnd, ...h_ara, ...h_msh, ...h_ops