update code style, use gapp.register() for cam driver
This commit is contained in:
parent
57a2129dba
commit
836d53aad5
10 changed files with 4881 additions and 4862 deletions
|
|
@ -2,12 +2,15 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
self.kiri.load(function() {
|
// dep: kiri.api
|
||||||
|
// dep: kiri-mode.cam.driver
|
||||||
|
gapp.register("kiri-mode.cam.animate", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { kiri } = root;
|
||||||
CAM = KIRI.driver.CAM,
|
const { api, driver } = kiri;
|
||||||
API, WORLD, SPACE,
|
const { CAM } = driver;
|
||||||
meshes = {},
|
|
||||||
|
let meshes = {},
|
||||||
unitScale = 1,
|
unitScale = 1,
|
||||||
progress, toolPosX, toolPosY, toolPosZ,
|
progress, toolPosX, toolPosY, toolPosZ,
|
||||||
speedValues = [ 25, 12, 6, 3 ],
|
speedValues = [ 25, 12, 6, 3 ],
|
||||||
|
|
@ -21,30 +24,31 @@ self.kiri.load(function() {
|
||||||
playButton,
|
playButton,
|
||||||
posOffset = { x:0, y:0, z:0 };
|
posOffset = { x:0, y:0, z:0 };
|
||||||
|
|
||||||
// ---( CLIENT FUNCTIONS )---
|
// ---( CLIENT FUNCTIONS )---
|
||||||
|
|
||||||
if (KIRI.client)
|
kiri.load(() => {
|
||||||
CAM.animate_clear = function(api) {
|
if (!kiri.client) {
|
||||||
API = api;
|
return;
|
||||||
KIRI.client.animate_cleanup();
|
}
|
||||||
SPACE = KIRI.space;
|
|
||||||
WORLD = SPACE.world;
|
const { moto } = root;
|
||||||
|
const { space } = moto;
|
||||||
|
const { world } = space;
|
||||||
|
|
||||||
|
function animate_clear(api) {
|
||||||
|
kiri.client.animate_cleanup();
|
||||||
$('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));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KIRI.client)
|
function animate(api, delay) {
|
||||||
CAM.animate = function(api, delay) {
|
kiri.client.animate_setup(api.conf.get(), data => {
|
||||||
API = api;
|
|
||||||
SPACE = KIRI.space;
|
|
||||||
WORLD = SPACE.world;
|
|
||||||
KIRI.client.animate_setup(API.conf.get(), data => {
|
|
||||||
checkMeshCommands(data);
|
checkMeshCommands(data);
|
||||||
if (!(data && data.mesh_add)) {
|
if (!(data && data.mesh_add)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const UC = API.uc;
|
const UC = api.uc;
|
||||||
const layer = $('layer-animate');
|
const layer = $('layer-animate');
|
||||||
layer.innerHTML = '';
|
layer.innerHTML = '';
|
||||||
UC.setGroup(layer);
|
UC.setGroup(layer);
|
||||||
|
|
@ -70,9 +74,109 @@ self.kiri.load(function() {
|
||||||
toolPosZ = UC.newInput('z', {disabled: true, size: 7});
|
toolPosZ = UC.newInput('z', {disabled: true, size: 7});
|
||||||
playButton.style.display = '';
|
playButton.style.display = '';
|
||||||
pauseButton.style.display = 'none';
|
pauseButton.style.display = 'none';
|
||||||
API.event.emit('animate', 'CAM');
|
api.event.emit('animate', 'CAM');
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
|
gapp.overlay(kiri.client, {
|
||||||
|
animate(data, ondone) {
|
||||||
|
kiri.client.send("animate", data, ondone);
|
||||||
|
},
|
||||||
|
|
||||||
|
animate_setup(settings, ondone) {
|
||||||
|
color = settings.controller.dark ? 0x888888 : 0;
|
||||||
|
unitScale = settings.controller.units === 'in' ? 1/25.4 : 1;
|
||||||
|
kiri.client.send("animate_setup", {settings}, ondone);
|
||||||
|
},
|
||||||
|
|
||||||
|
animate_cleanup(data, ondone) {
|
||||||
|
kiri.client.send("animate_cleanup", data, ondone);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gapp.overlay(CAM, {
|
||||||
|
animate,
|
||||||
|
animate_clear
|
||||||
|
});
|
||||||
|
|
||||||
|
function meshAdd(id, ind, pos) {
|
||||||
|
const geo = new THREE.BufferGeometry();
|
||||||
|
geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));
|
||||||
|
geo.setIndex(new THREE.BufferAttribute(new Uint32Array(ind), 1));
|
||||||
|
const mat = new THREE.LineBasicMaterial({
|
||||||
|
transparent: true,
|
||||||
|
opacity: 0.75,
|
||||||
|
color
|
||||||
|
});
|
||||||
|
const mesh = new THREE.LineSegments(geo, mat);
|
||||||
|
world.add(mesh);
|
||||||
|
meshes[id] = mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
function meshUpdates(id, updates) {
|
||||||
|
const mesh = meshes[id];
|
||||||
|
if (!mesh) {
|
||||||
|
return; // animate cancelled
|
||||||
|
}
|
||||||
|
const mpos = mesh.geometry.attributes.position;
|
||||||
|
for (let i=0, il=updates.length; i<il; ) {
|
||||||
|
const pos = updates[i++];
|
||||||
|
const val = updates[i++];
|
||||||
|
mpos.array[pos] = val;
|
||||||
|
}
|
||||||
|
mpos.needsUpdate = true;
|
||||||
|
space.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteMesh(id) {
|
||||||
|
world.remove(meshes[id]);
|
||||||
|
delete meshes[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
function step(opts) {
|
||||||
|
const { steps } = opts;
|
||||||
|
updateSpeed();
|
||||||
|
kiri.client.animate({speed, steps: 1}, handleGridUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function play(opts) {
|
||||||
|
const { steps } = opts;
|
||||||
|
updateSpeed();
|
||||||
|
if (steps !== 1) {
|
||||||
|
playButton.style.display = 'none';
|
||||||
|
pauseButton.style.display = '';
|
||||||
|
}
|
||||||
|
kiri.client.animate({speed, steps: steps || Infinity}, handleGridUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fast(opts) {
|
||||||
|
const { steps } = opts;
|
||||||
|
updateSpeed(1);
|
||||||
|
playButton.style.display = 'none';
|
||||||
|
pauseButton.style.display = '';
|
||||||
|
kiri.client.animate({speed, steps: steps || Infinity}, handleGridUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pause() {
|
||||||
|
playButton.style.display = '';
|
||||||
|
pauseButton.style.display = 'none';
|
||||||
|
kiri.client.animate({speed: 0}, handleGridUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function skip() {
|
||||||
|
api.show.alert('fast fowarding without animation');
|
||||||
|
playButton.style.display = 'none';
|
||||||
|
pauseButton.style.display = '';
|
||||||
|
updateSpeed(Infinity);
|
||||||
|
kiri.client.animate({speed, steps: Infinity, toend: true}, handleGridUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleGridUpdate(data) {
|
||||||
|
checkMeshCommands(data);
|
||||||
|
if (data && data.progress) {
|
||||||
|
progress.value = (data.progress * 100).toFixed(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateSpeed(inc = 0) {
|
function updateSpeed(inc = 0) {
|
||||||
if (inc === Infinity) {
|
if (inc === Infinity) {
|
||||||
|
|
@ -85,9 +189,9 @@ self.kiri.load(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function replay() {
|
function replay() {
|
||||||
CAM.animate_clear(API);
|
CAM.animate_clear(api);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
CAM.animate(API, 50);
|
CAM.animate(api, 50);
|
||||||
}, 250);
|
}, 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +216,7 @@ self.kiri.load(function() {
|
||||||
mesh.position.x = pos.x;
|
mesh.position.x = pos.x;
|
||||||
mesh.position.y = pos.y;
|
mesh.position.y = pos.y;
|
||||||
mesh.position.z = pos.z;
|
mesh.position.z = pos.z;
|
||||||
SPACE.update();
|
space.update();
|
||||||
if (id !== 0) {
|
if (id !== 0) {
|
||||||
toolPosX.value = ((pos.x + posOffset.x) * unitScale).toFixed(2);
|
toolPosX.value = ((pos.x + posOffset.x) * unitScale).toFixed(2);
|
||||||
toolPosY.value = ((pos.y + posOffset.y) * unitScale).toFixed(2);
|
toolPosY.value = ((pos.y + posOffset.y) * unitScale).toFixed(2);
|
||||||
|
|
@ -125,109 +229,19 @@ self.kiri.load(function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function meshAdd(id, ind, pos) {
|
});
|
||||||
const geo = new THREE.BufferGeometry();
|
|
||||||
geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));
|
|
||||||
geo.setIndex(new THREE.BufferAttribute(new Uint32Array(ind), 1));
|
|
||||||
const mat = new THREE.LineBasicMaterial({
|
|
||||||
transparent: true,
|
|
||||||
opacity: 0.75,
|
|
||||||
color
|
|
||||||
});
|
|
||||||
const mesh = new THREE.LineSegments(geo, mat);
|
|
||||||
WORLD.add(mesh);
|
|
||||||
meshes[id] = mesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
function meshUpdates(id, updates) {
|
// ---( WORKER FUNCTIONS )---
|
||||||
const mesh = meshes[id];
|
|
||||||
if (!mesh) {
|
|
||||||
return; // animate cancelled
|
|
||||||
}
|
|
||||||
const mpos = mesh.geometry.attributes.position;
|
|
||||||
for (let i=0, il=updates.length; i<il; ) {
|
|
||||||
const pos = updates[i++];
|
|
||||||
const val = updates[i++];
|
|
||||||
mpos.array[pos] = val;
|
|
||||||
}
|
|
||||||
mpos.needsUpdate = true;
|
|
||||||
SPACE.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteMesh(id) {
|
kiri.load(() => {
|
||||||
WORLD.remove(meshes[id]);
|
if (!kiri.worker) {
|
||||||
delete meshes[id];
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function step(opts) {
|
|
||||||
const { steps } = opts;
|
|
||||||
updateSpeed();
|
|
||||||
KIRI.client.animate({speed, steps: 1}, handleGridUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function play(opts) {
|
|
||||||
const { steps } = opts;
|
|
||||||
updateSpeed();
|
|
||||||
if (steps !== 1) {
|
|
||||||
playButton.style.display = 'none';
|
|
||||||
pauseButton.style.display = '';
|
|
||||||
}
|
|
||||||
KIRI.client.animate({speed, steps: steps || Infinity}, handleGridUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function fast(opts) {
|
|
||||||
const { steps } = opts;
|
|
||||||
updateSpeed(1);
|
|
||||||
playButton.style.display = 'none';
|
|
||||||
pauseButton.style.display = '';
|
|
||||||
KIRI.client.animate({speed, steps: steps || Infinity}, handleGridUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function pause() {
|
|
||||||
playButton.style.display = '';
|
|
||||||
pauseButton.style.display = 'none';
|
|
||||||
KIRI.client.animate({speed: 0}, handleGridUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function skip() {
|
|
||||||
API.show.alert('fast fowarding without animation');
|
|
||||||
playButton.style.display = 'none';
|
|
||||||
pauseButton.style.display = '';
|
|
||||||
updateSpeed(Infinity);
|
|
||||||
KIRI.client.animate({speed, steps: Infinity, toend: true}, handleGridUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleGridUpdate(data) {
|
|
||||||
checkMeshCommands(data);
|
|
||||||
if (data && data.progress) {
|
|
||||||
progress.value = (data.progress * 100).toFixed(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (KIRI.client)
|
|
||||||
KIRI.client.animate_setup = function(settings, ondone) {
|
|
||||||
color = settings.controller.dark ? 0x888888 : 0;
|
|
||||||
unitScale = settings.controller.units === 'in' ? 1/25.4 : 1;
|
|
||||||
KIRI.client.send("animate_setup", {settings}, ondone);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (KIRI.client)
|
|
||||||
KIRI.client.animate = function(data, ondone) {
|
|
||||||
KIRI.client.send("animate", data, ondone);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (KIRI.client)
|
|
||||||
KIRI.client.animate_cleanup = function(data, ondone) {
|
|
||||||
KIRI.client.send("animate_cleanup", data, ondone);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---( WORKER FUNCTIONS )---
|
|
||||||
|
|
||||||
let stock, center, grid, gridX, gridY, rez;
|
let stock, center, grid, gridX, gridY, rez;
|
||||||
let path, pathIndex, tool, tools, last, toolID = 1;
|
let path, pathIndex, tool, tools, last, toolID = 1;
|
||||||
|
|
||||||
if (KIRI.worker)
|
kiri.worker.animate_setup = function(data, send) {
|
||||||
KIRI.worker.animate_setup = function(data, send) {
|
|
||||||
const { settings } = data;
|
const { settings } = data;
|
||||||
const { process } = settings;
|
const { process } = settings;
|
||||||
const print = current.print;
|
const print = current.print;
|
||||||
|
|
@ -267,6 +281,31 @@ self.kiri.load(function() {
|
||||||
send.done();
|
send.done();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kiri.worker.animate = function(data, send) {
|
||||||
|
if (data.speed >= 0) {
|
||||||
|
renderSpeed = data.speed;
|
||||||
|
}
|
||||||
|
if (data.steps > 0) {
|
||||||
|
stepsRemain = data.steps;
|
||||||
|
}
|
||||||
|
if (data.toend) {
|
||||||
|
skipMode = !skipMode;
|
||||||
|
} else {
|
||||||
|
skipMode = false;
|
||||||
|
}
|
||||||
|
checkStash(send);
|
||||||
|
if (animating) {
|
||||||
|
return send.done();
|
||||||
|
}
|
||||||
|
renderPath(send);
|
||||||
|
};
|
||||||
|
|
||||||
|
kiri.worker.animate_cleanup = function(data, send) {
|
||||||
|
if (animating) {
|
||||||
|
animateClear = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function createGrid(stepsX, stepsY, size, step) {
|
function createGrid(stepsX, stepsY, size, step) {
|
||||||
const gridPoints = stepsX * stepsY;
|
const gridPoints = stepsX * stepsY;
|
||||||
const pos = new Float32Array(gridPoints * 3);
|
const pos = new Float32Array(gridPoints * 3);
|
||||||
|
|
@ -300,33 +339,6 @@ self.kiri.load(function() {
|
||||||
return { pos, ind };
|
return { pos, ind };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KIRI.worker)
|
|
||||||
KIRI.worker.animate = function(data, send) {
|
|
||||||
if (data.speed >= 0) {
|
|
||||||
renderSpeed = data.speed;
|
|
||||||
}
|
|
||||||
if (data.steps > 0) {
|
|
||||||
stepsRemain = data.steps;
|
|
||||||
}
|
|
||||||
if (data.toend) {
|
|
||||||
skipMode = !skipMode;
|
|
||||||
} else {
|
|
||||||
skipMode = false;
|
|
||||||
}
|
|
||||||
checkStash(send);
|
|
||||||
if (animating) {
|
|
||||||
return send.done();
|
|
||||||
}
|
|
||||||
renderPath(send);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (KIRI.worker)
|
|
||||||
KIRI.worker.animate_cleanup = function(data, send) {
|
|
||||||
if (animating) {
|
|
||||||
animateClear = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let animateClear = false;
|
let animateClear = false;
|
||||||
let animating = false;
|
let animating = false;
|
||||||
let renderSpeed = 25;
|
let renderSpeed = 25;
|
||||||
|
|
@ -510,7 +522,7 @@ self.kiri.load(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// load renderer code in worker context only
|
// load renderer code in worker context only
|
||||||
if (KIRI.worker && false)
|
if (kiri.worker && false)
|
||||||
fetch('/wasm/kiri-ani.wasm')
|
fetch('/wasm/kiri-ani.wasm')
|
||||||
.then(response => response.arrayBuffer())
|
.then(response => response.arrayBuffer())
|
||||||
.then(bytes => WebAssembly.instantiate(bytes, {
|
.then(bytes => WebAssembly.instantiate(bytes, {
|
||||||
|
|
@ -535,3 +547,5 @@ self.kiri.load(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
gapp.register("kiri-mode.cam.client", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { base, kiri } = root;
|
||||||
BASE = self.base,
|
const { newPoint, newPolygon } = base;
|
||||||
CAM = KIRI.driver.CAM,
|
const { driver } = kiri;
|
||||||
PRO = CAM.process,
|
const { CAM } = driver;
|
||||||
newPolygon = BASE.newPolygon,
|
|
||||||
newPoint = BASE.newPoint,
|
let PRO = CAM.process,
|
||||||
isAnimate,
|
isAnimate,
|
||||||
isArrange,
|
isArrange,
|
||||||
isCamMode,
|
isCamMode,
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
hoveredOp,
|
hoveredOp,
|
||||||
API, FDM, SPACE, STACKS, MODES, VIEWS, UI, UC, LANG;
|
API, FDM, SPACE, STACKS, MODES, VIEWS, UI, UC, LANG;
|
||||||
|
|
||||||
let zaxis = { x: 0, y: 0, z: 1 },
|
let zaxis = { x: 0, y: 0, z: 1 },
|
||||||
popOp = {},
|
popOp = {},
|
||||||
func = {
|
func = {
|
||||||
hover: noop,
|
hover: noop,
|
||||||
|
|
@ -28,10 +28,10 @@
|
||||||
},
|
},
|
||||||
flipping;
|
flipping;
|
||||||
|
|
||||||
CAM.restoreTabs = restoreTabs;
|
CAM.restoreTabs = restoreTabs;
|
||||||
|
|
||||||
CAM.init = function(kiri, api) {
|
CAM.init = function(kiri, api) {
|
||||||
FDM = KIRI.driver.FDM;
|
FDM = kiri.driver.FDM;
|
||||||
|
|
||||||
// console.log({kiri,api})
|
// console.log({kiri,api})
|
||||||
SPACE = kiri.space;
|
SPACE = kiri.space;
|
||||||
|
|
@ -563,8 +563,8 @@
|
||||||
CAM.traces((ids) => {
|
CAM.traces((ids) => {
|
||||||
api.hide.alert(alert);
|
api.hide.alert(alert);
|
||||||
alert = api.show.alert("[esc] cancels trace editing");
|
alert = api.show.alert("[esc] cancels trace editing");
|
||||||
KIRI.api.widgets.opacity(0.8);
|
kiri.api.widgets.opacity(0.8);
|
||||||
KIRI.api.widgets.for(widget => {
|
kiri.api.widgets.for(widget => {
|
||||||
if (ids.indexOf(widget.id) >= 0) {
|
if (ids.indexOf(widget.id) >= 0) {
|
||||||
unselectTraces(widget, true);
|
unselectTraces(widget, true);
|
||||||
widget.trace_stack = null;
|
widget.trace_stack = null;
|
||||||
|
|
@ -575,11 +575,11 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let areas = (poppedRec.areas[widget.id] || []);
|
let areas = (poppedRec.areas[widget.id] || []);
|
||||||
let stack = new KIRI.Stack(widget.mesh);
|
let stack = new kiri.Stack(widget.mesh);
|
||||||
widget.trace_stack = stack;
|
widget.trace_stack = stack;
|
||||||
widget.traces.forEach(poly => {
|
widget.traces.forEach(poly => {
|
||||||
let match = areas.filter(arr => poly.matches(arr));
|
let match = areas.filter(arr => poly.matches(arr));
|
||||||
let layers = new KIRI.Layers();
|
let layers = new kiri.Layers();
|
||||||
layers.setLayer("trace", {line: 0xaaaa55}, false).addPoly(poly);
|
layers.setLayer("trace", {line: 0xaaaa55}, false).addPoly(poly);
|
||||||
stack.addLayers(layers);
|
stack.addLayers(layers);
|
||||||
stack.new_meshes.forEach(mesh => {
|
stack.new_meshes.forEach(mesh => {
|
||||||
|
|
@ -595,7 +595,7 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// ensure appropriate traces are toggled matching current record
|
// ensure appropriate traces are toggled matching current record
|
||||||
KIRI.api.widgets.for(widget => {
|
kiri.api.widgets.for(widget => {
|
||||||
let areas = (poppedRec.areas[widget.id] || []);
|
let areas = (poppedRec.areas[widget.id] || []);
|
||||||
let stack = widget.trace_stack;
|
let stack = widget.trace_stack;
|
||||||
stack.meshes.forEach(mesh => {
|
stack.meshes.forEach(mesh => {
|
||||||
|
|
@ -623,11 +623,11 @@
|
||||||
func.unpop();
|
func.unpop();
|
||||||
traceOn.classList.remove("editing");
|
traceOn.classList.remove("editing");
|
||||||
traceOn = false;
|
traceOn = false;
|
||||||
KIRI.api.widgets.opacity(1);
|
kiri.api.widgets.opacity(1);
|
||||||
api.hide.alert(alert);
|
api.hide.alert(alert);
|
||||||
api.feature.hover = false;
|
api.feature.hover = false;
|
||||||
api.feature.hoverAdds = false;
|
api.feature.hoverAdds = false;
|
||||||
KIRI.api.widgets.for(widget => {
|
kiri.api.widgets.for(widget => {
|
||||||
if (widget.trace_stack) {
|
if (widget.trace_stack) {
|
||||||
widget.trace_stack.hide();
|
widget.trace_stack.hide();
|
||||||
widget.adds.removeAll(widget.trace_stack.meshes);
|
widget.adds.removeAll(widget.trace_stack.meshes);
|
||||||
|
|
@ -1020,9 +1020,9 @@
|
||||||
UC.newButton(LANG.cc_flip, func.opFlip)
|
UC.newButton(LANG.cc_flip, func.opFlip)
|
||||||
], {class:"ext-buttons f-row"})
|
], {class:"ext-buttons f-row"})
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function createPopOp(type, map) {
|
function createPopOp(type, map) {
|
||||||
let op = popOp[type] = {
|
let op = popOp[type] = {
|
||||||
div: UC.newElement('div', { id:`${type}-op`, class:"cam-pop-op" }),
|
div: UC.newElement('div', { id:`${type}-op`, class:"cam-pop-op" }),
|
||||||
use: (rec) => {
|
use: (rec) => {
|
||||||
|
|
@ -1076,9 +1076,9 @@
|
||||||
lastGroup: op.group
|
lastGroup: op.group
|
||||||
});
|
});
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTabBox(iw, ic, n) {
|
function createTabBox(iw, ic, n) {
|
||||||
const { track } = iw;
|
const { track } = iw;
|
||||||
const { stock, bounds, process } = API.conf.get();
|
const { stock, bounds, process } = API.conf.get();
|
||||||
const { camTabsWidth, camTabsHeight, camTabsDepth, camTabsMidline } = process;
|
const { camTabsWidth, camTabsHeight, camTabsDepth, camTabsMidline } = process;
|
||||||
|
|
@ -1093,9 +1093,9 @@
|
||||||
const dim = { x:camTabsDepth, y:camTabsWidth, z:camTabsHeight };
|
const dim = { x:camTabsDepth, y:camTabsWidth, z:camTabsHeight };
|
||||||
const tab = addbox(pos, 0x0000dd, 'tabb', dim, { rotate: rot });
|
const tab = addbox(pos, 0x0000dd, 'tabb', dim, { rotate: rot });
|
||||||
return { pos, dim, rot, tab, width: camTabsWidth, height: camTabsHeight };
|
return { pos, dim, rot, tab, width: camTabsWidth, height: camTabsHeight };
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWidgetTab(widget, rec) {
|
function addWidgetTab(widget, rec) {
|
||||||
const { pos, dim, rot, id } = rec;
|
const { pos, dim, rot, id } = rec;
|
||||||
const tabs = widget.tabs = (widget.tabs || {});
|
const tabs = widget.tabs = (widget.tabs || {});
|
||||||
// prevent duplicate restore from repeated settings load calls
|
// prevent duplicate restore from repeated settings load calls
|
||||||
|
|
@ -1108,9 +1108,9 @@
|
||||||
widget.adds.push(pos.box);
|
widget.adds.push(pos.box);
|
||||||
tabs[id] = pos;
|
tabs[id] = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreTabs(widgets) {
|
function restoreTabs(widgets) {
|
||||||
widgets.forEach(widget => {
|
widgets.forEach(widget => {
|
||||||
const tabs = API.widgets.annotate(widget.id).tab || [];
|
const tabs = API.widgets.annotate(widget.id).tab || [];
|
||||||
tabs.forEach(rec => {
|
tabs.forEach(rec => {
|
||||||
|
|
@ -1119,9 +1119,9 @@
|
||||||
addWidgetTab(widget, rec);
|
addWidgetTab(widget, rec);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearTabs(widget, skiprec) {
|
function clearTabs(widget, skiprec) {
|
||||||
Object.values(widget.tabs || {}).forEach(rec => {
|
Object.values(widget.tabs || {}).forEach(rec => {
|
||||||
widget.adds.remove(rec.box);
|
widget.adds.remove(rec.box);
|
||||||
widget.mesh.remove(rec.box);
|
widget.mesh.remove(rec.box);
|
||||||
|
|
@ -1130,9 +1130,9 @@
|
||||||
if (!skiprec) {
|
if (!skiprec) {
|
||||||
delete API.widgets.annotate(widget.id).tab;
|
delete API.widgets.annotate(widget.id).tab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function unselectTraces(widget, skip) {
|
function unselectTraces(widget, skip) {
|
||||||
if (widget.trace_stack) {
|
if (widget.trace_stack) {
|
||||||
widget.trace_stack.meshes.forEach(mesh => {
|
widget.trace_stack.meshes.forEach(mesh => {
|
||||||
if (mesh.selected) {
|
if (mesh.selected) {
|
||||||
|
|
@ -1140,20 +1140,20 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addbox() { return FDM.addbox(...arguments)};
|
function addbox() { return FDM.addbox(...arguments)};
|
||||||
function delbox() { return FDM.delbox(...arguments)};
|
function delbox() { return FDM.delbox(...arguments)};
|
||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
isAnimate = true;
|
isAnimate = true;
|
||||||
API.widgets.opacity(isParsed ? 0 : 0.75);
|
API.widgets.opacity(isParsed ? 0 : 0.75);
|
||||||
API.hide.slider();
|
API.hide.slider();
|
||||||
STACKS.clear();
|
STACKS.clear();
|
||||||
CAM.animate(API);
|
CAM.animate(API);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStock(args, event) {
|
function updateStock(args, event) {
|
||||||
if (isAnimate) {
|
if (isAnimate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1254,7 +1254,7 @@
|
||||||
|
|
||||||
const {x, y, z} = stock;
|
const {x, y, z} = stock;
|
||||||
if (x && y && z && !STACKS.getStack('bounds')) {
|
if (x && y && z && !STACKS.getStack('bounds')) {
|
||||||
const render = new KIRI.Layers().setLayer('bounds', { face: 0xaaaaaa, line: 0xaaaaaa });
|
const render = new kiri.Layers().setLayer('bounds', { face: 0xaaaaaa, line: 0xaaaaaa });
|
||||||
const stack = STACKS.setFreeMem(false).create('bounds', SPACE.world);
|
const stack = STACKS.setFreeMem(false).create('bounds', SPACE.world);
|
||||||
stack.add(render.addPolys([
|
stack.add(render.addPolys([
|
||||||
newPolygon().centerRectangle({x:csox, y:csoy, z:0}, x, y),
|
newPolygon().centerRectangle({x:csox, y:csoy, z:0}, x, y),
|
||||||
|
|
@ -1274,6 +1274,6 @@
|
||||||
API.platform.update_top_z(delta);
|
API.platform.update_top_z(delta);
|
||||||
API.platform.update_origin();
|
API.platform.update_origin();
|
||||||
SPACE.update();
|
SPACE.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,17 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
// dep: main.kiri
|
||||||
|
// use: kiri.api
|
||||||
|
// use: kiri.widgets
|
||||||
|
gapp.register("kiri-mode.cam.driver", [], (root, exports) => {
|
||||||
|
|
||||||
const KIRI = self.kiri,
|
const { kiri } = root;
|
||||||
CAM = KIRI.driver.CAM = {
|
const { driver } = kiri;
|
||||||
// init, // src/mode/cam/client.js
|
|
||||||
// slice, // src/mode/cam/slice.js
|
const CAM = driver.CAM = {};
|
||||||
// prepare, // src/mode/cam/prepare.js
|
|
||||||
// export // src/mode/cam/export.js
|
CAM.process = {
|
||||||
},
|
|
||||||
CPRO = CAM.process = {
|
|
||||||
LEVEL: 1,
|
LEVEL: 1,
|
||||||
ROUGH: 2,
|
ROUGH: 2,
|
||||||
OUTLINE: 3,
|
OUTLINE: 3,
|
||||||
|
|
@ -19,19 +20,19 @@
|
||||||
CONTOUR_Y: 5,
|
CONTOUR_Y: 5,
|
||||||
TRACE: 6,
|
TRACE: 6,
|
||||||
DRILL: 7
|
DRILL: 7
|
||||||
};
|
};
|
||||||
|
|
||||||
// defer loading until KIRI.client and KIRI.worker exist
|
// defer loading until kiri.client and kiri.worker exist
|
||||||
KIRI.load(function(API) {
|
kiri.load(api => {
|
||||||
|
|
||||||
if (KIRI.client)
|
if (kiri.client)
|
||||||
CAM.traces = function(ondone, single) {
|
CAM.traces = function(ondone, single) {
|
||||||
KIRI.client.sync();
|
kiri.client.sync();
|
||||||
let settings = API.conf.get();
|
const settings = api.conf.get();
|
||||||
let widgets = API.widgets.map();
|
const widgets = api.widgets.map();
|
||||||
KIRI.client.send("cam_traces", { settings, single }, output => {
|
kiri.client.send("cam_traces", { settings, single }, output => {
|
||||||
let ids = [];
|
const ids = [];
|
||||||
KIRI.codec.decode(output).forEach(rec => {
|
kiri.codec.decode(output).forEach(rec => {
|
||||||
ids.push(rec.id);
|
ids.push(rec.id);
|
||||||
widgets[rec.id].traces = rec.traces;
|
widgets[rec.id].traces = rec.traces;
|
||||||
});
|
});
|
||||||
|
|
@ -39,17 +40,17 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (KIRI.worker)
|
if (kiri.worker)
|
||||||
KIRI.worker.cam_traces = function(data, send) {
|
kiri.worker.cam_traces = function(data, send) {
|
||||||
const { settings, single } = data;
|
const { settings, single } = data;
|
||||||
const widgets = Object.values(wcache);
|
const widgets = Object.values(wcache);
|
||||||
const fresh = widgets.filter(widget => CAM.traces(settings, widget, single));
|
const fresh = widgets.filter(widget => CAM.traces(settings, widget, single));
|
||||||
send.done(KIRI.codec.encode(fresh.map(widget => { return {
|
send.done(kiri.codec.encode(fresh.map(widget => { return {
|
||||||
id: widget.id,
|
id: widget.id,
|
||||||
traces: widget.traces,
|
traces: widget.traces,
|
||||||
} } )));
|
} } )));
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,28 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
// dep: geo.base
|
||||||
|
// dep: geo.polygons
|
||||||
|
gapp.register("kiri-mode.cam.export", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { base, kiri } = root;
|
||||||
BASE = self.base,
|
const { polygons, util } = base;
|
||||||
POLY = BASE.polygons,
|
const { driver } = kiri;
|
||||||
UTIL = BASE.util,
|
const { CAM } = driver;
|
||||||
CAM = KIRI.driver.CAM,
|
|
||||||
PRO = CAM.process;
|
|
||||||
|
|
||||||
/**
|
const POLY = polygons;
|
||||||
|
const PRO = CAM.process;
|
||||||
|
|
||||||
|
/**
|
||||||
* @returns {Array} gcode lines
|
* @returns {Array} gcode lines
|
||||||
*/
|
*/
|
||||||
CAM.export = function(print, online) {
|
CAM.export = function(print, online) {
|
||||||
let widget = print.widgets[0];
|
const widget = print.widgets[0];
|
||||||
if (!widget) return;
|
if (!widget) return;
|
||||||
|
|
||||||
|
const { settings } = print;
|
||||||
|
const { device, tools } = settings;
|
||||||
|
|
||||||
let i,
|
let i,
|
||||||
time = 0,
|
time = 0,
|
||||||
lines = 0,
|
lines = 0,
|
||||||
|
|
@ -26,22 +32,18 @@
|
||||||
factor = 1,
|
factor = 1,
|
||||||
output = [],
|
output = [],
|
||||||
spindle = 0,
|
spindle = 0,
|
||||||
settings = print.settings,
|
|
||||||
device = settings.device,
|
|
||||||
gcodes = settings.device || {},
|
|
||||||
origin = settings.origin || { x: 0, y: 0, z: 0 },
|
origin = settings.origin || { x: 0, y: 0, z: 0 },
|
||||||
tools = settings.tools,
|
space = device.gcodeSpace ? ' ' : '',
|
||||||
space = gcodes.gcodeSpace ? ' ' : '',
|
|
||||||
isRML = device.gcodeFExt.toLowerCase() === 'rml',
|
isRML = device.gcodeFExt.toLowerCase() === 'rml',
|
||||||
stripComments = gcodes.gcodeStrip || false,
|
stripComments = device.gcodeStrip || false,
|
||||||
cmdToolChange = gcodes.gcodeChange || [ "M6 T{tool}" ],
|
cmdToolChange = device.gcodeChange || [ "M6 T{tool}" ],
|
||||||
cmdSpindle = gcodes.gcodeSpindle || [ "M3 S{speed}" ],
|
cmdSpindle = device.gcodeSpindle || [ "M3 S{speed}" ],
|
||||||
cmdDwell = gcodes.gcodeDwell || [ "G4 P{time}" ],
|
cmdDwell = device.gcodeDwell || [ "G4 P{time}" ],
|
||||||
dev = settings.device,
|
dev = settings.device,
|
||||||
spro = settings.process,
|
spro = settings.process,
|
||||||
maxZd = spro.camFastFeedZ,
|
maxZd = spro.camFastFeedZ,
|
||||||
maxXYd = spro.camFastFeed,
|
maxXYd = spro.camFastFeed,
|
||||||
decimals = BASE.config.gcode_decimals || 4,
|
decimals = base.config.gcode_decimals || 4,
|
||||||
pos = { x:null, y:null, z:null, f:null, t:null },
|
pos = { x:null, y:null, z:null, f:null, t:null },
|
||||||
line,
|
line,
|
||||||
cidx,
|
cidx,
|
||||||
|
|
@ -149,9 +151,9 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
newpos.x = UTIL.round(newpos.x, decimals);
|
newpos.x = util.round(newpos.x, decimals);
|
||||||
newpos.y = UTIL.round(newpos.y, decimals);
|
newpos.y = util.round(newpos.y, decimals);
|
||||||
newpos.z = UTIL.round(newpos.z, decimals);
|
newpos.z = util.round(newpos.z, decimals);
|
||||||
|
|
||||||
// on tool change
|
// on tool change
|
||||||
if (out.tool != pos.t) {
|
if (out.tool != pos.t) {
|
||||||
|
|
@ -241,7 +243,7 @@
|
||||||
|
|
||||||
section('header');
|
section('header');
|
||||||
if (!stripComments) {
|
if (!stripComments) {
|
||||||
append(`; Generated by Kiri:Moto ${KIRI.version}`);
|
append(`; Generated by Kiri:Moto ${kiri.version}`);
|
||||||
append(`; ${new Date().toString()}`);
|
append(`; ${new Date().toString()}`);
|
||||||
filterEmit(["; Bed left:{left} right:{right} top:{top} bottom:{bottom}"], consts);
|
filterEmit(["; Bed left:{left} right:{right} top:{top} bottom:{bottom}"], consts);
|
||||||
if (hasStock) {
|
if (hasStock) {
|
||||||
|
|
@ -290,7 +292,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit gcode preamble
|
// emit gcode preamble
|
||||||
filterEmit(gcodes.gcodePre, consts);
|
filterEmit(device.gcodePre, consts);
|
||||||
|
|
||||||
// emit all points in layer/point order
|
// emit all points in layer/point order
|
||||||
print.output.forEach(function (layerout) {
|
print.output.forEach(function (layerout) {
|
||||||
|
|
@ -320,7 +322,7 @@
|
||||||
|
|
||||||
// emit gcode post
|
// emit gcode post
|
||||||
section('footer');
|
section('footer');
|
||||||
filterEmit(gcodes.gcodePost, consts);
|
filterEmit(device.gcodePost, consts);
|
||||||
|
|
||||||
// flush buffered gcode
|
// flush buffered gcode
|
||||||
append();
|
append();
|
||||||
|
|
@ -329,6 +331,6 @@
|
||||||
print.lines = lines;
|
print.lines = lines;
|
||||||
print.bytes = bytes + lines - 1;
|
print.bytes = bytes + lines - 1;
|
||||||
print.bounds = runbox;
|
print.bounds = runbox;
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,22 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
// dep: geo.base
|
||||||
|
// dep: geo.paths
|
||||||
|
// dep: geo.point
|
||||||
|
// dep: geo.polygons
|
||||||
|
// dep: kiri.slice
|
||||||
|
gapp.register("kiri-mode.cam.ops", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { base, kiri } = root;
|
||||||
BASE = self.base,
|
const { paths, polygons, newPoint, newPolygon } = base;
|
||||||
UTIL = BASE.util,
|
const { poly2polyEmit, tip2tipEmit } = paths;
|
||||||
CAM = KIRI.driver.CAM,
|
const { driver, newSlice } = kiri;
|
||||||
PRO = CAM.process,
|
const { CAM } = driver;
|
||||||
POLY = BASE.polygons,
|
|
||||||
newSlice = KIRI.newSlice,
|
|
||||||
newPoint = BASE.newPoint,
|
|
||||||
newPolygon = BASE.newPolygon;
|
|
||||||
|
|
||||||
class CamOp {
|
const POLY = polygons;
|
||||||
|
|
||||||
|
class CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.op = op
|
this.op = op
|
||||||
|
|
@ -31,9 +34,9 @@
|
||||||
slice() { }
|
slice() { }
|
||||||
|
|
||||||
prepare() { }
|
prepare() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpLevel extends CamOp {
|
class OpLevel extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
@ -95,9 +98,9 @@
|
||||||
polyEmit(lines[0]);
|
polyEmit(lines[0]);
|
||||||
newLayer();
|
newLayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpRough extends CamOp {
|
class OpRough extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
@ -320,7 +323,7 @@
|
||||||
prepare(ops, progress) {
|
prepare(ops, progress) {
|
||||||
let { op, state, sliceOut, camFaces } = this;
|
let { op, state, sliceOut, camFaces } = this;
|
||||||
let { setTool, setSpindle, setPrintPoint } = ops;
|
let { setTool, setSpindle, setPrintPoint } = ops;
|
||||||
let { polyEmit, poly2polyEmit, depthRoughPath } = ops;
|
let { polyEmit, depthRoughPath } = ops;
|
||||||
let { camOut, newLayer, printPoint } = ops;
|
let { camOut, newLayer, printPoint } = ops;
|
||||||
let { settings, widget } = state;
|
let { settings, widget } = state;
|
||||||
let { process, controller } = settings;
|
let { process, controller } = settings;
|
||||||
|
|
@ -403,9 +406,9 @@
|
||||||
|
|
||||||
setPrintPoint(printPoint);
|
setPrintPoint(printPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpOutline extends CamOp {
|
class OpOutline extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
@ -467,7 +470,7 @@
|
||||||
// extend cut thru (only when z bottom is 0)
|
// extend cut thru (only when z bottom is 0)
|
||||||
if (zThru) {
|
if (zThru) {
|
||||||
let last = slices[slices.length-1];
|
let last = slices[slices.length-1];
|
||||||
for (let zneg of BASE.util.lerp(0, zThru, op.down)) {
|
for (let zneg of base.util.lerp(0, zThru, op.down)) {
|
||||||
let add = last.clone(true);
|
let add = last.clone(true);
|
||||||
add.tops.forEach(top => top.poly.setZ(add.z));
|
add.tops.forEach(top => top.poly.setZ(add.z));
|
||||||
add.shadow = last.shadow.clone(true);
|
add.shadow = last.shadow.clone(true);
|
||||||
|
|
@ -566,7 +569,7 @@
|
||||||
prepare(ops, progress) {
|
prepare(ops, progress) {
|
||||||
let { op, state, sliceOut } = this;
|
let { op, state, sliceOut } = this;
|
||||||
let { setTool, setSpindle, setPrintPoint } = ops;
|
let { setTool, setSpindle, setPrintPoint } = ops;
|
||||||
let { polyEmit, poly2polyEmit, depthOutlinePath } = ops;
|
let { polyEmit, depthOutlinePath } = ops;
|
||||||
let { camOut, newLayer, printPoint } = ops;
|
let { camOut, newLayer, printPoint } = ops;
|
||||||
let { settings, widget } = state;
|
let { settings, widget } = state;
|
||||||
let { process, controller } = settings;
|
let { process, controller } = settings;
|
||||||
|
|
@ -630,9 +633,9 @@
|
||||||
|
|
||||||
setPrintPoint(printPoint);
|
setPrintPoint(printPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpContour extends CamOp {
|
class OpContour extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
@ -662,7 +665,7 @@
|
||||||
prepare(ops, progress) {
|
prepare(ops, progress) {
|
||||||
let { op, state, sliceOut } = this;
|
let { op, state, sliceOut } = this;
|
||||||
let { setTolerance, setTool, setSpindle, setPrintPoint } = ops;
|
let { setTolerance, setTool, setSpindle, setPrintPoint } = ops;
|
||||||
let { polyEmit, poly2polyEmit, tip2tipEmit } = ops;
|
let { polyEmit } = ops;
|
||||||
let { camOut, newLayer, printPoint, lastPoint } = ops;
|
let { camOut, newLayer, printPoint, lastPoint } = ops;
|
||||||
let { bounds, zmax } = ops;
|
let { bounds, zmax } = ops;
|
||||||
let { settings, widget } = state;
|
let { settings, widget } = state;
|
||||||
|
|
@ -719,9 +722,9 @@
|
||||||
|
|
||||||
setPrintPoint(printPoint);
|
setPrintPoint(printPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpTrace extends CamOp {
|
class OpTrace extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
@ -732,7 +735,6 @@
|
||||||
let { settings, widget, sliceAll, zMax, zTop, zThru, tabs } = state;
|
let { settings, widget, sliceAll, zMax, zTop, zThru, tabs } = state;
|
||||||
let { updateToolDiams, cutTabs, cutPolys, healPolys } = state;
|
let { updateToolDiams, cutTabs, cutPolys, healPolys } = state;
|
||||||
let { process, stock } = settings;
|
let { process, stock } = settings;
|
||||||
let poly2polyEmit = BASE.util.poly2polyEmit;
|
|
||||||
// generate tracing offsets from chosen features
|
// generate tracing offsets from chosen features
|
||||||
let sliceOut = this.sliceOut = [];
|
let sliceOut = this.sliceOut = [];
|
||||||
let areas = op.areas[widget.id] || [];
|
let areas = op.areas[widget.id] || [];
|
||||||
|
|
@ -776,7 +778,7 @@
|
||||||
.addPolys(slice.camLines)
|
.addPolys(slice.camLines)
|
||||||
}
|
}
|
||||||
function clearZ(polys, z, down) {
|
function clearZ(polys, z, down) {
|
||||||
let zs = down ? BASE.util.lerp(zTop, z, down) : [ z ];
|
let zs = down ? base.util.lerp(zTop, z, down) : [ z ];
|
||||||
let nested = POLY.nest(polys);
|
let nested = POLY.nest(polys);
|
||||||
for (let poly of nested) {
|
for (let poly of nested) {
|
||||||
for (let z of zs) {
|
for (let z of zs) {
|
||||||
|
|
@ -881,7 +883,7 @@
|
||||||
if (zThru && similar(zto,0)) {
|
if (zThru && similar(zto,0)) {
|
||||||
zto -= zThru;
|
zto -= zThru;
|
||||||
}
|
}
|
||||||
for (let z of BASE.util.lerp(zTop, zto, down)) {
|
for (let z of base.util.lerp(zTop, zto, down)) {
|
||||||
followZ(pi.clone().setZ(z));
|
followZ(pi.clone().setZ(z));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -912,9 +914,9 @@
|
||||||
ops.emitTrace(slice);
|
ops.emitTrace(slice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpDrill extends CamOp {
|
class OpDrill extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
@ -1002,9 +1004,9 @@
|
||||||
setSpindle(op.spindle);
|
setSpindle(op.spindle);
|
||||||
emitDrills(this.sliceOut.map(slice => slice.camLines).flat());
|
emitDrills(this.sliceOut.map(slice => slice.camLines).flat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpRegister extends CamOp {
|
class OpRegister extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
@ -1089,7 +1091,7 @@
|
||||||
tv = -tv;
|
tv = -tv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let z of BASE.util.lerp(z1, z2, op.down)) {
|
for (let z of base.util.lerp(z1, z2, op.down)) {
|
||||||
let slice = newSlice(z);
|
let slice = newSlice(z);
|
||||||
sliceAll.push(slice);
|
sliceAll.push(slice);
|
||||||
sliceOut.push(slice);
|
sliceOut.push(slice);
|
||||||
|
|
@ -1154,16 +1156,16 @@
|
||||||
emitDrills(this.sliceOut.map(slice => slice.camLines).flat());
|
emitDrills(this.sliceOut.map(slice => slice.camLines).flat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpXRay extends CamOp {
|
class OpXRay extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
slice(progress) {
|
slice(progress) {
|
||||||
let { widget, sliceAll } = this.state;
|
let { widget, sliceAll } = this.state;
|
||||||
let slicer = new KIRI.cam_slicer(widget.getPoints(), {
|
let slicer = new kiri.cam_slicer(widget.getPoints(), {
|
||||||
zlist: true,
|
zlist: true,
|
||||||
zline: true
|
zline: true
|
||||||
});
|
});
|
||||||
|
|
@ -1182,9 +1184,9 @@
|
||||||
// xrayopt.over = true;
|
// xrayopt.over = true;
|
||||||
// slicer.slice(xrayind, xrayopt);
|
// slicer.slice(xrayind, xrayopt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpShadow extends CamOp {
|
class OpShadow extends CamOp {
|
||||||
constructor(state, op) {
|
constructor(state, op) {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
@ -1257,9 +1259,9 @@
|
||||||
// identify through holes
|
// identify through holes
|
||||||
state.thruHoles = tshadow.map(p => p.inner || []).flat();
|
state.thruHoles = tshadow.map(p => p.inner || []).flat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CAM.shadowAt = function(widget, z, ztop) {
|
CAM.shadowAt = function(widget, z, ztop) {
|
||||||
let geo = widget.cache.geo || new THREE.BufferGeometry()
|
let geo = widget.cache.geo || new THREE.BufferGeometry()
|
||||||
.setAttribute('position', new THREE.BufferAttribute(widget.vertices, 3));
|
.setAttribute('position', new THREE.BufferAttribute(widget.vertices, 3));
|
||||||
widget.cache.geo = geo;
|
widget.cache.geo = geo;
|
||||||
|
|
@ -1329,9 +1331,9 @@
|
||||||
.add(a[2].x,a[2].y,a[2].z);
|
.add(a[2].x,a[2].y,a[2].z);
|
||||||
});
|
});
|
||||||
return POLY.union(polys, 0.0001, true);
|
return POLY.union(polys, 0.0001, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
CAM.OPS = CamOp.MAP = {
|
CAM.OPS = CamOp.MAP = {
|
||||||
"xray": OpXRay,
|
"xray": OpXRay,
|
||||||
"shadow": OpShadow,
|
"shadow": OpShadow,
|
||||||
"level": OpLevel,
|
"level": OpLevel,
|
||||||
|
|
@ -1342,6 +1344,6 @@
|
||||||
"drill": OpDrill,
|
"drill": OpDrill,
|
||||||
"register": OpRegister,
|
"register": OpRegister,
|
||||||
"flip": CamOp
|
"flip": CamOp
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,20 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
// dep: geo.paths
|
||||||
|
// dep: geo.point
|
||||||
|
// dep: geo.polygons
|
||||||
|
gapp.register("kiri-mode.cam.prepare", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { base, kiri } = root;
|
||||||
BASE = self.base,
|
const { paths, polygons, newPoint } = base;
|
||||||
POLY = BASE.polygons,
|
const { tip2tipEmit, poly2polyEmit } = paths;
|
||||||
PATH = BASE.paths,
|
const { driver } = kiri;
|
||||||
CAM = KIRI.driver.CAM,
|
const { CAM } = driver;
|
||||||
{ newPoint } = BASE,
|
|
||||||
{ tip2tipEmit, poly2polyEmit } = PATH;
|
|
||||||
|
|
||||||
/**
|
const POLY = polygons;
|
||||||
|
|
||||||
|
/**
|
||||||
* DRIVER PRINT CONTRACT
|
* DRIVER PRINT CONTRACT
|
||||||
*
|
*
|
||||||
* @param {Object} print state object
|
* @param {Object} print state object
|
||||||
|
|
@ -20,12 +23,12 @@
|
||||||
* @param {Number} [index] into widget array
|
* @param {Number} [index] into widget array
|
||||||
* @param {Object} [firstPoint] starting point
|
* @param {Object} [firstPoint] starting point
|
||||||
*/
|
*/
|
||||||
CAM.prepare = function(widgets, settings, update) {
|
CAM.prepare = function(widgets, settings, update) {
|
||||||
widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled);
|
widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled);
|
||||||
|
|
||||||
const count = widgets.length;
|
const count = widgets.length;
|
||||||
const weight = 1/count;
|
const weight = 1/count;
|
||||||
const print = self.worker.print = KIRI.newPrint(settings, widgets);
|
const print = self.worker.print = kiri.newPrint(settings, widgets);
|
||||||
print.output = [];
|
print.output = [];
|
||||||
|
|
||||||
let point;
|
let point;
|
||||||
|
|
@ -35,7 +38,7 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
print.render = KIRI.driver.FDM.prepareRender(print.output, (progress, layer) => {
|
print.render = kiri.driver.FDM.prepareRender(print.output, (progress, layer) => {
|
||||||
update(0.75 + progress * 0.25, "render", layer);
|
update(0.75 + progress * 0.25, "render", layer);
|
||||||
}, {
|
}, {
|
||||||
thin: true,
|
thin: true,
|
||||||
|
|
@ -49,9 +52,9 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
return print.render;
|
return print.render;
|
||||||
};
|
};
|
||||||
|
|
||||||
function prepEach(widget, settings, print, firstPoint, update) {
|
function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
|
|
||||||
if (widget.camops.length === 0 || widget.meta.disabled) return;
|
if (widget.camops.length === 0 || widget.meta.disabled) return;
|
||||||
|
|
||||||
|
|
@ -502,12 +505,12 @@
|
||||||
// replace output single flattened layer with all points
|
// replace output single flattened layer with all points
|
||||||
print.output = newOutput;
|
print.output = newOutput;
|
||||||
return printPoint;
|
return printPoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return tool Z clearance height for a line segment movement path
|
* return tool Z clearance height for a line segment movement path
|
||||||
*/
|
*/
|
||||||
function getZClearPath(terrain, x1, y1, x2, y2, z, zadd, off, over) {
|
function getZClearPath(terrain, x1, y1, x2, y2, z, zadd, off, over) {
|
||||||
// when terrain skipped, top + pass used
|
// when terrain skipped, top + pass used
|
||||||
if (terrain > 0) {
|
if (terrain > 0) {
|
||||||
return terrain;
|
return terrain;
|
||||||
|
|
@ -549,6 +552,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return maxz;
|
return maxz;
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,28 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
// dep: geo.point
|
||||||
|
// dep: geo.polygons
|
||||||
|
// dep: kiri.slice
|
||||||
|
gapp.register("kiri-mode.cam.slice", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { base, kiri } = root;
|
||||||
BASE = self.base,
|
const { driver, newSlice } = kiri;
|
||||||
UTIL = BASE.util,
|
const { polygons, newPoint, newPolygon } = base;
|
||||||
CAM = KIRI.driver.CAM,
|
const { CAM } = driver;
|
||||||
OPS = CAM.OPS,
|
const { OPS } = CAM;
|
||||||
PRO = CAM.process,
|
|
||||||
POLY = BASE.polygons,
|
|
||||||
newSlice = KIRI.newSlice,
|
|
||||||
newPoint = BASE.newPoint,
|
|
||||||
newPolygon = BASE.newPolygon;
|
|
||||||
|
|
||||||
/**
|
const PRO = CAM.process;
|
||||||
|
const POLY = polygons;
|
||||||
|
|
||||||
|
/**
|
||||||
* DRIVER SLICE CONTRACT
|
* DRIVER SLICE CONTRACT
|
||||||
*
|
*
|
||||||
* @param {Object} settings
|
* @param {Object} settings
|
||||||
* @param {Widget} widget
|
* @param {Widget} widget
|
||||||
* @param {Function} output
|
* @param {Function} output
|
||||||
*/
|
*/
|
||||||
CAM.slice = function(settings, widget, onupdate, ondone) {
|
CAM.slice = function(settings, widget, onupdate, ondone) {
|
||||||
let mesh = widget.mesh,
|
let mesh = widget.mesh,
|
||||||
proc = settings.process,
|
proc = settings.process,
|
||||||
stock = settings.stock || {},
|
stock = settings.stock || {},
|
||||||
|
|
@ -93,7 +94,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let mark = Date.now();
|
let mark = Date.now();
|
||||||
let slicer = new KIRI.cam_slicer(widget.getPoints(), {
|
let slicer = new kiri.cam_slicer(widget.getPoints(), {
|
||||||
zlist: true,
|
zlist: true,
|
||||||
zline: true
|
zline: true
|
||||||
});
|
});
|
||||||
|
|
@ -189,9 +190,9 @@
|
||||||
widget.maxToolDiam = maxToolDiam;
|
widget.maxToolDiam = maxToolDiam;
|
||||||
|
|
||||||
ondone();
|
ondone();
|
||||||
};
|
};
|
||||||
|
|
||||||
CAM.addDogbones = function(poly, dist, reverse) {
|
CAM.addDogbones = function(poly, dist, reverse) {
|
||||||
if (Array.isArray(poly)) {
|
if (Array.isArray(poly)) {
|
||||||
return poly.forEach(p => CAM.addDogbones(p, dist));
|
return poly.forEach(p => CAM.addDogbones(p, dist));
|
||||||
}
|
}
|
||||||
|
|
@ -208,11 +209,11 @@
|
||||||
let adiff = lastsl.angleDiff(nextsl, true);
|
let adiff = lastsl.angleDiff(nextsl, true);
|
||||||
let bdiff = ((adiff < 0 ? (180 - adiff) : (180 + adiff)) / 2) + 180;
|
let bdiff = ((adiff < 0 ? (180 - adiff) : (180 + adiff)) / 2) + 180;
|
||||||
if (isCW && adiff > 45) {
|
if (isCW && adiff > 45) {
|
||||||
let newa = BASE.newSlopeFromAngle(lastsl.angle + bdiff);
|
let newa = base.newSlopeFromAngle(lastsl.angle + bdiff);
|
||||||
newpts.push(lastpt.projectOnSlope(newa, dist));
|
newpts.push(lastpt.projectOnSlope(newa, dist));
|
||||||
newpts.push(lastpt.clone());
|
newpts.push(lastpt.clone());
|
||||||
} else if (!isCW && adiff < -45) {
|
} else if (!isCW && adiff < -45) {
|
||||||
let newa = BASE.newSlopeFromAngle(lastsl.angle - bdiff);
|
let newa = base.newSlopeFromAngle(lastsl.angle - bdiff);
|
||||||
newpts.push(lastpt.projectOnSlope(newa, dist));
|
newpts.push(lastpt.projectOnSlope(newa, dist));
|
||||||
newpts.push(lastpt.clone());
|
newpts.push(lastpt.clone());
|
||||||
}
|
}
|
||||||
|
|
@ -226,14 +227,14 @@
|
||||||
if (poly.inner) {
|
if (poly.inner) {
|
||||||
CAM.addDogbones(poly.inner, dist, true);
|
CAM.addDogbones(poly.inner, dist, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CAM.traces = function(settings, widget, single) {
|
CAM.traces = function(settings, widget, single) {
|
||||||
if (widget.traces && widget.trace_single === single) {
|
if (widget.traces && widget.trace_single === single) {
|
||||||
// do no work if cached
|
// do no work if cached
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let slicer = new KIRI.cam_slicer(widget.getPoints(), {
|
let slicer = new kiri.cam_slicer(widget.getPoints(), {
|
||||||
zlist: true,
|
zlist: true,
|
||||||
zline: true
|
zline: true
|
||||||
});
|
});
|
||||||
|
|
@ -256,7 +257,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
BASE.polygons.flatten(data.tops,null,true).forEach(poly => {
|
base.polygons.flatten(data.tops,null,true).forEach(poly => {
|
||||||
poly.inner = null;
|
poly.inner = null;
|
||||||
poly.parent = null;
|
poly.parent = null;
|
||||||
let z = poly.getZ();
|
let z = poly.getZ();
|
||||||
|
|
@ -281,20 +282,20 @@
|
||||||
widget.traces = traces;
|
widget.traces = traces;
|
||||||
widget.trace_single = single;
|
widget.trace_single = single;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
function cutTabs(tabs, offset, z, inter) {
|
function cutTabs(tabs, offset, z, inter) {
|
||||||
tabs = tabs.filter(tab => z < tab.pos.z + tab.dim.z/2).map(tab => tab.off).flat();
|
tabs = tabs.filter(tab => z < tab.pos.z + tab.dim.z/2).map(tab => tab.off).flat();
|
||||||
return cutPolys(tabs, offset, z, false);
|
return cutPolys(tabs, offset, z, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function cutPolys(polys, offset, z, inter) {
|
function cutPolys(polys, offset, z, inter) {
|
||||||
let noff = [];
|
let noff = [];
|
||||||
offset.forEach(op => noff.appendAll( op.cut(POLY.union(polys, 0, true), inter) ));
|
offset.forEach(op => noff.appendAll( op.cut(POLY.union(polys, 0, true), inter) ));
|
||||||
return healPolys(noff);
|
return healPolys(noff);
|
||||||
}
|
}
|
||||||
|
|
||||||
function healPolys(noff) {
|
function healPolys(noff) {
|
||||||
if (noff.length > 1) {
|
if (noff.length > 1) {
|
||||||
let heal = 0;
|
let heal = 0;
|
||||||
// heal/rejoin open segments that share endpoints
|
// heal/rejoin open segments that share endpoints
|
||||||
|
|
@ -350,6 +351,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return noff;
|
return noff;
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,15 @@
|
||||||
/**
|
/**
|
||||||
* Slicing engine used by CAM
|
* Slicing engine used by CAM
|
||||||
*/
|
*/
|
||||||
(function() {
|
gapp.register("kiri-mode.cam.slicer", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { base, kiri } = root;
|
||||||
BASE = self.base,
|
const { config, util, polygons, newOrderedLine } = base;
|
||||||
CONF = BASE.config,
|
const { newSlice } = kiri;
|
||||||
UTIL = BASE.util,
|
|
||||||
POLY = BASE.polygons,
|
|
||||||
newSlice = KIRI.newSlice,
|
|
||||||
newOrderedLine = BASE.newOrderedLine;
|
|
||||||
|
|
||||||
class Slicer {
|
const POLY = polygons;
|
||||||
|
|
||||||
|
class Slicer {
|
||||||
constructor(points, options) {
|
constructor(points, options) {
|
||||||
this.options = {};
|
this.options = {};
|
||||||
if (points) {
|
if (points) {
|
||||||
|
|
@ -92,7 +90,7 @@
|
||||||
if (p1.z === p2.z && p2.z === p3.z) {
|
if (p1.z === p2.z && p2.z === p3.z) {
|
||||||
// detect zFlat faces to avoid slicing directly on them
|
// detect zFlat faces to avoid slicing directly on them
|
||||||
let zkey = p1.z.toFixed(5),
|
let zkey = p1.z.toFixed(5),
|
||||||
area = Math.abs(UTIL.area2(p1,p2,p3)) / 2;
|
area = Math.abs(util.area2(p1,p2,p3)) / 2;
|
||||||
if (!zFlat[zkey]) {
|
if (!zFlat[zkey]) {
|
||||||
zFlat[zkey] = area;
|
zFlat[zkey] = area;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -165,7 +163,7 @@
|
||||||
|
|
||||||
// if Z is supplied as an array, iterate and collect
|
// if Z is supplied as an array, iterate and collect
|
||||||
if (Array.isArray(z)) {
|
if (Array.isArray(z)) {
|
||||||
const mark = UTIL.time();
|
const mark = util.time();
|
||||||
const rarr = [];
|
const rarr = [];
|
||||||
z.forEach((zv,zi) => {
|
z.forEach((zv,zi) => {
|
||||||
const data = this.slice(zv, opt, zi, z.length, mark);
|
const data = this.slice(zv, opt, zi, z.length, mark);
|
||||||
|
|
@ -177,7 +175,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let znorm = z.toFixed(5),
|
let znorm = z.toFixed(5),
|
||||||
flatoff = UTIL.numOrDefault(opt.flatoff, 0.01),
|
flatoff = util.numOrDefault(opt.flatoff, 0.01),
|
||||||
onflat = this.zFlat[znorm],
|
onflat = this.zFlat[znorm],
|
||||||
edges = opt.edges || false,
|
edges = opt.edges || false,
|
||||||
over = opt.over || false,
|
over = opt.over || false,
|
||||||
|
|
@ -258,7 +256,7 @@
|
||||||
const hastops = !opt.genso || opt.notopok || (retn.tops && retn.tops.length) || edges;
|
const hastops = !opt.genso || opt.notopok || (retn.tops && retn.tops.length) || edges;
|
||||||
|
|
||||||
if (opt.each && haslines && hastops) {
|
if (opt.each && haslines && hastops) {
|
||||||
opt.each(retn, index, total, UTIL.time() - mark);
|
opt.each(retn, index, total, util.time() - mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
return haslines && hastops ? retn : null;
|
return haslines && hastops ? retn : null;
|
||||||
|
|
@ -399,9 +397,9 @@
|
||||||
array = array.map(v => v.round(5)).filter((e,i,a) => i < 1 || a[i-1] !== a[i]);
|
array = array.map(v => v.round(5)).filter((e,i,a) => i < 1 || a[i-1] !== a[i]);
|
||||||
return array.map(v => Math.abs(parseFloat(v.toFixed(5))));
|
return array.map(v => Math.abs(parseFloat(v.toFixed(5))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* given a point, append to the correct
|
* given a point, append to the correct
|
||||||
* 'where' objec tarray (on, over or under)
|
* 'where' objec tarray (on, over or under)
|
||||||
*
|
*
|
||||||
|
|
@ -409,18 +407,18 @@
|
||||||
* @param {number} z offset
|
* @param {number} z offset
|
||||||
* @param {Obejct} where
|
* @param {Obejct} where
|
||||||
*/
|
*/
|
||||||
function checkOverUnderOn(p, z, where) {
|
function checkOverUnderOn(p, z, where) {
|
||||||
let delta = p.z - z;
|
let delta = p.z - z;
|
||||||
if (Math.abs(delta) < CONF.precision_slice_z) { // on
|
if (Math.abs(delta) < config.precision_slice_z) { // on
|
||||||
where.on.push(p);
|
where.on.push(p);
|
||||||
} else if (delta < 0) { // under
|
} else if (delta < 0) { // under
|
||||||
where.under.push(p);
|
where.under.push(p);
|
||||||
} else { // over
|
} else { // over
|
||||||
where.over.push(p);
|
where.over.push(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a point over and under a z offset, calculate
|
* Given a point over and under a z offset, calculate
|
||||||
* and return the intersection point on that z plane
|
* and return the intersection point on that z plane
|
||||||
*
|
*
|
||||||
|
|
@ -429,7 +427,7 @@
|
||||||
* @param {number} z offset
|
* @param {number} z offset
|
||||||
* @returns {Point} intersection point
|
* @returns {Point} intersection point
|
||||||
*/
|
*/
|
||||||
function intersectPoints(over, under, z) {
|
function intersectPoints(over, under, z) {
|
||||||
let ip = [];
|
let ip = [];
|
||||||
for (let i = 0; i < over.length; i++) {
|
for (let i = 0; i < over.length; i++) {
|
||||||
for (let j = 0; j < under.length; j++) {
|
for (let j = 0; j < under.length; j++) {
|
||||||
|
|
@ -437,21 +435,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure points are unique with a cache/key algorithm
|
* Ensure points are unique with a cache/key algorithm
|
||||||
*/
|
*/
|
||||||
function getCachedPoint(phash, p) {
|
function getCachedPoint(phash, p) {
|
||||||
let cached = phash[p.key];
|
let cached = phash[p.key];
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
phash[p.key] = p;
|
phash[p.key] = p;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given two points and hints about their edges,
|
* Given two points and hints about their edges,
|
||||||
* return a new Line object with points sorted
|
* return a new Line object with points sorted
|
||||||
* lexicographically by key. This allows for future
|
* lexicographically by key. This allows for future
|
||||||
|
|
@ -464,16 +462,16 @@
|
||||||
* @param {boolean} [edge]
|
* @param {boolean} [edge]
|
||||||
* @returns {Line}
|
* @returns {Line}
|
||||||
*/
|
*/
|
||||||
function makeZLine(phash, p1, p2, coplanar, edge) {
|
function makeZLine(phash, p1, p2, coplanar, edge) {
|
||||||
p1 = getCachedPoint(phash, p1);
|
p1 = getCachedPoint(phash, p1);
|
||||||
p2 = getCachedPoint(phash, p2);
|
p2 = getCachedPoint(phash, p2);
|
||||||
let line = newOrderedLine(p1,p2);
|
let line = newOrderedLine(p1,p2);
|
||||||
line.coplanar = coplanar || false;
|
line.coplanar = coplanar || false;
|
||||||
line.edge = edge || false;
|
line.edge = edge || false;
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an array of input lines (line soup), find the path through
|
* Given an array of input lines (line soup), find the path through
|
||||||
* joining line ends that encompasses the greatest area without self
|
* joining line ends that encompasses the greatest area without self
|
||||||
* interesection. Eliminate used points and repeat. Unjoined lines
|
* interesection. Eliminate used points and repeat. Unjoined lines
|
||||||
|
|
@ -483,16 +481,16 @@
|
||||||
* @param {number} [index]
|
* @param {number} [index]
|
||||||
* @returns {Array}
|
* @returns {Array}
|
||||||
*/
|
*/
|
||||||
function connectLines(input, opt = {}, debug) {
|
function connectLines(input, opt = {}, debug) {
|
||||||
// map points to all other points they're connected to
|
// map points to all other points they're connected to
|
||||||
let CONF = BASE.config,
|
let config = base.config,
|
||||||
pmap = {},
|
pmap = {},
|
||||||
points = [],
|
points = [],
|
||||||
output = [],
|
output = [],
|
||||||
connect = [],
|
connect = [],
|
||||||
search = 1,
|
search = 1,
|
||||||
nextMod = 1,
|
nextMod = 1,
|
||||||
bridge = CONF.bridgeLineGapDistance,
|
bridge = config.bridgeLineGapDistance,
|
||||||
minPoly = opt.openok ? 2 : 3,
|
minPoly = opt.openok ? 2 : 3,
|
||||||
p1, p2;
|
p1, p2;
|
||||||
|
|
||||||
|
|
@ -611,7 +609,7 @@
|
||||||
// it gets more complicated with multiple possible output paths
|
// it gets more complicated with multiple possible output paths
|
||||||
if (closed > 1 && open === 0) {
|
if (closed > 1 && open === 0) {
|
||||||
// add polygon to path (for area sorting)
|
// add polygon to path (for area sorting)
|
||||||
paths.forEach(function(path) { path.poly = BASE.newPolygon().addPoints(path) });
|
paths.forEach(function(path) { path.poly = base.newPolygon().addPoints(path) });
|
||||||
|
|
||||||
// sort descending by area VS (length below -- better in most cases)
|
// sort descending by area VS (length below -- better in most cases)
|
||||||
// paths.sort(function(a,b) { return b.poly.area() - a.poly.area() });
|
// paths.sort(function(a,b) { return b.poly.area() - a.poly.area() });
|
||||||
|
|
@ -633,7 +631,7 @@
|
||||||
if (longest.open) {
|
if (longest.open) {
|
||||||
connect.push(longest);
|
connect.push(longest);
|
||||||
} else {
|
} else {
|
||||||
emit(BASE.newPolygon().addPoints(longest));
|
emit(base.newPolygon().addPoints(longest));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -685,7 +683,7 @@
|
||||||
|
|
||||||
if (!bridge) {
|
if (!bridge) {
|
||||||
if (opt.openok) {
|
if (opt.openok) {
|
||||||
emit(BASE.newPolygon().addPoints(array).setOpen());
|
emit(base.newPolygon().addPoints(array).setOpen());
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -722,15 +720,15 @@
|
||||||
merged++;
|
merged++;
|
||||||
// tail meets head (closed)
|
// tail meets head (closed)
|
||||||
if (close(array[0], last)) {
|
if (close(array[0], last)) {
|
||||||
emit(BASE.newPolygon().addPoints(array));
|
emit(base.newPolygon().addPoints(array));
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no more closest polys (open set)
|
// no more closest polys (open set)
|
||||||
if (opt.openok) {
|
if (opt.openok) {
|
||||||
emit(BASE.newPolygon().addPoints(array).setOpen());
|
emit(base.newPolygon().addPoints(array).setOpen());
|
||||||
} else {
|
} else {
|
||||||
emit(BASE.newPolygon().addPoints(array));
|
emit(base.newPolygon().addPoints(array));
|
||||||
}
|
}
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
|
|
@ -738,9 +736,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eliminate duplicate lines and interior-only lines (coplanar)
|
* eliminate duplicate lines and interior-only lines (coplanar)
|
||||||
*
|
*
|
||||||
* lines are sorted using lexicographic point keys such that
|
* lines are sorted using lexicographic point keys such that
|
||||||
|
|
@ -751,7 +749,7 @@
|
||||||
* @param {Line[]} lines
|
* @param {Line[]} lines
|
||||||
* @returns {Line[]}
|
* @returns {Line[]}
|
||||||
*/
|
*/
|
||||||
function removeDuplicateLines(lines, debug) {
|
function removeDuplicateLines(lines, debug) {
|
||||||
let output = [],
|
let output = [],
|
||||||
tmplines = [],
|
tmplines = [],
|
||||||
points = [],
|
points = [],
|
||||||
|
|
@ -804,7 +802,7 @@
|
||||||
// find new endpoints that are not shared point
|
// find new endpoints that are not shared point
|
||||||
let p1 = l1.p1 != point ? l1.p1 : l1.p2,
|
let p1 = l1.p1 != point ? l1.p1 : l1.p2,
|
||||||
p2 = l2.p1 != point ? l2.p1 : l2.p2,
|
p2 = l2.p1 != point ? l2.p1 : l2.p2,
|
||||||
newline = BASE.newOrderedLine(p1,p2);
|
newline = base.newOrderedLine(p1,p2);
|
||||||
// remove deleted lines from associated points
|
// remove deleted lines from associated points
|
||||||
p1.group.remove(l1);
|
p1.group.remove(l1);
|
||||||
p1.group.remove(l2);
|
p1.group.remove(l2);
|
||||||
|
|
@ -840,11 +838,11 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
Slicer.checkOverUnderOn = checkOverUnderOn;
|
Slicer.checkOverUnderOn = checkOverUnderOn;
|
||||||
Slicer.intersectPoints = intersectPoints;
|
Slicer.intersectPoints = intersectPoints;
|
||||||
|
|
||||||
self.kiri.cam_slicer = Slicer;
|
kiri.cam_slicer = Slicer;
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,15 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
gapp.register("kiri-mode.cam.tools", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { kiri } = root;
|
||||||
BASE = self.base,
|
const { driver } = kiri;
|
||||||
UTIL = BASE.util,
|
const { CAM } = driver;
|
||||||
HPI = Math.PI/2,
|
|
||||||
CAM = KIRI.driver.CAM;
|
|
||||||
|
|
||||||
class Tool {
|
const HPI = Math.PI/2;
|
||||||
|
|
||||||
|
class Tool {
|
||||||
constructor(settings, id, number) {
|
constructor(settings, id, number) {
|
||||||
if (number >= 0) {
|
if (number >= 0) {
|
||||||
this.tool = settings.tools.filter(tool => tool.number == number)[0];
|
this.tool = settings.tools.filter(tool => tool.number == number)[0];
|
||||||
|
|
@ -125,11 +125,12 @@
|
||||||
};
|
};
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CAM.Tool = Tool;
|
CAM.Tool = Tool;
|
||||||
CAM.getToolDiameter = function(settings, id) {
|
|
||||||
|
CAM.getToolDiameter = function(settings, id) {
|
||||||
return new CAM.Tool(settings, id).fluteDiameter();
|
return new CAM.Tool(settings, id).fluteDiameter();
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,18 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
gapp.register("kiri-mode.cam.tools", [], (root, exports) => {
|
||||||
|
|
||||||
let KIRI = self.kiri,
|
const { base, kiri } = root;
|
||||||
BASE = self.base,
|
const { driver, newSlice } = kiri;
|
||||||
CAM = KIRI.driver.CAM,
|
const { CAM } = driver;
|
||||||
PRO = CAM.process,
|
const { polygons, newLine, newSlope, newPoint, newPolygon } = base;
|
||||||
POLY = BASE.polygons,
|
|
||||||
RAD2DEG = 180 / Math.PI,
|
|
||||||
newSlice = KIRI.newSlice,
|
|
||||||
newLine = BASE.newLine,
|
|
||||||
newSlope = BASE.newSlope,
|
|
||||||
newPoint = BASE.newPoint,
|
|
||||||
newPolygon = BASE.newPolygon;
|
|
||||||
|
|
||||||
class Topo {
|
const PRO = CAM.process;
|
||||||
|
const POLY = polygons;
|
||||||
|
const RAD2DEG = 180 / Math.PI;
|
||||||
|
|
||||||
|
class Topo {
|
||||||
constructor(opt = {}) {
|
constructor(opt = {}) {
|
||||||
let { state, contour, onupdate, ondone } = opt;
|
let { state, contour, onupdate, ondone } = opt;
|
||||||
let { widget, settings, tshadow, center, tabs, color } = opt.state;
|
let { widget, settings, tshadow, center, tabs, color } = opt.state;
|
||||||
|
|
@ -384,7 +381,7 @@
|
||||||
ondone(newslices);
|
ondone(newslices);
|
||||||
}
|
}
|
||||||
|
|
||||||
let slicer = new KIRI.cam_slicer(widget.getPoints(), {
|
let slicer = new kiri.cam_slicer(widget.getPoints(), {
|
||||||
swapX: true, emptyok: true, notopok: true
|
swapX: true, emptyok: true, notopok: true
|
||||||
});
|
});
|
||||||
let sindex = slicer.interval(resolution);
|
let sindex = slicer.interval(resolution);
|
||||||
|
|
@ -398,8 +395,8 @@
|
||||||
|
|
||||||
processSlices(slices.filter(s => s.lines).map(data => data.slice));
|
processSlices(slices.filter(s => s.lines).map(data => data.slice));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CAM.Topo = Topo;
|
CAM.Topo = Topo;
|
||||||
|
|
||||||
})();
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue