checkpoint sketch work
This commit is contained in:
parent
c00e4995e6
commit
32e57fd00e
6 changed files with 111 additions and 32 deletions
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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, []);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,11 @@ mesh.object = class MeshObject {
|
|||
}
|
||||
|
||||
select() {
|
||||
mesh.api.selection.set([this]);
|
||||
throw "select() requires implementation";
|
||||
}
|
||||
|
||||
remove() {
|
||||
throw "remove() requires implementation";
|
||||
}
|
||||
|
||||
focus() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue