checkpoint tracing

This commit is contained in:
Stewart Allen 2020-12-01 18:19:28 -05:00
commit 0ff23ef8cd
11 changed files with 188 additions and 82 deletions

View file

@ -5,8 +5,8 @@
"pre":[
"G21 ; set units to MM (required)",
"G90 ; absolute position mode (required)",
"G0 F6000 ; default rapid move speed",
"G1 F1500 ; default cutting speed"
"G0 F6000 ; default rapid move speed",
"G1 F1500 ; default cutting speed"
],
"post":[
"M30 ; program end"
@ -14,11 +14,15 @@
"tool-change":[
"M6 T{tool} ; change tool to '{tool_name}'"
],
"dwell":[
"G4 P{time} ; dwell for {time}ms"
],
"settings": {
"bed_width": 760,
"bed_depth": 760
}
"dwell":[
"G4 P{time} ; dwell for {time}ms"
],
"settings": {
"ximage_url": "https://static.grid.space/kiri/siencilabs.png",
"image_url": "https://static.grid.space/kiri/longmill.png",
"image_scale": 200,
"image_anchor": 8,
"bed_width": 760,
"bed_depth": 760
}
}

View file

@ -303,11 +303,11 @@
type: 'poly',
id: this.id,
array: encodePointArray(this.points, state),
open: this.isOpen(),
inner: encode(this.inner, state),
parent: encode(this.parent, state),
depth: this.depth,
color: this.color
color: this.color,
open: this.open
};
};

View file

@ -437,7 +437,9 @@
camContourXOn: true,
camContourYOn: true,
camTraceTool: 1000,
camTraceType: "follow",
camTraceSpeed: 250,
camTracePlunge: 200,
camDrillTool: 1000,
camDrillSpindle: 1000,
camDrillDownSpeed: 250,

View file

@ -1610,10 +1610,12 @@
camContourSep: UC.newBlank({class:"pop-sep"}),
camContourYOn: UC.newBoolean(LANG.cf_liny_s, onBooleanClick, {title:LANG.cf_liny_l, modes:CAM}),
camContourXOn: UC.newBoolean(LANG.cf_linx_s, onBooleanClick, {title:LANG.cf_linx_l, modes:CAM}),
camTracing: UC.newGroup(LANG.cu_menu, null, {modes:CAM, marker:true}),
camTraceTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
camTraceSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
camTraceSep: UC.newBlank({class:"pop-sep"}),
camTracing: UC.newGroup(LANG.cu_menu, null, {modes:CAM, marker:true}),
camTraceTool: UC.newSelect(LANG.cc_tool, {modes:CAM}),
camTraceType: UC.newSelect(LANG.cu_type_s, {title:LANG.cu_type_l, modes:CAM}, "trace"),
camTraceSpeed: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, modes:CAM}),
camTracePlunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toFloat, modes:CAM, units:true}),
camTraceSep: UC.newBlank({class:"pop-sep"}),
camTraceSelect: UC.newRow([
(UI.traceAdd = UC.newButton(undefined, onButtonClick, {icon:'<i class="fas fa-plus"></i>'})),
(UI.traceDun = UC.newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),

View file

@ -177,6 +177,11 @@
{ name: "300" },
{ name: "400" },
{ name: "500" }
],
trace: [
{ name: "follow" },
{ name: "out" },
{ name: "in" }
]
};

View file

@ -15,6 +15,7 @@
isCamMode,
isParsed,
camStock,
current,
API, FDM, SPACE, STACKS, MODES, VIEWS, UI, UC;
let zaxis = {x: 0, y: 0, z: 1},
@ -41,6 +42,8 @@
func.tabClear();
func.traceDone();
}
// do not persist traces across page reloads
func.traceClear();
});
api.event.on("view.set", (mode) => {
@ -52,6 +55,7 @@
});
api.event.on("settings.saved", (settings) => {
current = settings;
const proc = settings.process;
let hasTabs = false;
let hasTraces = false;
@ -138,7 +142,7 @@
let showTab, lastTab, tab, iw, ic;
api.event.on("cam.tabs.add", func.tabAdd = () => {
func.traceDone();
alert = api.show.alert("&lt;esc&gt; key cancels editing tabs");
alert = api.show.alert("[esc] key cancels tab editing");
api.feature.hover = true;
func.hover = func.tabHover;
func.hoverUp = func.tabHoverUp;
@ -228,9 +232,11 @@
return;
}
func.tabDone();
alert = api.show.alert("&lt;esc&gt; key cancels editing traces");
alert = api.show.alert("analyzing parts...");
traceOn = true;
KIRI.client.traces(() => {
api.hide.alert(alert);
alert = api.show.alert("[esc] key cancels trace editing");
KIRI.api.widgets.opacity(0.5);
KIRI.api.widgets.for(widget => {
let stack = new KIRI.Stack(widget.mesh);
@ -239,6 +245,12 @@
let layers = new KIRI.Layers();
layers.setLayer("trace", {line: 0x88aa55}, false).addPoly(poly);
stack.addLayers(layers);
stack.meshes.forEach(mesh => {
mesh.trace = {widget, poly};
});
// reset so each mesh array is new for the layer
widget.adds.appendAll(stack.meshes);
stack.meshes = [];
});
// for (let [key, val] of Object.entries(widget.sindex)) {
// console.log('sindex', {key, val});
@ -246,7 +258,6 @@
// layers.setLayer("sindex", {line: 0x55aa88}, false).addPolys(val);
// stack.addLayers(layers);
// }
widget.adds.appendAll(stack.meshes);
});
});
api.feature.hover = true;
@ -264,8 +275,10 @@
api.feature.hover = false;
api.feature.hoverAdds = false;
KIRI.api.widgets.for(widget => {
widget.adds.removeAll(widget.trace_stack.meshes);
widget.trace_stack.destroy();
if (widget.trace_stack) {
widget.adds.removeAll(widget.trace_stack.meshes);
widget.trace_stack.destroy();
}
});
});
api.event.on("cam.trace.clear", func.traceClear = () => {
@ -286,20 +299,49 @@
lastTrace = null;
return;
}
// if (data.ints.length === 2) {
// console.log(data.ints);
// }
lastTrace = data.int.object;
let material = lastTrace.material[0];
let color = material.color;
let {r, g, b} = color;
material.colorSave = {r, g, b};
color.r = 255;
color.r = 1;
color.g = 0;
color.b = 0;
};
func.traceHoverUp = function(int) {
if (int) console.log({traceHoverUp: int});
if (!int) return;
console.log({traceHoverUp: int});
func.traceToggle(int.object);
};
func.traceToggle = function(obj) {
let material = obj.material[0];
let { color, colorSave } = material;
let { widget, poly } = obj.trace;
let wannot = API.widgets.annotate(widget.id);
let atrace = wannot.trace = wannot.trace || [];
let wtrace = widget.trace = widget.trace || [];
let process = current.process;
obj.selected = !obj.selected;
if (obj.selected) {
color.r = colorSave.r = 0.9;
color.g = colorSave.g = 0;
color.b = colorSave.b = 0.1;
poly.traceInfo = {
tool: process.camTraceTool,
speed: process.camTraceSpeed,
plunge: process.camTracePlunge,
path: KIRI.codec.encode(poly)
};
wtrace.push(poly);
atrace.push(poly.traceInfo);
} else {
color.r = colorSave.r = 0x88/255;
color.g = colorSave.g = 0xaa/255;
color.b = colorSave.b = 0x55/255;
wtrace.remove(poly);
atrace.remove(poly.traceInfo);
}
API.conf.save();
};
// COMMON TAB/TRACE EVENT HANDLERS
@ -326,6 +368,10 @@
return;
}
const {widget, x, y, z} = rot;
if (traceOn) {
func.traceDone();
}
clearTraces(widget);
if (x || y) {
clearTabs(widget);
} else {
@ -414,6 +460,17 @@
delete API.widgets.annotate(widget.id).tab;
}
function clearTraces(widget) {
Object.values(widget.traces || {}).forEach(rec => {
console.log('clear',rec);
// widget.adds.remove(rec.box);
// widget.mesh.remove(rec.box);
});
widget.traces = {};
widget.trace_stack = null;
delete API.widgets.annotate(widget.id).trace;
}
function addbox() { return FDM.addbox(...arguments)};
function delbox() { return FDM.delbox(...arguments)};

View file

@ -32,7 +32,7 @@
send("traces", { settings }, output => {
KIRI.codec.decode(output).forEach(rec => {
widgets[rec.id].traces = rec.traces;
widgets[rec.id].sindex = rec.sindex;
// widgets[rec.id].sindex = rec.sindex;
});
ondone(true);
});
@ -46,7 +46,7 @@
send.done(KIRI.codec.encode(widgets.map(widget => {return {
id: widget.id,
traces: widget.traces,
sindex: widget.sindex
// sindex: widget.sindex
}})));
};

View file

@ -432,6 +432,19 @@
}
}
break;
case PRO.TRACE:
console.log({prep_trace: slice});
let { tool, speed, plunge, path } = slice.camTrace;
setTool(tool, speed, plunge);
let traceTool = new CAM.Tool(settings, tool);
let traceToolDiam = traceTool.fluteDiameter();
slice.camLines.forEach(poly => {
poly.forEachPoint(function(point, pidx) {
camOut(point.clone(), pidx > 0);
}, !poly.open);
});
newLayer();
break;
case PRO.DRILL:
setTool(process.camDrillTool, process.camDrillDownSpeed, process.camDrillDownSpeed);
depthData.drill.appendAll(slice.camLines);

View file

@ -45,7 +45,7 @@
procContour = procContourX || procContourY,
procDrill = proc.camDrillingOn && proc.camDrillDown && proc.camDrillDownSpeed,
procDrillReg = proc.camDrillReg,
procTrace = proc.camTraceOn,
// procTrace = proc.camTraceOn,
roughDown = procRough ? proc.camRoughDown : Infinity,
outlineDown = procOutline ? proc.camOutlineDown : Infinity,
sliceDepth = Math.max(0.1, Math.min(roughDown, outlineDown) / 3),
@ -66,16 +66,16 @@
if (tabs) {
// make tab polygons
tabs.forEach(tab => {
let zero = BASE.newPoint(0,0,0);
let point = BASE.newPoint(tab.pos.x, tab.pos.y, tab.pos.z);
let poly = BASE.newPolygon().centerRectangle(zero, tab.dim.x, tab.dim.y);
let tslice = KIRI.newSlice(0);
let zero = newPoint(0,0,0);
let point = newPoint(tab.pos.x, tab.pos.y, tab.pos.z);
let poly = newPolygon().centerRectangle(zero, tab.dim.x, tab.dim.y);
let tslice = newSlice(0);
let m4 = new THREE.Matrix4().makeRotationFromQuaternion(
new THREE.Quaternion(tab.rot._x, tab.rot._y, tab.rot._z, tab.rot._w)
);
poly.points = poly.points
.map(p => new THREE.Vector3(p.x,p.y,p.z).applyMatrix4(m4))
.map(v => BASE.newPoint(v.x, v.y, v.z));
.map(v => newPoint(v.x, v.y, v.z));
poly.move(point);
tab.poly = poly;
// tslice.output().setLayer("tabs", 0xff0000).addPoly(poly);
@ -452,8 +452,8 @@
// offset.xout(`slice ${slice.z}`);
slice.camLines = offset;
if (true) slice.output()
.setLayer("slice", {line: 0xaaaa00}, true)
if (false) slice.output()
.setLayer("slice", {line: 0xaaaa00}, false)
.addPolys(slice.topPolys())
slice.output()
.setLayer("outline", {face: 0, line: 0})
@ -484,13 +484,27 @@
}
// generate tracing offsets from chosen features
if (procTrace) {
// todo
// let proc = settings.process;
// let traceTool = new CAM.Tool(settings, proc.camTraceTool);
// let traceToolDiam = traceTool.fluteDiameter();
// widget.maxToolDiam = Math.max(maxToolDiam, traceToolDiam);
// slice.camMode = PRO.TRACE;
{
let proc = settings.process;
let traces = (settings.widget[widget.id] || {}).trace || [];
traces.forEach(trace => {
console.log({trace});
let { tool, path } = trace;
let traceTool = new CAM.Tool(settings, tool);
let traceToolDiam = traceTool.fluteDiameter();
let slice = newSlice();
let poly = KIRI.codec.decode(path);
slice.addTop(poly);
slice.camMode = PRO.TRACE;
slice.camLines = [ poly ];
slice.camTrace = trace;
if (true) slice.output()
.setLayer("trace", {line: 0xaa00aa}, false)
.addPolys(slice.topPolys())
sliceAll.push(slice);
maxToolDiam = Math.max(maxToolDiam, traceToolDiam);
console.log({slice});
});
}
if (procDrill) {
@ -537,55 +551,62 @@
.sort((a,b) => b - a);
// create shadow
let sindex = {};
let shadow = [];
let sindices = indices.map((v,i) => v > 0 ? v : v + 0.005 );
slicer.slice(sindices, { each: (data, index, total) => {
shadow = POLY.union(shadow.slice().appendAll(data.tops), 0, true);
POLY.setZ(shadow, data.z);
sindex[index] = shadow;
}, flatoff: 0 });
// let sindex = {};
// let shadow = [];
// let sindices = indices.map((v,i) => v > 0 ? v : v + 0.005);
// slicer.slice(sindices, { each: (data, index, total) => {
// shadow = POLY.union(shadow.slice().appendAll(data.tops), 0, true);
// POLY.setZ(shadow, data.z);
// sindex[index] = shadow;
// }, flatoff: 0 });
let traces = [];
// find and trim polys (including open) to shadow
let oneach = (data, index, total) => {
BASE.polygons.flatten(data.tops,null,true).forEach(poly => {
poly.inner = null;
poly.parent = null;
let z = poly.getZ();
for (let i=0, il=traces.length; i<il; i++) {
let trace = traces[i];
// only compare polys farther apart in Z
if (Math.abs(z - trace.getZ()) > 0.01) {
continue;
}
// do not add duplicates
if (traces[i].isEquivalent(poly)) {
return;
}
}
traces.push(poly);
return;
// do trimming
let trimto = sindex[index];
if (!trimto) {
traces.push(poly);
return;
}
trimto = trimto.clone(true);
if (poly.open) {
let cuts = poly.cut(trimto);
if (cuts.length) {
traces.appendAll(cuts);
} else {
traces.push(poly);
}
} else {
let limit = 1000;
while (trimto.length && limit-- > 0) {
let trim = trimto.shift();
let mask = poly.mask(trim, true);
if (mask) {
trimto.appendAll(mask);
} else {
traces.push(poly);
}
}
if (limit === 1000) {
traces.push(poly);
}
}
// let trimto = sindex[index];
// if (!trimto) {
// traces.push(poly);
// return;
// }
// trimto = trimto.clone(true);
// if (poly.open) {
// let cuts = poly.cut(trimto);
// if (cuts.length) {
// traces.appendAll(cuts);
// } else {
// traces.push(poly);
// }
// } else {
// let limit = 1000;
// while (trimto.length && limit-- > 0) {
// let trim = trimto.shift();
// let mask = poly.mask(trim, true);
// if (mask) {
// trimto.appendAll(mask);
// } else {
// traces.push(poly);
// }
// }
// if (limit === 1000) {
// traces.push(poly);
// }
// }
});
};
let opts = { each: oneach, over: false, flatoff: 0, edges: true, openok: true };
@ -593,7 +614,7 @@
opts.over = true;
slicer.slice(indices, opts);
widget.traces = traces;
widget.sindex = sindex;
// widget.sindex = sindex;
};
// drilling op

View file

@ -51,7 +51,7 @@
}
});
api.event.on("fdm.supports.add", func.sadd = () => {
alert = api.show.alert("&lt;esc&gt; key cancels editing supports");
alert = api.show.alert("[esc] key cancels support editing");
api.feature.hover = true;
});
api.event.on("fdm.supports.done", func.sdone = () => {

View file

@ -311,8 +311,10 @@ kiri.lang['en-us'] = {
cf_liny_s: "enable x pass",
cf_liny_l: "linear x-axis finishing",
// CNC CONTOUR
// CNC TRACE
cu_menu: "trace",
cu_type_s: "type",
cu_type_l: "follow = tool tip follows line\nright or left = tool tip\nfollows line offset by tool radius",
// CNC DRILLING
cd_menu: "drill",