complete threading support for all slicing ops. add pocket surface selection criteria
This commit is contained in:
parent
70c00e1bab
commit
fa6d07ed15
9 changed files with 62 additions and 27 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
Full docs @ https://docs.grid.space/projects/kiri-moto
|
Full docs @ https://docs.grid.space/projects/kiri-moto
|
||||||
|
|
||||||
|
|
||||||
# Release 3.8
|
# Release 3.8 (2023-01-21)
|
||||||
|
|
||||||
* update server-side sample module code
|
* update server-side sample module code
|
||||||
* various fixes and improvements to CAM indexing
|
* various fixes and improvements to CAM indexing
|
||||||
|
|
@ -23,6 +23,7 @@ Full docs @ https://docs.grid.space/projects/kiri-moto
|
||||||
* CAM fix tracing nested polyline offset ordering
|
* CAM fix tracing nested polyline offset ordering
|
||||||
* CAM refactor of contouring yields 2x - 20x speedup
|
* CAM refactor of contouring yields 2x - 20x speedup
|
||||||
* CAM update traces to async slicing, fix use with flip
|
* CAM update traces to async slicing, fix use with flip
|
||||||
|
* CAM add threading support for all slicing ops
|
||||||
|
|
||||||
- refactor object/group storage model in Mesh:Tool
|
- refactor object/group storage model in Mesh:Tool
|
||||||
- add omit pocket to rough and outline
|
- add omit pocket to rough and outline
|
||||||
|
|
@ -85,6 +86,7 @@ Full docs @ https://docs.grid.space/projects/kiri-moto
|
||||||
* add CAM Z bottom inversion option to flip operator
|
* add CAM Z bottom inversion option to flip operator
|
||||||
* add CAM custom gcode operator (can be used for pausing, too)
|
* add CAM custom gcode operator (can be used for pausing, too)
|
||||||
* add CAM z extend option on registration op independent of "Z Thru" global
|
* add CAM z extend option on registration op independent of "Z Thru" global
|
||||||
|
* add CAM pocket surface selection filter by angle
|
||||||
* add optional CAM operation notes (helps with many similar ops)
|
* add optional CAM operation notes (helps with many similar ops)
|
||||||
* add option to limit CAM trace ops to Z bottom limit (when in use)
|
* add option to limit CAM trace ops to Z bottom limit (when in use)
|
||||||
* extend url loading of workspaces to all formats
|
* extend url loading of workspaces to all formats
|
||||||
|
|
|
||||||
|
|
@ -844,6 +844,7 @@ CAM.init = function(kiri, api) {
|
||||||
func.clearPops();
|
func.clearPops();
|
||||||
alert = api.show.alert("analyzing surfaces...", 1000);
|
alert = api.show.alert("analyzing surfaces...", 1000);
|
||||||
let surfaces = poppedRec.surfaces;
|
let surfaces = poppedRec.surfaces;
|
||||||
|
let radians = poppedRec.follow * DEG2RAD;
|
||||||
CAM.surface_prep(currentIndex * RAD2DEG, () => {
|
CAM.surface_prep(currentIndex * RAD2DEG, () => {
|
||||||
api.hide.alert(alert);
|
api.hide.alert(alert);
|
||||||
alert = api.show.alert("[esc] cancels surface editing");
|
alert = api.show.alert("[esc] cancels surface editing");
|
||||||
|
|
@ -851,7 +852,7 @@ CAM.init = function(kiri, api) {
|
||||||
let widget = api.widgets.forid(wid);
|
let widget = api.widgets.forid(wid);
|
||||||
if (widget && arr.length)
|
if (widget && arr.length)
|
||||||
for (let faceid of arr) {
|
for (let faceid of arr) {
|
||||||
CAM.surface_toggle(widget, faceid, faceids => {
|
CAM.surface_toggle(widget, faceid, radians, faceids => {
|
||||||
// surfaces[widget.id] = faceids;
|
// surfaces[widget.id] = faceids;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -864,7 +865,7 @@ CAM.init = function(kiri, api) {
|
||||||
let min = Math.min(face.a, face.b, face.c);
|
let min = Math.min(face.a, face.b, face.c);
|
||||||
let faceid = min / 3;
|
let faceid = min / 3;
|
||||||
let widget = lastWidget = obj.object.widget;
|
let widget = lastWidget = obj.object.widget;
|
||||||
CAM.surface_toggle(widget, faceid, faceids => {
|
CAM.surface_toggle(widget, faceid, radians, faceids => {
|
||||||
surfaces[widget.id] = faceids;
|
surfaces[widget.id] = faceids;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -1338,10 +1339,11 @@ CAM.init = function(kiri, api) {
|
||||||
plunge: 'camPocketPlunge',
|
plunge: 'camPocketPlunge',
|
||||||
expand: 'camPocketExpand',
|
expand: 'camPocketExpand',
|
||||||
smooth: 'camPocketSmooth',
|
smooth: 'camPocketSmooth',
|
||||||
refine: 'cmaPocketRefine',
|
refine: 'camPocketRefine',
|
||||||
|
follow: 'camPocketFollow',
|
||||||
contour: 'camPocketContour',
|
contour: 'camPocketContour',
|
||||||
engrave: 'camPocketEngrave',
|
engrave: 'camPocketEngrave',
|
||||||
outline: 'cmaPocketOutline',
|
outline: 'camPocketOutline',
|
||||||
tolerance: 'camTolerance',
|
tolerance: 'camTolerance',
|
||||||
}).inputs = {
|
}).inputs = {
|
||||||
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
|
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
|
||||||
|
|
@ -1354,8 +1356,9 @@ CAM.init = function(kiri, api) {
|
||||||
sep: UC.newBlank({class:"pop-sep"}),
|
sep: UC.newBlank({class:"pop-sep"}),
|
||||||
expand: UC.newInput(LANG.cp_xpnd_s, {title:LANG.cp_xpnd_l, convert:UC.toFloat, units:true, show:() => !poppedRec.contour}),
|
expand: UC.newInput(LANG.cp_xpnd_s, {title:LANG.cp_xpnd_l, convert:UC.toFloat, units:true, show:() => !poppedRec.contour}),
|
||||||
refine: UC.newInput(LANG.cp_refi_s, {title:LANG.cp_refi_l, convert:UC.toInt, show:() => poppedRec.contour}),
|
refine: UC.newInput(LANG.cp_refi_s, {title:LANG.cp_refi_l, convert:UC.toInt, show:() => poppedRec.contour}),
|
||||||
smooth: UC.newInput(LANG.cp_smoo_s, {title:LANG.cp_smoo_l, convert:UC.toFloat, units:true}),
|
smooth: UC.newInput(LANG.cp_smoo_s, {title:LANG.cp_smoo_l, convert:UC.toInt}),
|
||||||
tolerance: UC.newInput(LANG.ou_toll_s, {title:LANG.ou_toll_l, convert:UC.toFloat, bound:UC.bound(0,10.0), units:true, round:4, show:() => poppedRec.contour}),
|
tolerance: UC.newInput(LANG.ou_toll_s, {title:LANG.ou_toll_l, convert:UC.toFloat, bound:UC.bound(0,10.0), units:true, round:4, show:() => poppedRec.contour}),
|
||||||
|
follow: UC.newInput(LANG.cp_foll_s, {title:LANG.cp_foll_l, convert:UC.toFloat}),
|
||||||
sep: UC.newBlank({class:"pop-sep"}),
|
sep: UC.newBlank({class:"pop-sep"}),
|
||||||
contour: UC.newBoolean(LANG.cp_cont_s, undefined, {title:LANG.cp_cont_s}),
|
contour: UC.newBoolean(LANG.cp_cont_s, undefined, {title:LANG.cp_cont_s}),
|
||||||
outline: UC.newBoolean(LANG.cp_outl_s, undefined, {title:LANG.cp_outl_l, show:() => !poppedRec.contour}),
|
outline: UC.newBoolean(LANG.cp_outl_s, undefined, {title:LANG.cp_outl_l, show:() => !poppedRec.contour}),
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ kiri.load(api => {
|
||||||
widget.selectFaces(Object.values(widget._surfaces).flat());
|
widget.selectFaces(Object.values(widget._surfaces).flat());
|
||||||
};
|
};
|
||||||
|
|
||||||
CAM.surface_toggle = function(widget, face, ondone) {
|
CAM.surface_toggle = function(widget, face, radians, ondone) {
|
||||||
let surfaces = widget._surfaces = widget._surfaces || {};
|
let surfaces = widget._surfaces = widget._surfaces || {};
|
||||||
for (let [root, faces] of Object.entries(surfaces)) {
|
for (let [root, faces] of Object.entries(surfaces)) {
|
||||||
if (faces.contains(face)) {
|
if (faces.contains(face)) {
|
||||||
|
|
@ -48,7 +48,7 @@ kiri.load(api => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kiri.client.send("cam_surface_find", { id: widget.id, face }, faces => {
|
kiri.client.send("cam_surface_find", { id: widget.id, face, radians }, faces => {
|
||||||
if (faces.length) {
|
if (faces.length) {
|
||||||
surfaces[face] = faces;
|
surfaces[face] = faces;
|
||||||
CAM.surface_show(widget);
|
CAM.surface_show(widget);
|
||||||
|
|
@ -92,9 +92,9 @@ kiri.load(api => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CAM.surface_find = function(widget, faces) {
|
CAM.surface_find = function(widget, faces, radians) {
|
||||||
CAM.surface_prep(widget);
|
CAM.surface_prep(widget);
|
||||||
return widget.tool.findConnectedSurface(faces, 0.1, 0.0);
|
return widget.tool.findConnectedSurface(faces, radians || 0, 0.0);
|
||||||
};
|
};
|
||||||
|
|
||||||
kiri.worker.cam_surfaces = function(data, send) {
|
kiri.worker.cam_surfaces = function(data, send) {
|
||||||
|
|
@ -114,9 +114,9 @@ kiri.load(api => {
|
||||||
};
|
};
|
||||||
|
|
||||||
kiri.worker.cam_surface_find = function(data, send) {
|
kiri.worker.cam_surface_find = function(data, send) {
|
||||||
const { id, face } = data;
|
const { id, face, radians } = data;
|
||||||
const widget = kiri.worker.cache[id];
|
const widget = kiri.worker.cache[id];
|
||||||
const faces = CAM.surface_find(widget, [face]);
|
const faces = CAM.surface_find(widget, [face], radians);
|
||||||
send.done(faces);
|
send.done(faces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1054,7 +1054,9 @@ class OpPocket extends CamOp {
|
||||||
onupdate: (index, total, msg) => {
|
onupdate: (index, total, msg) => {
|
||||||
progress((index / total) * 0.9, msg);
|
progress((index / total) * 0.9, msg);
|
||||||
},
|
},
|
||||||
ondone: (slices) => { },
|
ondone: (slices) => {
|
||||||
|
// console.log({ contour: slices });
|
||||||
|
},
|
||||||
contour: {
|
contour: {
|
||||||
tool,
|
tool,
|
||||||
tolerance,
|
tolerance,
|
||||||
|
|
|
||||||
|
|
@ -333,13 +333,13 @@ CAM.traces = async function(settings, widget, single) {
|
||||||
let slicer = new kiri.cam_slicer(widget);
|
let slicer = new kiri.cam_slicer(widget);
|
||||||
let indices = [...new Set(Object.keys(slicer.zFlat)
|
let indices = [...new Set(Object.keys(slicer.zFlat)
|
||||||
.map(kv => parseFloat(kv).round(5))
|
.map(kv => parseFloat(kv).round(5))
|
||||||
.appendAll(Object.entries(slicer.zLine).map(ze => {
|
// .appendAll(Object.entries(slicer.zLine).map(ze => {
|
||||||
let [ zk, zv ] = ze;
|
// let [ zk, zv ] = ze;
|
||||||
return zv > 1 ? parseFloat(zk).round(5) : null;
|
// return zv > 1 ? parseFloat(zk).round(5) : null;
|
||||||
})
|
// })
|
||||||
.filter(v => v !== null)))]
|
// .filter(v => v !== null))
|
||||||
|
)]
|
||||||
.sort((a,b) => b - a);
|
.sort((a,b) => b - a);
|
||||||
|
|
||||||
let traces = [];
|
let traces = [];
|
||||||
// find and trim polys (including open) to shadow
|
// find and trim polys (including open) to shadow
|
||||||
let oneach = data => {
|
let oneach = data => {
|
||||||
|
|
@ -369,8 +369,9 @@ CAM.traces = async function(settings, widget, single) {
|
||||||
traces.push(poly);
|
traces.push(poly);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let opts = { each: oneach, over: false, flatoff: 0, edges: true, openok: true };
|
let opts = { each: oneach, over: false, flatoff: 0, edges: true, openok: true, lines: true };
|
||||||
await slicer.slice(indices, opts);
|
await slicer.slice(indices, opts);
|
||||||
|
// pick up bottom features
|
||||||
opts.over = true;
|
opts.over = true;
|
||||||
await slicer.slice(indices, opts);
|
await slicer.slice(indices, opts);
|
||||||
widget.traces = traces;
|
widget.traces = traces;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
gapp.register("kiri-mode.cam.slicer", [], (root, exports) => {
|
gapp.register("kiri-mode.cam.slicer", [], (root, exports) => {
|
||||||
|
|
||||||
const { base, kiri } = root;
|
const { base, kiri } = root;
|
||||||
const { config, util, polygons, newOrderedLine, newPoint } = base;
|
const { config, util, polygons, newOrderedLine, newPoint, newLine } = base;
|
||||||
const { sliceConnect, sliceDedup } = base;
|
const { sliceConnect, sliceDedup } = base;
|
||||||
const { newSlice } = kiri;
|
const { newSlice } = kiri;
|
||||||
|
|
||||||
|
|
@ -237,18 +237,27 @@ class Slicer {
|
||||||
}
|
}
|
||||||
|
|
||||||
async sliceBucketMinion(bucket, opt, oneach) {
|
async sliceBucketMinion(bucket, opt, oneach) {
|
||||||
|
const { decode, decodePointArray } = kiri.codec;
|
||||||
const slices = (await new Promise(resolve => {
|
const slices = (await new Promise(resolve => {
|
||||||
kiri.minions.queue({
|
kiri.minions.queue({
|
||||||
cmd: "cam_slice",
|
cmd: "cam_slice",
|
||||||
opt: { lines: false },
|
opt: Object.clone(opt),
|
||||||
bucket,
|
bucket,
|
||||||
}, resolve);
|
}, resolve);
|
||||||
})).slices;
|
})).slices;
|
||||||
for (let slice of slices) {
|
for (let slice of slices) {
|
||||||
|
slice.polys = decode(slice.polys);
|
||||||
|
if (slice.lines) {
|
||||||
|
slice.lines = decodePointArray(slice.lines)
|
||||||
|
.group(2)
|
||||||
|
.map(arr => {
|
||||||
|
return newLine(arr[0], arr[1])
|
||||||
|
});
|
||||||
|
}
|
||||||
oneach(slice);
|
oneach(slice);
|
||||||
}
|
}
|
||||||
// console.log(bucket, slices);
|
// console.log(bucket, slices);
|
||||||
return kiri.codec.decode(slices);
|
return slices;
|
||||||
}
|
}
|
||||||
|
|
||||||
async sliceBucket(bucket, opt, oneach) {
|
async sliceBucket(bucket, opt, oneach) {
|
||||||
|
|
@ -472,10 +481,19 @@ moto.broker.subscribe("minion.started", msg => {
|
||||||
|
|
||||||
funcs.cam_slice = (data, seq) => {
|
funcs.cam_slice = (data, seq) => {
|
||||||
const { bucket, opt } = data;
|
const { bucket, opt } = data;
|
||||||
|
const { encode, encodePointArray } = kiri.codec;
|
||||||
|
// log({ slice: bucket, opt });
|
||||||
cache.slicer.sliceBucket(bucket, opt, slice => {
|
cache.slicer.sliceBucket(bucket, opt, slice => {
|
||||||
// console.log({ slice });
|
// console.log({ slice });
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
reply({ seq, slices: kiri.codec.encode(data) });
|
data.forEach(rec => {
|
||||||
|
rec.polys = encode(rec.polys);
|
||||||
|
if (rec.lines) {
|
||||||
|
const points = rec.lines.map(l => [l.p1, l.p2]).flat();
|
||||||
|
rec.lines = encodePointArray(points);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
reply({ seq, slices: data });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,8 @@ class Topo {
|
||||||
stepsY,
|
stepsY,
|
||||||
boundsX,
|
boundsX,
|
||||||
boundsY,
|
boundsY,
|
||||||
|
minX,
|
||||||
|
minY,
|
||||||
zMin
|
zMin
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -311,6 +313,10 @@ class Topo {
|
||||||
stepsTotal += ((maxX - minX + partOff * 2) / toolStep) | 0;
|
stepsTotal += ((maxX - minX + partOff * 2) / toolStep) | 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stepsTotal === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const box = params.box.clone().expandByVector(new THREE.Vector3(
|
const box = params.box.clone().expandByVector(new THREE.Vector3(
|
||||||
partOff, partOff, 0
|
partOff, partOff, 0
|
||||||
));
|
));
|
||||||
|
|
@ -411,7 +417,7 @@ class Probe {
|
||||||
constructor(params) {
|
constructor(params) {
|
||||||
|
|
||||||
const { data, profile } = params;
|
const { data, profile } = params;
|
||||||
const { stepsX, stepsY, boundsX, boundsY, zMin } = params;
|
const { stepsX, stepsY, boundsX, boundsY, zMin, minX, minY } = params;
|
||||||
|
|
||||||
this.params = params;
|
this.params = params;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -514,10 +514,11 @@ const conf = exports({
|
||||||
camPocketPlunge: 200,
|
camPocketPlunge: 200,
|
||||||
camPocketExpand: 0,
|
camPocketExpand: 0,
|
||||||
camPocketSmooth: 0,
|
camPocketSmooth: 0,
|
||||||
cmaPocketRefine: 20,
|
camPocketRefine: 20,
|
||||||
|
camPocketFollow: 5,
|
||||||
camPocketContour: false,
|
camPocketContour: false,
|
||||||
camPocketEngrave: false,
|
camPocketEngrave: false,
|
||||||
cmaPocketOutline: false,
|
camPocketOutline: false,
|
||||||
camDrillTool: 1000,
|
camDrillTool: 1000,
|
||||||
camDrillSpindle: 1000,
|
camDrillSpindle: 1000,
|
||||||
camDrillDownSpeed: 250,
|
camDrillDownSpeed: 250,
|
||||||
|
|
|
||||||
|
|
@ -527,6 +527,8 @@ self.kiri.lang['en-us'] = {
|
||||||
cp_xpnd_l: ["grow selected area to","encompass corners"],
|
cp_xpnd_l: ["grow selected area to","encompass corners"],
|
||||||
cp_smoo_s: "smooth",
|
cp_smoo_s: "smooth",
|
||||||
cp_smoo_l: ["clean up jagged edges caused by angled walls. can speedup and improve pocketing for detailed geometries. recommend starting with values around 1 if slicing takes too long or the contours look jagged"],
|
cp_smoo_l: ["clean up jagged edges caused by angled walls. can speedup and improve pocketing for detailed geometries. recommend starting with values around 1 if slicing takes too long or the contours look jagged"],
|
||||||
|
cp_foll_s: "selection",
|
||||||
|
cp_foll_l: ["curvature selection limit in degrees. values closer to 0 will restrict selections to flatter surfaces"],
|
||||||
cp_refi_s: "refine",
|
cp_refi_s: "refine",
|
||||||
cp_refi_l: ["number of refining passes to perform on contoured polylines. meant to address Z delta sawtoothing caused by faced geometries whereas smoothing handles XY. values > 10 work well for gently contoured geometries with significant Z movement."],
|
cp_refi_l: ["number of refining passes to perform on contoured polylines. meant to address Z delta sawtoothing caused by faced geometries whereas smoothing handles XY. values > 10 work well for gently contoured geometries with significant Z movement."],
|
||||||
cp_cont_s: "contour",
|
cp_cont_s: "contour",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue