restrict selections to models

This commit is contained in:
Stewart Allen 2022-04-21 10:14:12 -04:00
commit 5ba57ef249
3 changed files with 45 additions and 40 deletions

View file

@ -27,6 +27,7 @@ Full docs @ https://docs.grid.space/projects/kiri-moto
* `-` parameterize svg and image import * `-` parameterize svg and image import
* `-` undo / redo for some operations * `-` undo / redo for some operations
* `-` show camera focal point * `-` show camera focal point
* `-` better Z split snapping and split at defined Z index
# Release 3.3 (2022-04-01) # Release 3.3 (2022-04-01)

View file

@ -59,43 +59,48 @@ const selection = {
// @param group {MeshObject[]} // @param group {MeshObject[]}
set(objects, toolist) { set(objects, toolist) {
selected = objects; // flatten groups into model lists when present
selected = objects.map(o => o.models ? o.models : o).flat();
tools = toolist || []; tools = toolist || [];
util.defer(selection.update); util.defer(selection.update);
}, },
// @param group {MeshObject} // @param group {MeshObject}
add(object, tool) { add(object, tool = mode.is([ modes.tool ])) {
// pendantic code necessary to minimize re-entrant api calls // when group added, add group models instead
if (object.models) { if (object.models) {
// if group, remove discrete selected members
for (let m of object.models) { for (let m of object.models) {
if (selected.contains(m)) { selected.addOnce(m);
selection.remove(m); if (tool) {
tools.remove(m); tools.addOnce(m);
} }
} }
} else { } else {
// if model, remove selcted group selected.addOnce(object);
if (selected.contains(object.group)) { if (tool) {
selection.remove(object.group); tools.addOnce(object);
tools.remove(object.group);
} }
} }
selected.addOnce(object);
if (tool) tools.addOnce(object);
util.defer(selection.update); util.defer(selection.update);
}, },
// @param group {MeshObject} // @param group {MeshObject}
remove(object) { 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); util.defer(selection.update);
}, },
// remove all // remove all
delete() { delete() {
for (let s of selection.list()) { for (let s of selection.list(true)) {
selection.remove(s); selection.remove(s);
tools.remove(s); tools.remove(s);
s.showBounds(false); s.showBounds(false);
@ -104,13 +109,19 @@ const selection = {
}, },
// @param group {MeshObject} // @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)) { if (selected.contains(object)) {
selection.remove(object); selection.remove(object);
tools.remove(object);
} else { } else {
selection.add(object); selection.add(object, tool);
if (tool) tools.addOnce(object);
} }
}, },

View file

@ -437,9 +437,7 @@ function ui_build() {
.map(g => h.div([ .map(g => h.div([
h.button({ _: g.name || `group`, title: g.id, h.button({ _: g.name || `group`, title: g.id,
class: [ "group", selHas(g) ? 'selected' : undefined ], class: [ "group", selHas(g) ? 'selected' : undefined ],
onclick(e) { onclick(e) { selection.toggle(g) }
e.shiftKey ? selection.toggle(g) : selection.set([g])
}
}), }),
h.div({ class: "vsep" }), h.div({ class: "vsep" }),
h.div({ class: "models"}, h.div({ class: "models"},
@ -447,12 +445,7 @@ function ui_build() {
g.models.map(m => [ g.models.map(m => [
h.button({ _: m.file || m.id, h.button({ _: m.file || m.id,
class: [ selHas(m) ? 'selected' : undefined ], class: [ selHas(m) ? 'selected' : undefined ],
onclick(e) { onclick(e) { selection.toggle(m) }
let sel = selection.list();
e.shiftKey || (sel.length === 1 && m === sel[0]) ?
selection.toggle(m) :
selection.set([m])
}
}), }),
h.button({ h.button({
class: [ 'square' ], class: [ 'square' ],
@ -532,7 +525,7 @@ function ui_build() {
let g_pos = util.average(s_grp.map(g => g.object.position)); 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_rot = util.average(s_grp.map(g => g.object.rotation));
let g_id = s_grp.map(g => g.id).join(' '); 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_pos, map),
util.extract(g_rot).map(r => (r * rad).round(2).toFixed(map.fixed)), util.extract(g_rot).map(r => (r * rad).round(2).toFixed(map.fixed)),
und, und, 'group' und, und, 'group'
@ -541,17 +534,17 @@ function ui_build() {
let m_pos = util.average(s_mdl.map(m => m.object.position)); 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_rot = util.average(s_mdl.map(m => m.object.rotation));
let m_id = s_mdl.map(m => m.id).join(' '); let m_id = s_mdl.map(m => m.id).join(' ');
let h_mdl = sblock('model', m_id, grid( // let h_mdl = sblock('model', m_id, grid(
util.extract(m_pos, map), // util.extract(m_pos, map),
util.extract(m_rot, map) // util.extract(m_rot, map)
)); // ));
let bounds = util.bounds(s_mdl); let bounds = util.bounds(s_mdl);
let h_bnd = sblock('box', m_id, grid( // let h_bnd = sblock('bounds', m_id, grid(
util.extract(bounds.min, map), // util.extract(bounds.min, map),
util.extract(bounds.max, map), // util.extract(bounds.max, map),
[ "min", "max" ] // [ "min", "max" ]
)); // ));
let h_ara = sblock('span', m_id, grid( let h_ara = sblock('span', m_id, grid(
util.extract(bounds.center, map), util.extract(bounds.center, map),
util.extract(bounds.size, map), util.extract(bounds.size, map),
@ -591,8 +584,8 @@ function ui_build() {
// bind elements to selectlist div // bind elements to selectlist div
let bound = h.bind(selectlist, [ let bound = h.bind(selectlist, [
...h_grp, ...h_grp,
...h_mdl, // ...h_mdl,
...h_bnd, // ...h_bnd,
...h_ara, ...h_ara,
...h_msh, ...h_msh,
...h_ops ...h_ops