add primitives menu

This commit is contained in:
Stewart Allen 2022-04-19 16:51:55 -04:00
commit 1d7d0064c0
5 changed files with 69 additions and 23 deletions

View file

@ -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` added batch processing to object adds/removes to speedup complex workspace restore
* `C` substitute some prusa slicer [variables] with KM {variables} on import * `C` substitute some prusa slicer [variables] with KM {variables} on import
* `C` fix CAM output order for tool changes an spindle speed updates * `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 * `-` refactor cnc to use new core slicer engine
* `-` improve vertex replacement and widget update matrix tracking * `-` 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` auto-fog in wireframe view to aid close mesh inspections
* `C` significant speed-up for large surface selections * `C` significant speed-up for large surface selections

View file

@ -288,39 +288,33 @@ function space_init(data) {
case 'KeyX': case 'KeyX':
return api.file.export(); return api.file.export();
case 'KeyD': case 'KeyD':
if (shiftKey) return api.tool.duplicate(); return shiftKey && api.tool.duplicate();
break;
case 'KeyC': case 'KeyC':
return selection.centerXY().focus(); return selection.centerXY().focus();
case 'KeyF': case 'KeyF':
return selection.floor().focus(); return selection.floor().focus();
case 'KeyM': case 'KeyM':
if (shiftKey) return api.tool.merge(); return shiftKey ? api.tool.merge() : api.tool.mirror();
return api.tool.mirror();
case 'KeyU': case 'KeyU':
return shiftKey && api.tool.union(); return shiftKey && api.tool.union();
case 'KeyA': case 'KeyA':
return shiftKey ? api.tool.analyze() : undefined; return shiftKey && api.tool.analyze();
case 'KeyR': case 'KeyR':
if (shiftKey) return api.tool.rebuild(); return shiftKey ? api.tool.rebuild() : api.tool.repair();
return api.tool.repair();
case 'KeyE': case 'KeyE':
return api.tool.clean(); return api.tool.clean();
case 'KeyV': case 'KeyV':
return selection.focus(); return selection.focus();
case 'KeyN': case 'KeyN':
if (shiftKey) return estop(evt, api.tool.rename()); return shiftKey ? estop(evt, api.tool.rename()) : api.normals();
return api.normals();
case 'KeyW': case 'KeyW':
return api.wireframe(); return api.wireframe();
case 'KeyG': case 'KeyG':
if (shiftKey) return api.tool.regroup(); return shiftKey ? api.tool.regroup() : api.grid();
return api.grid();
case 'KeyL': case 'KeyL':
return api.log.toggle({ spinner: false }); return api.log.toggle({ spinner: false });
case 'KeyS': case 'KeyS':
if (shiftKey) return selection.visible({toggle:true}); return shiftKey ? selection.visible({toggle:true}) : call.edit_split();
return call.edit_split();
case 'KeyB': case 'KeyB':
return selection.boundsBox({toggle:true}); return selection.boundsBox({toggle:true});
case 'KeyH': case 'KeyH':

View file

@ -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 = { let file = {
import() { import() {
// binding created in mesh.build // binding created in mesh.build
@ -696,6 +735,8 @@ const api = exports({
model, model,
add,
file, file,
tool, tool,

View file

@ -335,7 +335,7 @@ function ui_build() {
h.bind(logger, [ h.div({ id: 'logtext' }) ]); h.bind(logger, [ h.div({ id: 'logtext' }) ]);
// a few shortcuts to api calls // 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 // top/center mode selector
h.bind(modes, [ h.bind(modes, [
@ -351,7 +351,6 @@ function ui_build() {
h.div([ h.div([
// create and bind file loading elements // create and bind file loading elements
h.div({ _: "file", class: "head" }), h.div({ _: "file", class: "head" }),
// h.div({ class: "vsep" }),
h.button({ _: 'import', onclick: file.import }, [ h.button({ _: 'import', onclick: file.import }, [
h.input({ h.input({
id: "import", type: "file", class: ["hide"], multiple: true, id: "import", type: "file", class: ["hide"], multiple: true,
@ -362,7 +361,6 @@ function ui_build() {
]), ]),
h.div([ h.div([
h.div({ _: "view", class: "head" }), h.div({ _: "view", class: "head" }),
// h.div({ class: "vsep" }),
h.button({ _: 'visible', onclick() { selection.visible({ toggle: true }) } }), h.button({ _: 'visible', onclick() { selection.visible({ toggle: true }) } }),
h.button({ _: 'bounds', onclick() { selection.boundsBox({ toggle: true }) } }), h.button({ _: 'bounds', onclick() { selection.boundsBox({ toggle: true }) } }),
h.button({ _: 'gridlines', onclick() { api.grid() } }), h.button({ _: 'gridlines', onclick() { api.grid() } }),
@ -370,8 +368,7 @@ function ui_build() {
h.button({ _: 'wireframe', onclick() { api.wireframe() } }), h.button({ _: 'wireframe', onclick() { api.wireframe() } }),
]), ]),
h.div([ h.div([
h.div({ _: "models", class: "head" }), h.div({ _: "model", class: "head" }),
// h.div({ class: "vsep" }),
h.button({ _: 'duplicate', onclick: tool.duplicate }), h.button({ _: 'duplicate', onclick: tool.duplicate }),
h.button({ _: 'regroup', onclick: tool.regroup }), h.button({ _: 'regroup', onclick: tool.regroup }),
h.button({ _: 'merge', onclick: tool.merge }), h.button({ _: 'merge', onclick: tool.merge }),
@ -383,9 +380,13 @@ function ui_build() {
h.div({ _: "normal", class: "head" }), h.div({ _: "normal", class: "head" }),
h.button({ _: 'invert', onclick: tool.invert }), 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([
h.div({ _: "repair", class: "head" }), h.div({ _: "repair", class: "head" }),
// h.div({ class: "vsep" }),
h.button({ _: 'analyze', onclick: tool.analyze }), h.button({ _: 'analyze', onclick: tool.analyze }),
h.button({ _: 'isolate', onclick: tool.isolate }), h.button({ _: 'isolate', onclick: tool.isolate }),
h.button({ _: 'patch', onclick: tool.repair }), h.button({ _: 'patch', onclick: tool.repair }),

View file

@ -199,6 +199,8 @@ button:hover {
color: white; color: white;
} }
/** specific modal dialogs */
.export { .export {
flex-direction: column; flex-direction: column;
font-family: monospace; font-family: monospace;
@ -219,7 +221,15 @@ button:hover {
padding: 4px; padding: 4px;
} }
/** modal dialogs **/ .cylinder {
gap: 4px;
}
.cylinder input {
text-align: center;
}
/** generic modal dialogs **/
#modal_page { #modal_page {
background-color: rgba(0,0,0,0.25); background-color: rgba(0,0,0,0.25);
@ -262,7 +272,7 @@ button:hover {
#modal_title_close { #modal_title_close {
position: absolute; position: absolute;
color: #555; color: #555;
right: 2px; right: 3px;
top: 2px; top: 2px;
} }