From 1d7d0064c0f4ab47c7cdea86e51a2e8b5cd0affd Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Tue, 19 Apr 2022 16:51:55 -0400 Subject: [PATCH] add primitives menu --- release.md | 4 ++-- src/main/mesh.js | 20 +++++++------------- src/mesh/api.js | 41 +++++++++++++++++++++++++++++++++++++++++ src/mesh/build.js | 13 +++++++------ web/mesh/index.css | 14 ++++++++++++-- 5 files changed, 69 insertions(+), 23 deletions(-) diff --git a/release.md b/release.md index be63477f..485bf6a5 100644 --- a/release.md +++ b/release.md @@ -11,11 +11,11 @@ Full docs @ https://docs.grid.space/projects/kiri-moto * `C` added batch processing to object adds/removes to speedup complex workspace restore * `C` substitute some prusa slicer [variables] with KM {variables} on import * `C` fix CAM output order for tool changes an spindle speed updates -* `I` add CAM pocket operation using surface selection +* `C` add CAM pocket operation using surface selection * `-` refactor cnc to use new core slicer engine * `-` improve vertex replacement and widget update matrix tracking -## Mesh:Tool +## Mesh:Tool (1.2.0) * `C` auto-fog in wireframe view to aid close mesh inspections * `C` significant speed-up for large surface selections diff --git a/src/main/mesh.js b/src/main/mesh.js index 548f6090..145a961f 100644 --- a/src/main/mesh.js +++ b/src/main/mesh.js @@ -288,39 +288,33 @@ function space_init(data) { case 'KeyX': return api.file.export(); case 'KeyD': - if (shiftKey) return api.tool.duplicate(); - break; + return shiftKey && api.tool.duplicate(); case 'KeyC': return selection.centerXY().focus(); case 'KeyF': return selection.floor().focus(); case 'KeyM': - if (shiftKey) return api.tool.merge(); - return api.tool.mirror(); + return shiftKey ? api.tool.merge() : api.tool.mirror(); case 'KeyU': return shiftKey && api.tool.union(); case 'KeyA': - return shiftKey ? api.tool.analyze() : undefined; + return shiftKey && api.tool.analyze(); case 'KeyR': - if (shiftKey) return api.tool.rebuild(); - return api.tool.repair(); + return shiftKey ? api.tool.rebuild() : api.tool.repair(); case 'KeyE': return api.tool.clean(); case 'KeyV': return selection.focus(); case 'KeyN': - if (shiftKey) return estop(evt, api.tool.rename()); - return api.normals(); + return shiftKey ? estop(evt, api.tool.rename()) : api.normals(); case 'KeyW': return api.wireframe(); case 'KeyG': - if (shiftKey) return api.tool.regroup(); - return api.grid(); + return shiftKey ? api.tool.regroup() : api.grid(); case 'KeyL': return api.log.toggle({ spinner: false }); case 'KeyS': - if (shiftKey) return selection.visible({toggle:true}); - return call.edit_split(); + return shiftKey ? selection.visible({toggle:true}) : call.edit_split(); case 'KeyB': return selection.boundsBox({toggle:true}); case 'KeyH': diff --git a/src/mesh/api.js b/src/mesh/api.js index 16dbbb1e..b5a9e3b3 100644 --- a/src/mesh/api.js +++ b/src/mesh/api.js @@ -233,6 +233,45 @@ let model = { } }; +let add = { + cube() { + const box = new THREE.BoxGeometry(1,1,1).toNonIndexed(); + const vert = box.attributes.position.array; + const nmdl = new mesh.model({ file: "box", mesh: vert }); + const ngrp = group.new([ nmdl ]); + ngrp.scale(5, 5, 5).floor(); + }, + + cylinder(opt = { facets: 30 }) { + function gencyl(facets) { + api.modal.hide(); + facets = parseInt(facets); + if (facets > 3) { + api.log.emit(`add cylinder with ${facets} facets`); + const cyl = new THREE.CylinderGeometry(5,5,1,facets).toNonIndexed(); + const vert = cyl.attributes.position.array; + const nmdl = new mesh.model({ file: "cylinder", mesh: vert }); + const ngrp = group.new([ nmdl ]); + ngrp.floor(); + } + } + if (opt.facets > 2) { + gencyl(opt.facets); + } else { + api.modal.dialog({ + title: "cylinder", + body: [ h.div({ class: "cylinder" }, [ + h.label('facets'), + h.input({ value: opt.facets || 30, size: 5, id: "gencyl" }), + h.button({ _: "create", onclick() { + gencyl(api.modal.bound.gencyl.value) + } }) + ]) ] + }); + } + } +}; + let file = { import() { // binding created in mesh.build @@ -696,6 +735,8 @@ const api = exports({ model, + add, + file, tool, diff --git a/src/mesh/build.js b/src/mesh/build.js index 7639a18b..2de2c6e8 100644 --- a/src/mesh/build.js +++ b/src/mesh/build.js @@ -335,7 +335,7 @@ function ui_build() { h.bind(logger, [ h.div({ id: 'logtext' }) ]); // a few shortcuts to api calls - let { file, selection, mode, tool, prefs } = api; + let { file, selection, mode, tool, prefs, add } = api; // top/center mode selector h.bind(modes, [ @@ -351,7 +351,6 @@ function ui_build() { h.div([ // create and bind file loading elements h.div({ _: "file", class: "head" }), - // h.div({ class: "vsep" }), h.button({ _: 'import', onclick: file.import }, [ h.input({ id: "import", type: "file", class: ["hide"], multiple: true, @@ -362,7 +361,6 @@ function ui_build() { ]), h.div([ h.div({ _: "view", class: "head" }), - // h.div({ class: "vsep" }), h.button({ _: 'visible', onclick() { selection.visible({ toggle: true }) } }), h.button({ _: 'bounds', onclick() { selection.boundsBox({ toggle: true }) } }), h.button({ _: 'gridlines', onclick() { api.grid() } }), @@ -370,8 +368,7 @@ function ui_build() { h.button({ _: 'wireframe', onclick() { api.wireframe() } }), ]), h.div([ - h.div({ _: "models", class: "head" }), - // h.div({ class: "vsep" }), + h.div({ _: "model", class: "head" }), h.button({ _: 'duplicate', onclick: tool.duplicate }), h.button({ _: 'regroup', onclick: tool.regroup }), h.button({ _: 'merge', onclick: tool.merge }), @@ -383,9 +380,13 @@ function ui_build() { h.div({ _: "normal", class: "head" }), h.button({ _: 'invert', onclick: tool.invert }), ]), + h.div([ + h.div({ _: "add", class: "head" }), + h.button({ _: 'cylinder', onclick: add.cylinder }), + h.button({ _: 'cube', onclick: add.cube }), + ]), h.div([ h.div({ _: "repair", class: "head" }), - // h.div({ class: "vsep" }), h.button({ _: 'analyze', onclick: tool.analyze }), h.button({ _: 'isolate', onclick: tool.isolate }), h.button({ _: 'patch', onclick: tool.repair }), diff --git a/web/mesh/index.css b/web/mesh/index.css index c121e539..aad30edb 100644 --- a/web/mesh/index.css +++ b/web/mesh/index.css @@ -199,6 +199,8 @@ button:hover { color: white; } +/** specific modal dialogs */ + .export { flex-direction: column; font-family: monospace; @@ -219,7 +221,15 @@ button:hover { padding: 4px; } -/** modal dialogs **/ +.cylinder { + gap: 4px; +} + +.cylinder input { + text-align: center; +} + +/** generic modal dialogs **/ #modal_page { background-color: rgba(0,0,0,0.25); @@ -262,7 +272,7 @@ button:hover { #modal_title_close { position: absolute; color: #555; - right: 2px; + right: 3px; top: 2px; }