diff --git a/src/main/mesh.js b/src/main/mesh.js index fa2371af..420b1b65 100644 --- a/src/main/mesh.js +++ b/src/main/mesh.js @@ -364,6 +364,8 @@ function space_init(data) { const opt = { radians: 0, radius: surface.radius }; const mode = api.mode.get(); switch(mode) { + case modes.sketch: + api.mode.object(); case modes.object: case modes.tool: selection.toggle(shiftKey ? model : model.group, mode === modes.tool); diff --git a/src/mesh/api.js b/src/mesh/api.js index d3f8846c..1aaa4469 100644 --- a/src/mesh/api.js +++ b/src/mesh/api.js @@ -83,8 +83,9 @@ const selection = { // eject incompatible types from selection switch (object.type) { case 'sketch': - selected = selected.filter(s => s.type === 'sketch'); + mode.sketch(); tools.length = 0; + selected.length = 0; mesh.edges?.end(); break; case 'group': @@ -897,6 +898,7 @@ const modes = { face: "face", // facet / triangle surface: "surface", // normal aligned & adjacent faces edge: "edge", // edge of a face + sketch: "sketch", // 2D sketching }; // edit mode @@ -909,6 +911,13 @@ const mode = { $(`mode-${mode}`).classList.add('selected'); api.mode.check(); mesh.edges?.end(); + if (mode === 'sketch') { + $C('sketch-on', null, 'hide'); + $C('sketch-off', 'hide', null); + } else { + $C('sketch-off', null, 'hide'); + $C('sketch-on', 'hide', null); + } }, get() { @@ -962,6 +971,13 @@ const mode = { } mode.set(modes.edge); mesh.edges.start(); + }, + + sketch() { + if (!mode.is([ modes.sketch ])) { + selection.clear(); + } + mode.set(modes.sketch); } }; diff --git a/src/mesh/build.js b/src/mesh/build.js index 9f3a38fd..703c33b9 100644 --- a/src/mesh/build.js +++ b/src/mesh/build.js @@ -362,6 +362,8 @@ function ui_build() { h.button({ _: 'surface', id: "mode-surface", onclick() { mode.surface() } }), h.button({ _: 'face', id: "mode-face", onclick() { mode.face() } }), h.button({ _: 'edge', id: "mode-edge", onclick() { mode.edge() } }), + ]), h.div([ + h.button({ _: 'sketch', id: "mode-sketch", onclick() { mode.sketch() } }), ]) ]); // create hotkey/action menu (top/left) @@ -380,7 +382,7 @@ function ui_build() { h.button({ _: 'export', onclick: file.export }), ]) ]), - h.div([ + h.div({ class: "sketch-off" }, [ h.div({ _: "add", class: "head" }), h.div({ class: "back"}), h.div({ class: "pop"}, [ @@ -392,6 +394,15 @@ function ui_build() { devel ? h.button({ _: 'input', onclick: add.input }) : undefined ]) ]), + h.div({ class: "sketch-on" }, [ + h.div({ _: "add", class: "head" }), + h.div({ class: "back"}), + h.div({ class: "pop"}, [ + h.button({ _: 'circle', onclick() { add.cylinder() } }), + h.button({ _: 'square', onclick() { add.cube() } }), + h.button({ _: 'gear', onclick() { add.gear() } }), + ]) + ]), h.div([ h.div({ _: "view", class: "head" }), h.div({ class: "back"}), @@ -420,7 +431,7 @@ function ui_build() { h.button({ _: 'grid', onclick() { api.pattern.grid() } }), ]) ]), - h.div([ + h.div({ class: "sketch-off" }, [ h.div({ _: "models", class: "head" }), h.div({ class: "back"}), h.div({ class: "pop"}, [ @@ -434,7 +445,7 @@ function ui_build() { h.button({ _: 'delete', onclick: api.selection.delete }), ]) ]), - h.div([ + h.div({ class: "sketch-off" }, [ h.div({ _: "faces", class: "head" }), h.div({ class: "back"}), h.div({ class: "pop"}, [ @@ -443,7 +454,7 @@ function ui_build() { h.button({ _: 'delete', onclick: api.selection.delete }), ]) ]), - h.div([ + h.div({ class: "sketch-off" }, [ h.div({ _: "repair", class: "head" }), h.div({ class: "back"}), h.div({ class: "pop"}, [ diff --git a/src/moto/webui.js b/src/moto/webui.js index 5d943696..0217e5e1 100644 --- a/src/moto/webui.js +++ b/src/moto/webui.js @@ -129,6 +129,15 @@ gapp.overlay(root, { if (del) $(id).classList.remove(del); }, + $C: (clazz, add, del) => { + let el = [...document.getElementsByClassName(clazz)]; + for (let e of el) { + if (add) e.classList.add(add); + if (del) e.classList.remove(del); + } + return el; + }, + h, estop: (evt) => {