diff --git a/src/dev/cam/Sienci.LongMill b/src/dev/cam/Sienci.LongMill
index e0324842..65a854f7 100644
--- a/src/dev/cam/Sienci.LongMill
+++ b/src/dev/cam/Sienci.LongMill
@@ -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
+ }
}
diff --git a/src/kiri/codec.js b/src/kiri/codec.js
index ec9d6a18..bc473e8c 100644
--- a/src/kiri/codec.js
+++ b/src/kiri/codec.js
@@ -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
};
};
diff --git a/src/kiri/conf.js b/src/kiri/conf.js
index 37f01a22..b2b691ad 100644
--- a/src/kiri/conf.js
+++ b/src/kiri/conf.js
@@ -437,7 +437,9 @@
camContourXOn: true,
camContourYOn: true,
camTraceTool: 1000,
+ camTraceType: "follow",
camTraceSpeed: 250,
+ camTracePlunge: 200,
camDrillTool: 1000,
camDrillSpindle: 1000,
camDrillDownSpeed: 250,
diff --git a/src/kiri/init.js b/src/kiri/init.js
index 183875d0..26fd1bf5 100644
--- a/src/kiri/init.js
+++ b/src/kiri/init.js
@@ -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:''})),
(UI.traceDun = UC.newButton(undefined, onButtonClick, {icon:''})),
diff --git a/src/kiri/main.js b/src/kiri/main.js
index 29df95e2..64e7b798 100644
--- a/src/kiri/main.js
+++ b/src/kiri/main.js
@@ -177,6 +177,11 @@
{ name: "300" },
{ name: "400" },
{ name: "500" }
+ ],
+ trace: [
+ { name: "follow" },
+ { name: "out" },
+ { name: "in" }
]
};
diff --git a/src/mode/cam/client.js b/src/mode/cam/client.js
index 20a7ee70..1f7221e0 100644
--- a/src/mode/cam/client.js
+++ b/src/mode/cam/client.js
@@ -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("<esc> 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("<esc> 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)};
diff --git a/src/mode/cam/driver.js b/src/mode/cam/driver.js
index e7809691..fc7a0a69 100644
--- a/src/mode/cam/driver.js
+++ b/src/mode/cam/driver.js
@@ -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
}})));
};
diff --git a/src/mode/cam/prepare.js b/src/mode/cam/prepare.js
index b560b255..7458f003 100644
--- a/src/mode/cam/prepare.js
+++ b/src/mode/cam/prepare.js
@@ -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);
diff --git a/src/mode/cam/slice.js b/src/mode/cam/slice.js
index c2fccc12..423780b3 100644
--- a/src/mode/cam/slice.js
+++ b/src/mode/cam/slice.js
@@ -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 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
diff --git a/src/mode/fdm/client.js b/src/mode/fdm/client.js
index eec69ccb..20caef2e 100644
--- a/src/mode/fdm/client.js
+++ b/src/mode/fdm/client.js
@@ -51,7 +51,7 @@
}
});
api.event.on("fdm.supports.add", func.sadd = () => {
- alert = api.show.alert("<esc> 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 = () => {
diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js
index 132613e8..fe09b8bb 100644
--- a/web/kiri/lang/en.js
+++ b/web/kiri/lang/en.js
@@ -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",