diff --git a/notes.md b/notes.md
index cd55f420..2e1407be 100644
--- a/notes.md
+++ b/notes.md
@@ -55,6 +55,7 @@
# CAM
+* `B` tabs are not cut to exact height
* `B` first rough step too far down in certain circumstances?
* `B` trace open polys are not wound consistently
* `B` path routing with tabs sometimes makes no sense
diff --git a/src/kiri/conf.js b/src/kiri/conf.js
index 0bef439a..b42cd45c 100644
--- a/src/kiri/conf.js
+++ b/src/kiri/conf.js
@@ -296,7 +296,7 @@
sliceSupportExtra: 0,
sliceSupportAngle: 50,
sliceSupportNozzle: 0,
- sliceSupportEnable: false,
+ // sliceSupportEnable: false,
sliceSolidMinArea: 1,
sliceSolidLayers: 3,
sliceBottomLayers: 3,
diff --git a/src/kiri/init.js b/src/kiri/init.js
index b954f2cf..861cf6c2 100644
--- a/src/kiri/init.js
+++ b/src/kiri/init.js
@@ -1650,18 +1650,18 @@
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
sliceSupportSize: UC.newInput(LANG.sp_size_s, {title:LANG.sp_size_l, bound:UC.bound(1.0,200.0), convert:UC.toFloat, modes:FDM}),
sliceSupportOffset: UC.newInput(LANG.sp_offs_s, {title:LANG.sp_offs_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
- sliceSupportGap: UC.newInput(LANG.sp_gaps_s, {title:LANG.sp_gaps_l, bound:UC.bound(0,5), convert:UC.toInt, modes:FDM}),
+ sliceSupportGap: UC.newInput(LANG.sp_gaps_s, {title:LANG.sp_gaps_l, bound:UC.bound(0,5), convert:UC.toInt, modes:FDM, show:isNotBelt}),
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
sliceSupportArea: UC.newInput(LANG.sp_area_s, {title:LANG.sp_area_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
sliceSupportExtra: UC.newInput(LANG.sp_xpnd_s, {title:LANG.sp_xpnd_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
- sliceSupportAngle: UC.newInput(LANG.sp_angl_s, {title:LANG.sp_angl_l, bound:UC.bound(0.0,90.0), convert:UC.toFloat, modes:FDM}),
+ sliceSupportAngle: UC.newInput(LANG.sp_angl_s, {title:LANG.sp_angl_l, bound:UC.bound(0.0,90.0), convert:UC.toFloat, modes:FDM, show:isNotBelt}),
sliceSupportEnable: UC.newBoolean(LANG.sp_auto_s, onBooleanClick, {title:LANG.sp_auto_l, modes:FDM, show:isNotBelt}),
sliceSupportGen: UC.newRow([
UI.ssaGen = UC.newButton(LANG.sp_detect, onButtonClick, {class: "f-col grow a-center"})
- ], { modes: FDM, class: "ext-buttons f-row grow" }),
- fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
+ ], { modes: FDM, class: "ext-buttons f-row grow", show:isNotBelt }),
+ fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
sliceSupportManual: UC.newRow([
(UI.ssmAdd = UC.newButton(undefined, onButtonClick, {icon:''})),
(UI.ssmDun = UC.newButton(undefined, onButtonClick, {icon:''})),
diff --git a/src/kiri/worker.js b/src/kiri/worker.js
index 0d399c46..d41e5396 100644
--- a/src/kiri/worker.js
+++ b/src/kiri/worker.js
@@ -84,7 +84,7 @@ KIRI.worker = {
if (z < 0.01) miny = Math.min(miny, y);
}
- widget.getBoundingBox(true);
+ let bb1 = widget.getBoundingBox(true);
let track = widget.track;
xpos = track.pos.x;
ypos = settings.device.bedDepth / 2 + track.pos.y + miny;
@@ -94,8 +94,8 @@ KIRI.worker = {
widget.loadVertices(widget.vertices);
widget._rotate(rotation,0,0,true);
widget.center(false, true);
- widget.getBoundingBox(true);
- widget.belt = { xpos, ypos };
+ let bb2 = widget.getBoundingBox(true);
+ widget.belt = { xpos, ypos, zmov: (bb2.max.z - bb1.max.z)/2 };
}
widget.slice(settings, function(error) {
diff --git a/src/mode/fdm/client.js b/src/mode/fdm/client.js
index 46c9e9cd..64fd4191 100644
--- a/src/mode/fdm/client.js
+++ b/src/mode/fdm/client.js
@@ -35,7 +35,7 @@
restoreSupports(api.widgets.all());
});
api.event.on("settings.saved", (settings) => {
- api.ui.fdmSupport.style.display = lastMode !== 'FDM' || settings.device.bedBelt ? 'none' : 'flex';
+ // api.ui.fdmSupport.style.display = lastMode !== 'FDM' || settings.device.bedBelt ? 'none' : 'flex';
});
api.event.on("button.click", target => {
switch (target) {
diff --git a/src/mode/fdm/prepare.js b/src/mode/fdm/prepare.js
index 63d7b99b..9f9dfb8e 100644
--- a/src/mode/fdm/prepare.js
+++ b/src/mode/fdm/prepare.js
@@ -216,6 +216,8 @@
let swidget = KIRI.newWidget();
swidget.slices = sslices;
swidget.support = true;
+ swidget.rotinfo = widget.rotinfo;
+ swidget.belt = widget.belt;
swidget.mesh = { widget: swidget, position: widget.mesh.position };
settings.widget[swidget.id] = { extruder: process.sliceSupportNozzle };
widgets.push(swidget);
@@ -288,7 +290,7 @@
// establish offsets
for (let widget of widgets) {
let { rotinfo, belt } = widget;
- // console.log({rotinfo, belt});
+ console.log({rotinfo, belt, widget});
let offset = widget.mesh ? Object.clone(widget.mesh.position) : {x:0, y:0, z:0};
if (isBelt) {
offset.x = rotinfo.xpos;
diff --git a/src/mode/fdm/slice.js b/src/mode/fdm/slice.js
index 17406b53..6bc6aa6c 100644
--- a/src/mode/fdm/slice.js
+++ b/src/mode/fdm/slice.js
@@ -23,7 +23,8 @@
infill: { check: 0x3322bb, face: 0x3322bb, line: 0x3322bb, opacity: 1 },
support: { check: 0xaa5533, face: 0xaa5533, line: 0xaa5533, opacity: 1 }
},
- PROTO = Object.clone(COLOR);
+ PROTO = Object.clone(COLOR),
+ bwcomp = (1 / Math.cos(Math.PI/4));
let isThin = false; // force line rendering
let isFlat = false; // force flat rendering
@@ -210,6 +211,11 @@
// slices[0].output()
// .setLayer('shadow', { line: 0xff0000, check: 0xff0000 })
// .addPolys(shadow);
+ if (isBelt) {
+ for (let col of fixed) {
+ col.z += widget.belt.zmov;
+ }
+ }
}
// create shells and diff inner fillable areas
@@ -271,7 +277,7 @@
}, "infill");
}
- // calculations only relevant when supports are enabled
+ // belt supports are their own thing
if (!isBelt) {
let auto = spro.sliceSupportEnable && spro.sliceSupportDensity > 0.0,
minArea = spro.sliceSupportArea;
@@ -282,6 +288,8 @@
forSlices(0.8, 0.9, slice => {
doSupportFill(slice, lineWidth, spro.sliceSupportDensity, minArea);
}, "support");
+ } else if (false) {
+ doSupportBelt(slices, spro, fixed, shadow, doupdate);
}
// render if not explicitly disabled
@@ -864,6 +872,77 @@
return true;
};
+ function doSupportBelt(slices, proc, fixed, shadow, doupdate) {
+ if (!fixed || fixed.length === 0) {
+ return;
+ }
+
+ let minArea = proc.supportMinArea,
+ offset = proc.sliceSupportOffset,
+ min = minArea || 0.01;
+
+ // find slice closest to z
+ function findSlice(z) {
+ let mind = Infinity,
+ mins = null;
+ for (let slice of slices) {
+ let d = Math.abs(slice.z - z);
+ if (d < mind) {
+ mind = d;
+ mins = slice;
+ }
+ }
+ return mins;
+ }
+
+ // add support pillar to a slice
+ function addPillar(slice, sup) {
+ // ensure slice has offsets
+ if (!slice.offsets) {
+ // create inner clip offset from tops
+ POLY.expand(slice.topPolys(), offset, slice.z, slice.offsets = []);
+ }
+ // ensure slice has supports array
+ if (!slice.supports) {
+ slice.supports = [];
+ }
+ // calculate support rect
+ let dz = sup.z - slice.z;
+ let dy = dz;
+ let dw = bwcomp;
+ let center = BASE.newPoint(sup.x, sup.y + dy, slice.z);
+ let poly = [ BASE.newPolygon().centerRectangle(center, sup.dw, sup.dw * dw) ];
+ let trim = [];
+ // poly = POLY.trimTo(poly, shadow);
+ POLY.subtract(poly, slice.offsets, trim, null, slice.z, min);
+ // if support is entirely culled, terminate projection
+ if (trim.length === 0) {
+ return false;
+ }
+ slice.supports.appendAll(trim);
+ return true;
+ }
+
+ for (let sup of fixed) {
+ let slice = findSlice(sup.z);
+ let rem = addPillar(slice, sup);
+ let zmin = sup.z - sup.dh / 2;
+ let zmax = sup.z + sup.dh / 2;
+ while (slice.up && slice.up.z <= zmax) {
+ slice = slice.up;
+ if (!addPillar(slice, sup)) {
+ break;
+ }
+ }
+ while (slice.down && slice.down.z >= zmin) {
+ slice = slice.down;
+ if (!addPillar(slice, sup)) {
+ break;
+ }
+ }
+ }
+ }
+
/**
* calculate external overhangs requiring support.
* this is done bottom-up except for fixed supports (manual)
@@ -961,6 +1040,7 @@
let zmin = sup.z - sup.dh / 2;
let zmax = sup.z + sup.dh / 2;
if (slice.z >= zmin && slice.z <= zmax) {
+ let dz = sup.z - slice.z;
let center = BASE.newPoint(sup.x, sup.y, slice.z);
supports.push(BASE.newPolygon().centerRectangle(center, sup.dw, sup.dw));
}
@@ -984,7 +1064,7 @@
// set depth hint on support polys for infill density
trimmed.forEach(function(trim) {
- if (trim.area() < 0.1) return;
+ // if (trim.area() < 0.1) return;
culled.push(trim.setZ(down.z));
});
diff --git a/web/kiri/lang/da.js b/web/kiri/lang/da.js
index c50e2166..c45c63b0 100644
--- a/web/kiri/lang/da.js
+++ b/web/kiri/lang/da.js
@@ -135,7 +135,7 @@ kiri.lang['da'] =
op_sped_s: "vis hastigheder",
op_sped_l: "vis hastighed til farve bar\ni forhåndsvisning",
op_auto_s: "auto fordel",
- op_auto_l: "automatisk layoutplatform,\nnår nye dele tilføjes,
+ op_auto_l: "automatisk layoutplatform,\nnår nye dele tilføjes",
op_free_s: "free layout",
op_free_l: "permit dragable layout\nno effect in laser mode",
op_invr_s: "vend zoom om",
@@ -346,7 +346,7 @@ kiri.lang['da'] =
cd_lift_s: "løft bor",
cd_lift_l: "løft mellem dyk\nefter opholdsperiode\ni arbejdsområdets enheder\n0 for at deaktivere",
cd_regi_s: "registrer",
- cd_regi_l: "bore registreringshuller\ntil dobbeltsidede dele\uafhængigt af aktivering af\nboring, men bruger samme værktøj og indstillinger",
+ cd_regi_l: "bore registreringshuller\ntil dobbeltsidede dele\nuafhængigt af aktivering af\nboring, men bruger samme værktøj og indstillinger",
// CNC CUTOUT TABS
ct_menu: "tapper",