animation fast fordward without render. preserve tabs and object meta-data on duplication

This commit is contained in:
Stewart Allen 2020-12-08 16:04:01 -05:00
commit af1ab0e572
9 changed files with 80 additions and 21 deletions

View file

@ -19,7 +19,6 @@
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
* `B` normals possibly inverted on faces in 2D to 3D conversion
* `F` right click / context menu (object deletion, etc)
* `F` detect and report slow framerates
* `P` duplicate objects should share same slice data unless rotated or scaled
* `P` optimize object import to vertices + indexes to save memory
@ -66,7 +65,7 @@
* `B` outside cutting direction in roughing mode inverted
* `B` top clearing operations should use linear, not offset, passes
* `B` on rotation, tabs dissociate from parts whose center changes with rotation
* `F` duplicating a part should duplicate added features like tabs
* `F` option to use part / STL coordinate space to determine X,Y origin
* `F` validate muti-part layout and spacing exceeds largest outside tool diameter
* `F` skip "thru" holes checkbox for roughing and outlining
* `F` polygon simplification option in tracing (for image derived maps)
@ -89,10 +88,8 @@
* `F` add support for tapered ball mills
* `F` warn when part > stock or cuts go outside bed
* `F` animation should clear the mesh in areas where the cuts go through the stock?
* `F` show render progress bar or %
* `P` detect render message backlog and pause or warn
* `P` redo all path route / planning in prepare to account for terrain before camOut
* `P` fast forward animation with "chunking" or "skip animation"
# Laser

View file

@ -1,6 +1,6 @@
{
"name": "grid-apps",
"version": "2.5.0D",
"version": "2.5.1D",
"description": "grid.space 3d slice & modeling tools",
"author": "Stewart Allen <sa@grid.space>",
"license": "MIT",

View file

@ -6,7 +6,7 @@
if (!self.kiri) {
self.kiri = {
beta: 2500,
beta: 2501,
driver: {}, // driver modules
loader: [] // module loading: array of functions
};

View file

@ -424,13 +424,25 @@
sel = API.selection.meshes();
platform.deselect();
for (i=0; i<sel.length; i++) {
m = sel[i].clone();
m.geometry = m.geometry.clone();
m.material = m.material.clone();
bb = m.getBoundingBox();
let nw = API.widgets.new().loadGeometry(m.geometry);
let mesh = sel[i].clone();
mesh.geometry = mesh.geometry.clone();
mesh.material = mesh.material.clone();
bb = mesh.getBoundingBox();
let ow = sel[i].widget;
let nw = API.widgets.new().loadGeometry(mesh.geometry);
nw.meta.file = ow.meta.file;
nw.meta.vertices = ow.meta.vertices;
nw.move(bb.max.x - bb.min.x + 1, 0, 0);
platform.add(nw,true);
let owa = API.widgets.annotate(ow.id);
let nwa = API.widgets.annotate(nw.id);
if (owa.tab) {
nwa.tab = Object.clone(owa.tab);
nwa.tab.forEach((tab,i) => {
tab.id = Date.now() + i
});
}
KIRI.driver.CAM.restoreTabs([nw]);
}
break;
case cca('m'): // mirror object

View file

@ -3,7 +3,7 @@
let terms = {
COPYRIGHT: "Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved",
LICENSE: "See the license.md file included with the source distribution",
VERSION: "2.5.D0"
VERSION: "2.5.D1"
};
if (typeof(module) === 'object') {

View file

@ -47,8 +47,9 @@ self.kiri.loader.push(function() {
UC.newButton(null,replay,{icon:'<i class="fas fa-fast-backward"></i>',title:"restart"}),
playButton = UC.newButton(null,play,{icon:'<i class="fas fa-play"></i>',title:"play"}),
pauseButton = UC.newButton(null,pause,{icon:'<i class="fas fa-pause"></i>',title:"pause"}),
UC.newButton(null,step,{icon:'<i class="fas fa-step-forward"></i>',title:"step"}),
UC.newButton(null,fast,{icon:'<i class="fas fa-forward"></i>',title:"speed"}),
UC.newButton(null,step,{icon:'<i class="fas fa-step-forward"></i>',title:"single step"}),
UC.newButton(null,fast,{icon:'<i class="fas fa-forward"></i>',title:"toggle speed"}),
UC.newButton(null,skip,{icon:'<i class="fas fa-fast-forward"></i>',title:"skip forward without animation"}),
speedLabel = UC.newLabel("speed")
]);
updateSpeed();
@ -178,6 +179,13 @@ self.kiri.loader.push(function() {
KIRI.client.animate({speed: 0}, handleGridUpdate);
}
function skip() {
API.show.alert('fast fowarding without animation');
playButton.style.display = 'none';
pauseButton.style.display = '';
KIRI.client.animate({speed, steps: Infinity, toend: true}, handleGridUpdate);
}
function handleGridUpdate(data) {
checkMeshCommands(data);
if (data && data.progress) {
@ -282,6 +290,12 @@ self.kiri.loader.push(function() {
if (data.steps > 0) {
stepsRemain = data.steps;
}
if (data.toend) {
skipMode = !skipMode;
} else {
skipMode = false;
}
checkStash(send);
if (animating) {
return send.done();
}
@ -299,6 +313,19 @@ self.kiri.loader.push(function() {
let animating = false;
let renderSpeed = 25;
let stepsRemain = 0;
let skipMode = false;
let skipMove = null;
let skipStash = [];
function checkStash(send) {
if (!skipMode && skipStash.length) {
skipStash.forEach(mesh_update => {
send.data({ id: 0, mesh_update }, [ mesh_update.buffer ]);
});
skipStash = [];
send.data({ mesh_move: skipMove });
}
}
function renderPath(send) {
if (animateClear) {
@ -308,12 +335,16 @@ self.kiri.loader.push(function() {
return;
}
if (stepsRemain <= 0 || renderSpeed === 0) {
skipMode = false;
checkStash(send);
animating = false;
send.done();
return;
}
const next = path[pathIndex++];
if (!next) {
skipMode = false;
checkStash(send);
animating = false;
stepsRemain = 0;
send.done();
@ -375,12 +406,17 @@ self.kiri.loader.push(function() {
if (!pos) throw `no pos @ ${index} of ${moves.length}`;
tool.pos = pos;
updateMesh(pos, send);
send.data({ mesh_move: { id, pos }});
if (skipMode) {
skipMove = { id, pos };
} else {
send.data({ mesh_move: { id, pos } });
}
}
let pauseTime = skipMode ? 0 : renderSpeed;
if (index < moves.length) {
setTimeout(update, renderSpeed);
setTimeout(update, pauseTime);
} else {
setTimeout(() => { renderPath(send) }, renderSpeed);
setTimeout(() => { renderPath(send) }, pauseTime);
}
}
update(0);
@ -418,7 +454,11 @@ self.kiri.loader.push(function() {
}
if (upos > 0) {
const mesh_update = update.slice(0,upos);
send.data({ id: 0, mesh_update }, [ mesh_update.buffer ]);
if (skipMode) {
skipStash.push(mesh_update);
} else {
send.data({ id: 0, mesh_update }, [ mesh_update.buffer ]);
}
}
}

View file

@ -22,6 +22,8 @@
let zaxis = {x: 0, y: 0, z: 1},
func = {};
CAM.restoreTabs = restoreTabs;
CAM.init = function(kiri, api) {
FDM = KIRI.driver.FDM;

View file

@ -999,7 +999,7 @@ th, tr, td, label {
justify-content: center;
align-items: center;
position: absolute;
bottom: 40px;
bottom: 45px;
left: 0;
right: 0;
}
@ -1249,3 +1249,7 @@ th, tr, td, label {
border-bottom: 1px solid #ddd;
background-color: #eee;
}
#context-menu .sep {
border-top: 1px solid #ddd;
margin: 5px 0 5px 0;
}

View file

@ -396,9 +396,13 @@
</div>
<div id="tool-info" class="noshow"></div>
<div id="context-menu">
<button id="context-export-stl">export selection as STL</button>
<button id="context-export-workspace">export workspace</button>
<button id="context-clear-workspace">clear workspace</button>
<button id="context-export-workspace">export workspace</button>
<div class="sep"></div>
<button id="context-mirror">mirror</button>
<button id="context-duplicate">duplicate</button>
<div class="sep"></div>
<button id="context-export-stl">export as STL</button>
</div>
<div id="fps" class="noshow"></div>
<div id="layer-animate" class="f-col a-center"></div>