add CAM 3D engraving and marking with the pocket contouring operation
This commit is contained in:
parent
c1501c7739
commit
b7f8ce5b52
7 changed files with 30 additions and 8 deletions
|
|
@ -8,6 +8,7 @@ Full docs @ https://docs.grid.space/projects/kiri-moto
|
||||||
* improve CAM animation speeds
|
* improve CAM animation speeds
|
||||||
* add CAM op level part offset parameters for xy and z
|
* add CAM op level part offset parameters for xy and z
|
||||||
* add CAM pocket smoothing and contouring which is closer to true 3 axis
|
* add CAM pocket smoothing and contouring which is closer to true 3 axis
|
||||||
|
* add CAM 3D engraving and marking with the pocket contouring operation
|
||||||
* fix CAM invalidation of tabs on scale and traces on scale or rotate
|
* fix CAM invalidation of tabs on scale and traces on scale or rotate
|
||||||
* fix belt fan override for base extrusions touching belt
|
* fix belt fan override for base extrusions touching belt
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1144,14 +1144,15 @@ CAM.init = function(kiri, api) {
|
||||||
smooth: 'camPocketSmooth',
|
smooth: 'camPocketSmooth',
|
||||||
refine: 'cmaPocketRefine',
|
refine: 'cmaPocketRefine',
|
||||||
contour: 'camPocketContour',
|
contour: 'camPocketContour',
|
||||||
|
engrave: 'camPocketEngrave',
|
||||||
outline: 'cmaPocketOutline',
|
outline: 'cmaPocketOutline',
|
||||||
tolerance: 'camTolerance',
|
tolerance: 'camTolerance',
|
||||||
}).inputs = {
|
}).inputs = {
|
||||||
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
|
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
|
||||||
sep: UC.newBlank({class:"pop-sep"}),
|
sep: UC.newBlank({class:"pop-sep"}),
|
||||||
spindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, show:hasSpindle}),
|
spindle: UC.newInput(LANG.cc_spnd_s, {title:LANG.cc_spnd_l, convert:UC.toInt, show:hasSpindle}),
|
||||||
step: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.01,1.0)}),
|
step: UC.newInput(LANG.cc_sovr_s, {title:LANG.cc_sovr_l, convert:UC.toFloat, bound:UC.bound(0.01,1.0), show:() => !(poppedRec.engrave && poppedRec.contour)}),
|
||||||
down: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:UC.toFloat, units:true}),
|
down: UC.newInput(LANG.cc_sdwn_s, {title:LANG.cc_sdwn_l, convert:UC.toFloat, units:true, show:() => !(poppedRec.engrave && poppedRec.contour)}),
|
||||||
rate: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, units:true}),
|
rate: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, units:true}),
|
||||||
plunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, units:true}),
|
plunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, units:true}),
|
||||||
sep: UC.newBlank({class:"pop-sep"}),
|
sep: UC.newBlank({class:"pop-sep"}),
|
||||||
|
|
@ -1162,6 +1163,7 @@ CAM.init = function(kiri, api) {
|
||||||
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}),
|
||||||
|
engrave: UC.newBoolean(LANG.cp_engr_s, undefined, {title:LANG.cp_engr_l, show:() => poppedRec.contour}),
|
||||||
sep: UC.newBlank({class:"pop-sep"}),
|
sep: UC.newBlank({class:"pop-sep"}),
|
||||||
menu: UC.newRow([
|
menu: UC.newRow([
|
||||||
UC.newButton(undefined, func.surfaceAdd, {icon:'<i class="fas fa-plus"></i>'}),
|
UC.newButton(undefined, func.surfaceAdd, {icon:'<i class="fas fa-plus"></i>'}),
|
||||||
|
|
|
||||||
|
|
@ -970,6 +970,7 @@ class OpPocket extends CamOp {
|
||||||
let toolDiam = camTool.fluteDiameter();
|
let toolDiam = camTool.fluteDiameter();
|
||||||
let toolOver = toolDiam * op.step;
|
let toolOver = toolDiam * op.step;
|
||||||
let cutdir = process.camConventional;
|
let cutdir = process.camConventional;
|
||||||
|
let engrave = contour && op.engrave;
|
||||||
if (contour) {
|
if (contour) {
|
||||||
down = 0;
|
down = 0;
|
||||||
this.topo = new CAM.Topo({
|
this.topo = new CAM.Topo({
|
||||||
|
|
@ -1034,9 +1035,10 @@ class OpPocket extends CamOp {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let slice = newSliceOut(z);
|
let slice = newSliceOut(z);
|
||||||
|
let count = engrave ? 1 : 999;
|
||||||
slice.camTrace = { tool, rate, plunge };
|
slice.camTrace = { tool, rate, plunge };
|
||||||
POLY.offset(clip, [ -toolDiam / 2, -toolOver ], {
|
POLY.offset(clip, [ -toolDiam / 2, -toolOver ], {
|
||||||
count:999, outs: slice.camLines = [], flat:true, z
|
count, outs: slice.camLines = [], flat:true, z
|
||||||
});
|
});
|
||||||
if (tabs) {
|
if (tabs) {
|
||||||
slice.camLines = cutTabs(tabs, POLY.flatten(slice.camLines, null, true), z);
|
slice.camLines = cutTabs(tabs, POLY.flatten(slice.camLines, null, true), z);
|
||||||
|
|
@ -1045,7 +1047,7 @@ class OpPocket extends CamOp {
|
||||||
}
|
}
|
||||||
POLY.setWinding(slice.camLines, cutdir, false);
|
POLY.setWinding(slice.camLines, cutdir, false);
|
||||||
if (contour) {
|
if (contour) {
|
||||||
slice.camLines = pocket.conform(slice.camLines, op.refine);
|
slice.camLines = pocket.conform(slice.camLines, op.refine, engrave);
|
||||||
}
|
}
|
||||||
slice.output()
|
slice.output()
|
||||||
.setLayer("pocket", {line: color}, false)
|
.setLayer("pocket", {line: color}, false)
|
||||||
|
|
@ -1093,14 +1095,14 @@ class OpPocket extends CamOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mold cam output lines to the surface of the topo offset by tool geometry
|
// mold cam output lines to the surface of the topo offset by tool geometry
|
||||||
conform(camLines, refine = 10) {
|
conform(camLines, refine = 10, engrave) {
|
||||||
const topo = this.topo;
|
const topo = this.topo;
|
||||||
// re-segment polygon to a higher resolution
|
// re-segment polygon to a higher resolution
|
||||||
const hirez = camLines.map(p => p.segment(topo.tolerance * 2));
|
const hirez = camLines.map(p => p.segment(topo.tolerance * 2));
|
||||||
// walk points and offset from surface taking into account tool geometry
|
// walk points and offset from surface taking into account tool geometry
|
||||||
for (let poly of hirez) {
|
for (let poly of hirez) {
|
||||||
for (let point of poly.points) {
|
for (let point of poly.points) {
|
||||||
point.z = topo.toolAtXY(point.x, point.y);
|
point.z = engrave ? topo.zAtXY(point.x, point.y) : topo.toolAtXY(point.x, point.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// walk points noting z deltas and smoothing sawtooth patterns
|
// walk points noting z deltas and smoothing sawtooth patterns
|
||||||
|
|
|
||||||
|
|
@ -69,11 +69,19 @@ class Tool {
|
||||||
return this.unitScale() * this.tool.shaft_diam;
|
return this.unitScale() * this.tool.shaft_diam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isBallMill() {
|
||||||
|
return this.type === "ballmill";
|
||||||
|
}
|
||||||
|
|
||||||
|
isTaperMill() {
|
||||||
|
return this.type === "tapermill";
|
||||||
|
}
|
||||||
|
|
||||||
generateProfile(resolution) {
|
generateProfile(resolution) {
|
||||||
// generate tool profile
|
// generate tool profile
|
||||||
let type = this.getType(),
|
let type = this.getType(),
|
||||||
ball = type === "ballmill",
|
ball = this.isBallMill(),
|
||||||
taper = type === "tapermill",
|
taper = this.isTaperMill(),
|
||||||
tip_diameter = this.tipDiameter(),
|
tip_diameter = this.tipDiameter(),
|
||||||
shaft_offset = this.fluteLength(),
|
shaft_offset = this.fluteLength(),
|
||||||
flute_diameter = this.fluteDiameter(),
|
flute_diameter = this.fluteDiameter(),
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,12 @@ class Topo {
|
||||||
return toolAtZ(px, py);
|
return toolAtZ(px, py);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.zAtXY = function(px, py) {
|
||||||
|
px = Math.round(rx * (px - minX));
|
||||||
|
py = Math.round(ry * (py - minY));
|
||||||
|
return topo.data[px * stepsy + py] || zMin;
|
||||||
|
};
|
||||||
|
|
||||||
function push_point(x,y,z) {
|
function push_point(x,y,z) {
|
||||||
const newP = newPoint(x,y,z);
|
const newP = newPoint(x,y,z);
|
||||||
// todo: merge co-linear, not just co-planar
|
// todo: merge co-linear, not just co-planar
|
||||||
|
|
|
||||||
|
|
@ -512,6 +512,7 @@ const conf = exports({
|
||||||
camPocketSmooth: 0,
|
camPocketSmooth: 0,
|
||||||
cmaPocketRefine: 20,
|
cmaPocketRefine: 20,
|
||||||
camPocketContour: false,
|
camPocketContour: false,
|
||||||
|
camPocketEngrave: false,
|
||||||
cmaPocketOutline: false,
|
cmaPocketOutline: false,
|
||||||
camDrillTool: 1000,
|
camDrillTool: 1000,
|
||||||
camDrillSpindle: 1000,
|
camDrillSpindle: 1000,
|
||||||
|
|
|
||||||
|
|
@ -521,6 +521,8 @@ self.kiri.lang['en-us'] = {
|
||||||
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",
|
||||||
cp_cont_l: ["ignore interior voids and features"],
|
cp_cont_l: ["ignore interior voids and features"],
|
||||||
|
cp_engr_s: "engrave",
|
||||||
|
cp_engr_l: ["sets up a single pass around the perimeter of the selected area. also useful for 3D laser marking"],
|
||||||
cp_outl_s: "outline only",
|
cp_outl_s: "outline only",
|
||||||
cp_outl_l: ["ignore interior voids and features"],
|
cp_outl_l: ["ignore interior voids and features"],
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue