add mesh script tool

This commit is contained in:
Stewart Allen 2025-10-24 23:56:06 -04:00
commit 6d202aafaa
5 changed files with 93 additions and 6 deletions

View file

@ -224,7 +224,11 @@ function space_init(data) {
if (evt.key === '?') {
return api.welcome(version);
}
let { shiftKey, metaKey, ctrlKey, code } = evt;
let { shiftKey, metaKey, ctrlKey, code, target } = evt;
if (target.nodeName === 'TEXTAREA') {
api.script.changed();
return;
}
switch (code) {
case 'Digit1':
return api.mode.sketch();
@ -286,7 +290,26 @@ function space_init(data) {
}
},
'keydown', evt => {
let { shiftKey, metaKey, ctrlKey, code } = evt;
let { shiftKey, metaKey, ctrlKey, code, target } = evt;
if (target.nodeName === 'TEXTAREA') {
if (code === 'Tab') {
estop(evt);
const start = target.selectionStart;
const end = target.selectionEnd;
const val = target.value;
const upto = val.slice(0, start);
const col = start - upto.lastIndexOf('\n') - 1;
const tab = ' '.substring(col % 4);
target.value = val.slice(0, start) + tab + val.slice(end);
target.selectionStart = target.selectionEnd = start + tab.length;
}
if (code === 'Enter' && metaKey) {
api.script.execute();
} else {
api.script.changed();
}
return;
}
let once = keyOnce[code];
if (once) {
delete keyOnce[code];

View file

@ -11,6 +11,7 @@ import { edges as meshEdges } from './edges.js';
import { group as meshGroup } from './group.js';
import { model as meshModel } from './model.js';
import { sketch as meshSketch } from './sketch.js';
import { script } from './script.js';
import { newPolygon } from '../geo/polygon.js';
import { THREE } from '../ext/three.js';
import { $, $C, h } from '../moto/webui.js';
@ -771,11 +772,12 @@ let add = {
},
cube() {
const [ x,y,z ] = [ ...arguments ];
const box = new THREE.BoxGeometry(1,1,1).toNonIndexed();
const vert = box.attributes.position.array;
const nmdl = new meshModel({ file: "box", mesh: vert });
const ngrp = api.group.new([ nmdl ]);
ngrp.scale(10, 10, 10).floor();
ngrp.scale(x ?? 10, y ?? 10, z ?? 10).floor();
selection.set([ nmdl ]);
return ngrp;
},
@ -1515,8 +1517,8 @@ const api = {
},
clear() {
for (let group of group.list()) {
group.remove(group);
for (let grp of group.list()) {
group.remove(grp);
}
},
@ -1645,6 +1647,8 @@ const api = {
prefs,
script,
selection,
sketch,

View file

@ -383,7 +383,7 @@ function menu_item(text, fn, short, id) {
// create html elements
function ui_build() {
let { bind, div, input, hr, label } = h;
let { bind, div, input, hr, label, textarea } = h;
let { file, selection, mode, tool, sketch, prefs, add } = api;
let trash = FontAwesome.icon({ prefix: "fas", iconName: "trash" }).html[0];
let eye_open = FontAwesome.icon({ prefix: "fas", iconName: "eye" }).html[0];
@ -402,6 +402,7 @@ function ui_build() {
menu_item('Export', file.export, 'X'),
hr(),
menu_item('Slicer', api.kirimoto),
menu_item('Script', api.script.toggle),
hr(),
menu_item('Close', window.close),
])
@ -579,6 +580,10 @@ function ui_build() {
div({ id: 'objecttools', class: "tools sketch-off" }),
div({ id: 'logger', onmouseover() { log.show() } }),
]),
div({ id: 'script', class: "hide" }, [
div({ id: 'script-header', _: "script" }),
textarea({ id: 'script-editor', rows: 20, cols: 60 }),
]),
div({ id: 'grouplist' }),
div({ id: 'selectlist' }),
div({ id: 'download', class: "hide" })

31
src/mesh/script.js Normal file
View file

@ -0,0 +1,31 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
import { api } from '../mesh/api.js';
import { $, h, estop } from '../moto/webui.js';
export const script = {
visible: false,
changed() {
localStorage.script = $('script-editor').value;
},
hide() {
$('script').classList.add('hide');
script.visible = false;
},
show() {
$('script').classList.remove('hide');
$('script-editor').value = localStorage.script ?? '';
script.visible = true;
},
toggle() {
if (script.visible) {
script.hide();
} else {
script.show();
}
},
execute() {
let cmd = localStorage.script || `console.log('no script')`;
if (cmd) eval(`{ ${cmd} }`);
}
};

View file

@ -629,6 +629,30 @@ button:hover {
display: grid;
}
#script {
margin-left: 5px;
flex-direction: column;
justify-content: end;
color: white;
}
#script-header {
padding: 3px 5px 3px 5px;
background-color: #333;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border-top: 1px solid #999;
border-left: 1px solid #999;
border-right: 1px solid #999;
flex-direction: row;
}
#script-editor {
color: white;
background-color: #222;
outline: none;
}
/** group/model buttons top/right of workspace **/
#grouplist {