fix construction of indexed animation tools, rotation sign in topo4, rotation animation

This commit is contained in:
Stewart Allen 2025-02-16 15:38:01 -05:00
commit 718876980b
6 changed files with 81 additions and 57 deletions

View file

@ -40,6 +40,7 @@ kiri.load(() => {
$('layer-animate').innerHTML = ''; $('layer-animate').innerHTML = '';
$('layer-toolpos').innerHTML = ''; $('layer-toolpos').innerHTML = '';
Object.keys(meshes).forEach(id => deleteMesh(id)); Object.keys(meshes).forEach(id => deleteMesh(id));
api.widgets.setAxisIndex(0);
} }
function animate2(api, delay) { function animate2(api, delay) {
@ -194,6 +195,9 @@ kiri.load(() => {
space.refresh(); space.refresh();
} }
} }
if (data.stock_index !== undefined) {
api.widgets.setAxisIndex(data.stock_index);
}
if (data.mesh_index) { if (data.mesh_index) {
const { id, index } = data.mesh_index; const { id, index } = data.mesh_index;
const mesh = meshes[id]; const mesh = meshes[id];
@ -550,6 +554,7 @@ kiri.load(() => {
send.data(toolUpdateMsg); send.data(toolUpdateMsg);
} }
if (stockIndexMsg) { if (stockIndexMsg) {
send.data({ stock_index: stockIndex });
for (let slice of stockSlices) { for (let slice of stockSlices) {
send.data({ mesh_index: { id: slice.id, index: -stockIndex } }); send.data({ mesh_index: { id: slice.id, index: -stockIndex } });
} }
@ -592,8 +597,8 @@ kiri.load(() => {
let { cylinder, sphere } = Instance.Manifold; let { cylinder, sphere } = Instance.Manifold;
let mesh; let mesh;
if (tool.isBallMill()) { if (tool.isBallMill()) {
mesh = cylinder(flen + slen - frad, frad, frad, 20, true) mesh = cylinder(flen + slen - frad * 2, frad, frad, 20, true)
.add(sphere(frad, 20).translate(0, 0, -(flen + slen - frad)/2)); .add(sphere(frad, 20).translate(0, 0, -(flen + slen - frad * 2)/2));
} else if (tool.isTaperMill()) { } else if (tool.isTaperMill()) {
const trad = Math.max(tool.tipDiameter() / 2, 0.001); const trad = Math.max(tool.tipDiameter() / 2, 0.001);
mesh = cylinder(slen, srad, srad, 20, true).translate(0, 0, slen/2) mesh = cylinder(slen, srad, srad, 20, true).translate(0, 0, slen/2)

View file

@ -30,7 +30,8 @@ let isAnimate,
flipping, flipping,
poppedRec, poppedRec,
hoveredOp, hoveredOp,
API, FDM, SPACE, STACKS, MODES, VIEWS, UI, UC, LANG, MCAM; lastMode,
API, FDM, SPACE, STACKS, MODES, VIEWS, UI, UC, LANG, MCAM, WIDGETS;
let zaxis = { x: 0, y: 0, z: 1 }, let zaxis = { x: 0, y: 0, z: 1 },
popOp = {}, popOp = {},
@ -57,6 +58,7 @@ CAM.init = function(kiri, api) {
FDM = kiri.driver.FDM; FDM = kiri.driver.FDM;
// console.log({kiri,api}) // console.log({kiri,api})
WIDGETS = api.widgets;
SPACE = kiri.space; SPACE = kiri.space;
MODES = kiri.consts.MODES; MODES = kiri.consts.MODES;
VIEWS = kiri.consts.VIEWS; VIEWS = kiri.consts.VIEWS;
@ -73,9 +75,7 @@ CAM.init = function(kiri, api) {
let changed = refresh || isIndexed !== newIndexed; let changed = refresh || isIndexed !== newIndexed;
isIndexed = newIndexed; isIndexed = newIndexed;
if (!isIndexed || !isCamMode) { if (!isIndexed || !isCamMode) {
for (let widget of API.widgets.all()) { WIDGETS.setAxisIndex(0);
widget.setAxisIndex(0);
}
} }
if (!isCamMode) { if (!isCamMode) {
return; return;
@ -95,9 +95,7 @@ CAM.init = function(kiri, api) {
if (!changed) { if (!changed) {
return; return;
} }
for (let widget of api.widgets.all()) { WIDGETS.setIndexed(isIndexed ? true : false);
widget.setIndexed(isIndexed ? true : false);
}
api.platform.update_bounds(); api.platform.update_bounds();
// add or remove clock op depending on indexing // add or remove clock op depending on indexing
const cp = current.process; const cp = current.process;
@ -189,15 +187,14 @@ CAM.init = function(kiri, api) {
}); });
api.event.on("view.set", (mode) => { api.event.on("view.set", (mode) => {
lastMode = mode;
isArrange = (mode === VIEWS.ARRANGE); isArrange = (mode === VIEWS.ARRANGE);
isPreview = (mode === VIEWS.PREVIEW); isPreview = (mode === VIEWS.PREVIEW);
isAnimate = false; isAnimate = (mode === VIEWS.ANIMATE);
animFn().animate_clear(api); animFn().animate_clear(api);
func.clearPops(); func.clearPops();
if (isCamMode && isPreview) { if (isCamMode && isPreview) {
for (let widget of API.widgets.all()) { WIDGETS.setAxisIndex(0);
widget.setAxisIndex(0);
}
} }
updateStock(); updateStock();
func.opRender(); func.opRender();
@ -466,7 +463,7 @@ CAM.init = function(kiri, api) {
function updateIndex() { function updateIndex() {
let oplist = current.process.ops; let oplist = current.process.ops;
if (!(isCamMode && oplist)) { if (!(isCamMode && oplist) || lastMode === VIEWS.ANIMATE) {
return; return;
} }
let index = 0; let index = 0;
@ -484,9 +481,7 @@ CAM.init = function(kiri, api) {
} }
} }
} }
for (let widget of API.widgets.all()) { WIDGETS.setAxisIndex(isPreview || !isIndexed ? 0 : -index);
widget.setAxisIndex(isPreview || !isIndexed ? 0 : -index);
}
currentIndex = isIndexed && !isPreview ? index * DEG2RAD : 0; currentIndex = isIndexed && !isPreview ? index * DEG2RAD : 0;
} }
@ -728,9 +723,9 @@ CAM.init = function(kiri, api) {
el.onmouseleave = onLeave; el.onmouseleave = onLeave;
} }
} }
// update widget rotations from timeline marker if (lastMode !== VIEWS.ANIMATE) {
for (let widget of API.widgets.all()) { // update widget rotations from timeline marker
widget.setAxisIndex(isPreview || !isIndexed ? 0 : -index); WIDGETS.setAxisIndex(isPreview || !isIndexed ? 0 : -index);
} }
currentIndex = isIndexed && !isPreview ? index * DEG2RAD : 0; currentIndex = isIndexed && !isPreview ? index * DEG2RAD : 0;
updateStock(); updateStock();

View file

@ -517,7 +517,7 @@ class OpOutline extends CamOp {
let cnt = 0; let cnt = 0;
let tot = 0; let tot = 0;
if (op.outside && !op.inside) { if (op.outside && !op.inside) {
console.log({outline_bypass: indices, down: op.down}); // console.log({outline_bypass: indices, down: op.down});
indices.forEach((ind,i) => { indices.forEach((ind,i) => {
if (flats.indexOf(ind) >= 0) { if (flats.indexOf(ind) >= 0) {
// exclude flats // exclude flats

View file

@ -87,37 +87,44 @@ gapp.register("kiri-mode.cam.tools", (root, exports) => {
ui.toolTaperTip.disabled = taper ? undefined : 'true'; ui.toolTaperTip.disabled = taper ? undefined : 'true';
$('tool-view').innerHTML = '<svg id="tool-svg" width="100%" height="100%"></svg>'; $('tool-view').innerHTML = '<svg id="tool-svg" width="100%" height="100%"></svg>';
setTimeout(() => { setTimeout(() => {
let svg = $('tool-svg'); let svg = $('tool-svg'),
let pad = 10; pad = 10,
let dim = { w: svg.clientWidth, h: svg.clientHeight } dim = { w: svg.clientWidth, h: svg.clientHeight },
let max = { w: dim.w - pad * 2, h: dim.h - pad * 2}; max = { w: dim.w - pad * 2, h: dim.h - pad * 2},
let off = { x: pad, y: pad }; off = { x: pad, y: pad },
let shaft_fill = "#cccccc"; isBall = type === "ballmill",
let flute_fill = "#dddddd"; shaft_fill = "#cccccc",
let stroke = "#777777"; flute_fill = "#dddddd",
let stroke_width = 3; stroke = "#777777",
let stroke_thin = stroke_width / 2; stroke_width = 3,
let shaft = tool.shaft_len || 1; stroke_thin = stroke_width / 2,
let flute = tool.flute_len || 1; shaft = tool.shaft_len || 1,
let tip_len = type === "ballmill" ? tool.flute_diam / 2 : 0; flute = tool.flute_len || 1,
let total_len = shaft + flute + tip_len; total_len = shaft + flute,
let units = dim.h / total_len; units = dim.h / total_len,
let shaft_len = (shaft / total_len) * max.h; shaft_len = (shaft / total_len) * max.h,
let flute_len = (flute / total_len) * max.h; flute_len = ((flute / total_len) * max.h),
let total_wid = Math.max(tool.flute_diam, tool.shaft_diam); shaft_diam = tool.shaft_diam * units,
let shaft_off = (max.w - tool.shaft_diam * units) / 2; flute_diam = tool.flute_diam * units,
let flute_off = (max.w - tool.flute_diam * units) / 2; // total_wid = Math.max(flute_diam, shaft_diam),
let taper_off = (max.w - (tool.taper_tip || 0) * units) / 2; shaft_off = (max.w - shaft_diam) / 2,
let parts = [ flute_off = (max.w - flute_diam) / 2,
{ rect: { taper_off = (max.w - (tool.taper_tip || 0) * units) / 2,
x:off.x + shaft_off, y:off.y, parts = [
width:max.w - shaft_off * 2, height:shaft_len, // shaft rectangle
stroke, fill: shaft_fill, stroke_width { rect: {
} } x: off.x + shaft_off,
]; y: off.y,
width: max.w - shaft_off * 2,
height: shaft_len,
fill: shaft_fill,
stroke_width,
stroke
} }
];
if (type === "tapermill") { if (type === "tapermill") {
let yoff = off.y + shaft_len; let yoff = off.y + shaft_len;
let mid = dim.w / 2; // let mid = dim.w / 2;
parts.push({path: {stroke_width, stroke, fill:flute_fill, d:[ parts.push({path: {stroke_width, stroke, fill:flute_fill, d:[
`M ${off.x + flute_off} ${yoff}`, `M ${off.x + flute_off} ${yoff}`,
`L ${off.x + taper_off} ${yoff + flute_len}`, `L ${off.x + taper_off} ${yoff + flute_len}`,
@ -126,15 +133,22 @@ gapp.register("kiri-mode.cam.tools", (root, exports) => {
`z` `z`
].join('\n')}}); ].join('\n')}});
} else { } else {
let fl = isBall ? flute_len - flute_diam/2 : flute_len;
let x1 = off.x + flute_off; let x1 = off.x + flute_off;
let y1 = off.y + shaft_len; let y1 = off.y + shaft_len;
let x2 = x1 + max.w - flute_off * 2; let x2 = x1 + max.w - flute_off * 2;
let y2 = y1 + flute_len; let y2 = y1 + fl;
// flute rectangle
parts.push({ rect: { parts.push({ rect: {
x:off.x + flute_off, y:off.y + shaft_len, x: off.x + flute_off,
width:max.w - flute_off * 2, height:flute_len, y: off.y + shaft_len,
stroke, fill: flute_fill, stroke_width width: max.w - flute_off * 2,
height: fl,
fill: flute_fill,
stroke_width,
stroke,
} }); } });
// hatch "fill" flute
parts.push({ line: { x1, y1, x2, y2, stroke, stroke_width: stroke_thin } }); parts.push({ line: { x1, y1, x2, y2, stroke, stroke_width: stroke_thin } });
parts.push({ line: { parts.push({ line: {
x1: (x1 + x2) / 2, y1, x2, y2: (y1 + y2) / 2, x1: (x1 + x2) / 2, y1, x2, y2: (y1 + y2) / 2,
@ -145,10 +159,10 @@ gapp.register("kiri-mode.cam.tools", (root, exports) => {
stroke, stroke_width: stroke_thin stroke, stroke_width: stroke_thin
} }); } });
} }
if (type === "ballmill") { if (isBall) {
let rad = (max.w - flute_off * 2) / 2; let rad = (max.w - flute_off * 2) / 2;
let xend = dim.w - off.x - flute_off; let xend = dim.w - off.x - flute_off;
let yoff = off.y + shaft_len + flute_len + stroke_width/2; let yoff = off.y + shaft_len + flute_len + stroke_width/2 - flute_diam/2;
parts.push({path: {stroke_width, stroke, fill:flute_fill, d:[ parts.push({path: {stroke_width, stroke, fill:flute_fill, d:[
`M ${off.x + flute_off} ${yoff}`, `M ${off.x + flute_off} ${yoff}`,
`A ${rad} ${rad} 0 0 0 ${xend} ${yoff}`, `A ${rad} ${rad} 0 0 0 ${xend} ${yoff}`,

View file

@ -517,7 +517,7 @@ moto.broker.subscribe("minion.started", msg => {
const { slices, tool } = cache.lathe; const { slices, tool } = cache.lathe;
const axis = new THREE.Vector3(1, 0, 0); const axis = new THREE.Vector3(1, 0, 0);
const mrot = new THREE.Matrix4().makeRotationAxis(axis, angle); const mrot = new THREE.Matrix4().makeRotationAxis(axis, -angle);
const stmp = slices.map(s => { const stmp = slices.map(s => {
const lines = s.lines.slice(); const lines = s.lines.slice();
rotatePoints(lines, mrot); rotatePoints(lines, mrot);

View file

@ -92,6 +92,14 @@ function opacity(value) {
moto.space.update(); moto.space.update();
} }
function setIndexed(value) {
api.widgets.each(w => w.setIndexed(value));
}
function setAxisIndex(value) {
api.widgets.each(w => w.setAxisIndex(value));
}
// extend API (api.widgets) // extend API (api.widgets)
const widgets = Object.assign(api.widgets, { const widgets = Object.assign(api.widgets, {
load: Widget.loadFromCatalog, load: Widget.loadFromCatalog,
@ -102,6 +110,8 @@ const widgets = Object.assign(api.widgets, {
replace, replace,
opacity, opacity,
annotate, annotate,
setIndexed,
setAxisIndex,
all() { return WIDGETS.slice() }, all() { return WIDGETS.slice() },
add(w) { return WIDGETS.push(w) }, add(w) { return WIDGETS.push(w) },
remove(w) { return WIDGETS.remove(w) }, remove(w) { return WIDGETS.remove(w) },