checkpoint sketch work

This commit is contained in:
Stewart Allen 2024-07-23 22:42:20 -04:00
commit 32e57fd00e
6 changed files with 111 additions and 32 deletions

View file

@ -1,5 +1,5 @@
#!/bin/bash
tag=${1:-latest}
./bin/build-upload mac ${tag} && \
./bin/build-upload win ${tag} && \
./bin/build-upload linux ${tag}
./bin/build-upload linux ${tag} && \
./bin/build-upload mac ${tag}

View file

@ -8,6 +8,9 @@
// dep: moto.space
// dep: mesh.util
// dep: mesh.edges
// dep: mesh.group
// dep: mesh.model
// dep: mesh.sketch
// dep: add.three
// use: add.array
gapp.register("mesh.api", [], (root, exports) => {
@ -20,6 +23,7 @@ const { newPolygon } = base;
const worker = moto.client.fn
const groups = [];
const sketches = [];
let selected = [];
let tools = [];
@ -30,7 +34,7 @@ const selection = {
},
// @returns {MeshObject[]} or all groups if not strict and no selection
list(strict = false) {
list(strict) {
return selected.length || strict ? selected.slice() : groups.slice();
},
@ -156,6 +160,9 @@ const selection = {
opacity: prefs.map.wireframe.opacity}
);
}
for (let sketch of sketches) {
sketch.select(false);
}
api.updateFog();
// prevent selection of model and its group
let mgsel = selected.filter(s => s instanceof mesh.model).map(m => m.group);
@ -377,7 +384,30 @@ let model = {
}
};
let sketch = {
add(sk) {
sketches.addOnce(sk);
space.world.add(sk.object);
api.selection.update();
return sk;
},
remove(sk) {
sketches.remove(sk);
space.world.remove(sk.object);
space.update();s
},
list() {
return sketches;
}
};
let add = {
sketch() {
sketch.add(new mesh.sketch());
},
input() {
api.modal.dialog({
title: "vertices",
@ -695,7 +725,7 @@ const tool = {
}
},
rename(models) {
rename(models, type = 'model') {
models = fallback(models, true);
let model = models[0];
if (!model) {
@ -712,7 +742,7 @@ const tool = {
selection.update();
api.modal.hide();
};
let { tempedit } = api.modal.show(`rename model`, h.div({ class: "rename"}, [
let { tempedit } = api.modal.show(`rename ${type}`, h.div({ class: "rename"}, [
h.input({ id: "tempedit", value: model.file, onkeydown }),
h.button({ _: 'ok', onclick })
]));
@ -883,28 +913,28 @@ const mode = {
},
object() {
if (mode.is([ modes.face, modes.surface ])) {
if (!mode.is([ modes.object, modes.tool ])) {
selection.clear();
}
mode.set(modes.object);
},
tool() {
if (mode.is([ modes.face, modes.surface ])) {
if (!mode.is([ modes.object, modes.tool ])) {
selection.clear();
}
mode.set(modes.tool);
},
face() {
if (mode.is([ modes.object, modes.tool ])) {
if (!mode.is([ modes.face, modes.surface ])) {
selection.clear();
}
mode.set(modes.face);
},
surface() {
if (mode.is([ modes.object, modes.tool ])) {
if (!mode.is([ modes.face, modes.surface ])) {
selection.clear();
}
mode.set(modes.surface);
@ -1089,6 +1119,8 @@ const api = exports({
model,
sketch,
add,
file,

View file

@ -387,6 +387,8 @@ function ui_build() {
h.button({ _: 'cylinder', onclick() { add.cylinder() } }),
h.button({ _: 'cube', onclick() { add.cube() } }),
h.button({ _: 'gear', onclick() { add.gear() } }),
h.hr(),
h.button({ _: 'sketch', onclick() { add.sketch() } }),
devel ? h.button({ _: 'input', onclick: add.input }) : undefined
])
]),
@ -488,7 +490,10 @@ function ui_build() {
.map(g => h.div([
h.button({ _: g.name || `group`, title: g.id,
class: [ "group", selHas(g) ? 'selected' : undefined ],
onclick(e) { selection.toggle(g) }
onclick(e) {
api.mode.object();
selection.toggle(g);
}
}),
h.div({ class: "models"},
// map models to buttons
@ -499,18 +504,17 @@ function ui_build() {
if (e.shiftKey) {
tool.rename([ m ]);
} else {
if (!api.mode.is([ api.modes.object, api.modes.tool ])) {
api.mode.object();
}
selection.toggle(m);
}
},
onmouseover(e) {
if (!m.wireframe().enabled) {
m.opacity({temp: 0.5});
}
m.highlight();
},
onmouseleave(e) {
if (!m.wireframe().enabled) {
m.opacity({restore: true});
}
m.unhighlight();
}
}),
h.button({
@ -523,6 +527,42 @@ function ui_build() {
])
)
]));
let sketches = api.sketch.list();
if (sketches.length) {
let sg = h.div([
h.button({ _: 'sketch',
class: [ "group" ],
}),
sketches.map(sketch => h.div({ class: "models"}, [
h.button({ _: sketch.file || sketch.id,
class: [ selHas(sketch) ? 'selected' : undefined ],
onclick(e) {
if (e.shiftKey) {
tool.rename([ sketch ], 'sketch');
} else {
selection.toggle(sketch);
}
},
onmouseover(e) {
sketch.highlight();
},
onmouseleave(e) {
sketch.unhighlight();
}
}),
h.button({
class: [ 'square' ],
onclick(e) {
sketch.visible({ toggle: true });
update_selector();
}
}, [
h.raw(sketch.visible() ? eye_open : eye_closed)
])
]))
]);
groups.push(sg);
}
h.bind(grouplist, groups);
}
@ -564,8 +604,8 @@ function ui_build() {
// update model information dashboard (bottom)
function update_selection() {
let map = { fixed: 2 };
let s_grp = selection.groups();
let s_mdl = selection.models();
let s_grp = selection.groups(true);
let s_mdl = selection.models(true);
if (s_mdl.length === 0) {
return h.bind(selectlist, []);
}

View file

@ -89,6 +89,7 @@ let edges = {
},
async add() {
console.log({ add: selected.slice() });
if (selected.length === 2 && selected[0].object === selected[1].object) {
let verts = selected.map(s => [ s.side.p0, s.side.p1 ]).flat();
// clean up floating point cruft for comparison
@ -113,7 +114,7 @@ let edges = {
point.z !== arr[index - 1].z;
});
let model = selected[0].object.model;
if (verts.length === 3) {
if (sort.length === 3) {
await model.duplicate({ append: [
sort[0].x, -sort[0].z, sort[0].y,
sort[1].x, -sort[1].z, sort[1].y,
@ -125,8 +126,8 @@ let edges = {
verts[0].x, -verts[0].z, verts[0].y,
verts[1].x, -verts[1].z, verts[1].y,
verts[2].x, -verts[2].z, verts[2].y,
verts[1].x, -verts[1].z, verts[1].y,
verts[2].x, -verts[2].z, verts[2].y,
verts[1].x, -verts[1].z, verts[1].y,
verts[3].x, -verts[3].z, verts[3].y,
]});
model.remove();
@ -144,6 +145,7 @@ let edges = {
select() {
space.scene.remove(edges.selected);
if (!hovered) return;
const { object, face, side } = hovered;
let add = true;

View file

@ -281,17 +281,6 @@ mesh.model = class MeshModel extends mesh.object {
return this.vertices / 3;
}
// get, set, or toggle visibility of model and wireframe
visible(bool) {
if (bool === undefined) {
return this.mesh.visible;
}
if (bool.toggle) {
return this.visible(!this.mesh.visible);
}
this.mesh.visible = bool;
}
// get, set, or toggle selection of model (coloring)
select(bool, stool) {
const cmat = this.mesh.material[0];
@ -344,6 +333,18 @@ mesh.model = class MeshModel extends mesh.object {
space.update();
}
highlight() {
if (!this.wireframe().enabled) {
this.opacity({temp: 0.5});
}
}
unhighlight() {
if (!this.wireframe().enabled) {
this.opacity({restore: true});
}
}
wireframe(bool, opt = {}) {
let was = this._wire ? true : false;
if (bool === undefined) {

View file

@ -64,7 +64,11 @@ mesh.object = class MeshObject {
}
select() {
mesh.api.selection.set([this]);
throw "select() requires implementation";
}
remove() {
throw "remove() requires implementation";
}
focus() {