I’m using an area operation on the Engine API to clear out my flats, but I’m getting unexpected results when there’s a hole or other thru profiles within the same area. However, in the model I’m working with, a 1.6 toolbit size is small enough to clear the flat countersunk area, but it fails to generate that path unless I reduce the bit to 0.6 or below. I’m attaching the engine code below. Any help solving this issue would be appreciated.
const projectUnits = "MM";
const isMetric = projectUnits === "MM";
const toolSize = 1.6;
const CUT_THROUGH = 0; // Default cut-through thickness if not provided
const passes = 2;
const speed = 1500;
const plunge = 635;
const stock_offset = {
x: 0,
y: 0,
z: 0,
};
new Engine()
.setListener(display_message)
.load(
"https://raw.githubusercontent.com/alzatin/A-Test-project-6/refs/heads/main/test_area_1.stl",
)
.then((eng) => {
eng.setMode("CAM");
eng.moveTo(50, 0, 0);
eng.setTools([
{
id: 1000,
number: 1,
type: "endmill",
name: "endmill",
metric: isMetric,
shaft_diam: toolSize,
shaft_len: 1,
flute_diam: toolSize,
flute_len: 2,
taper_tip: 0,
order: 5,
},
]);
const bounds = eng.widget.getBoundingBox();
const down = (bounds.dim.z + CUT_THROUGH) / passes;
const stepOver = 0.6;
// camZAnchor is only for UI
eng.setOrigin(bounds.mid.x, bounds.mid.y, bounds.max.z);
// camStockOffset is only reliable in UI
eng.setStock({
x: bounds.dim.x + stock_offset.x,
y: bounds.dim.y + stock_offset.y,
z: bounds.dim.z + stock_offset.z,
});
eng.setProcess({
camDepthFirst: true,
camEaseAngle: 40,
camEaseDown: true,
camOriginTop: true,
camOriginCenter: true,
camStockOffset: false,
camToolInit: true,
ops: [
{
all: false,
disabled: false,
down: down,
flats: false,
inside: true,
leave: 0,
leavez: 0,
omitthru: true,
ov_botz: 0,
ov_conv: false,
ov_topz: 0,
plunge: plunge,
rate: speed,
spindle: 13000,
step: stepOver,
tool: 1000,
type: "rough",
voids: false,
},
{
disabled: false,
down: 0,
flats: [2.5],
leave: 0,
leavez: 0,
mode: "clear",
ov_botz: 0,
ov_conv: false,
ov_topz: bounds.max.z,
plunge: plunge,
rate: speed,
shadow: true,
spindle: 13000,
step: stepOver,
tool: 1000,
type: "area",
},
{
disabled: false,
dogbones: false,
down: down,
inside: false,
omitthru: false,
omitvoid: false,
outside: true,
ov_botz: 0,
ov_conv: true,
ov_topz: 0,
plunge: plunge,
rate: speed,
spindle: 13000,
step: stepOver,
steps: 1,
tool: 1000,
top: false,
type: "outline",
wide: false,
},
],
});
const unitsCommand =
projectUnits === "MM"
? "G21 ; set units to MM (required)"
: "G20 ; set units to inches (required)";
return eng.setDevice({
mode: "CAM",
internal: 0,
bedHeight: 2.5,
bedWidth: 678.18,
bedDepth: 1524,
maxHeight: 150,
spindleMax: 24000,
gcodePre: [unitsCommand, "G90 ; absolute position mode (required)"],
gcodePost: ["M05 ; spindle off", "M30 ; program end"],
gcodeDwell: ["G4 P{time} ; dwell for {time}ms"],
gcodeSpindle: ["M3 S{speed} ; spindle on at {spindle} rpm"],
gcodeChange: [
"M05 ; spindle off",
"M6 T{tool} ; change tool to '{tool_name}'",
"G37; get tool offset with ETS",
],
gcodeFExt: "nc",
gcodeSpace: true,
gcodeStrip: false,
deviceName: "Tormach.24R",
useLaser: false,
});
})
.then((eng) => eng.slice())
.then((eng) => eng.prepare())
.then((eng) => eng.export())
.then((gcode) => {
localStorage.gcode = gcode;
display_gcode(gcode);
});

