diff --git a/src/kiri/app/conf/defaults.js b/src/kiri/app/conf/defaults.js index dbdf5b7c..81513b08 100644 --- a/src/kiri/app/conf/defaults.js +++ b/src/kiri/app/conf/defaults.js @@ -338,18 +338,14 @@ export const conf = { sliceSolidify: false, sliceSolidMinArea: 1, sliceSupportAngle: 50, - // sliceSupportArea: 0.1, sliceSupportDensity: 0.1, - // sliceSupportEnable: false, sliceSupportExtra: 0, sliceSupportGap: 1, - // sliceSupportGrow: 0, sliceSupportNozzle: 0, sliceSupportOffset: 1.0, sliceSupportOutline: true, - // sliceSupportSize: 5, sliceSupportSpan: 5, - sliceSupportType: "automatic", + sliceSupportType: "disabled", sliceSupportTree: false, sliceTopLayers: 3, sliceZInterleave: false, diff --git a/src/kiri/mode/fdm/init-menu.js b/src/kiri/mode/fdm/init-menu.js index 071400d1..ffaf931f 100644 --- a/src/kiri/mode/fdm/init-menu.js +++ b/src/kiri/mode/fdm/init-menu.js @@ -120,22 +120,13 @@ export function menu() { separator: newBlank({ class:"set-sep", driven }), sliceSupportAngle: newInput(LANG.sp_angl_s, {title:LANG.sp_angl_l, convert:toFloat, bound:bound(0.0,90.0)}), sliceSupportDensity: newInput(LANG.sp_dens_s, {title:LANG.sp_dens_l, convert:toFloat, bound:bound(0.0,1.0)}), - // sliceSupportSize: newInput(LANG.sp_size_s, {title:LANG.sp_size_l, convert:toFloat, bound:bound(1.0,200.0)}), sliceSupportGap: newInput(LANG.sp_gaps_s, {title:LANG.sp_gaps_l, convert:toInt, bound:bound(0,5)}), sliceSupportOffset: newInput(LANG.sp_offs_s, {title:LANG.sp_offs_l, convert:toFloat, bound:bound(0.0,200.0)}), - // sliceSupportArea: newInput(LANG.sp_area_s, {title:LANG.sp_area_l, convert:toFloat, bound:bound(0.0,200.0)}), sliceSupportExtra: newInput(LANG.sp_xpnd_s, {title:LANG.sp_xpnd_l, convert:toFloat, bound:bound(0.0,10.0)}), - // sliceSupportGrow: newInput(LANG.sp_grow_s, {title:LANG.sp_grow_l, convert:toFloat, bound:bound(0.0,10.0)}), sliceSupportSpan: newInput(LANG.sp_span_s, {title:LANG.sp_span_l, convert:toFloat, bound:bound(0.0,200.0), show:() => ui.sliceSupportEnable.checked }), separator: newBlank({ class:"set-sep", driven }), - // sliceSupportTree: newBoolean(LANG.sp_tree_s, onBooleanClick, {title:LANG.sp_tree_s, trigger, show:isNotBelt}), - // sliceSupportEnable: newBoolean(LANG.sp_auto_s, onBooleanClick, {title:LANG.sp_auto_l, show:isNotBelt}), sliceSupportOutline: newBoolean(LANG.sp_outl_s, onBooleanClick, {title:LANG.sp_outl_l, xshow: () => !isTree() }), separator: newBlank({ class:"set-sep", driven, show:manualSupport }), - // sliceSupportGen: newRow([ - // ui.ssaGen = newButton(LANG.sp_detect, onButtonClick, {class: "f-col grow a-center"}) - // ], { modes: FDM, class: "ext-buttons f-row grow", show:manualSupport }), - // separator: newBlank({ class:"set-sep", driven }), sliceSupportManual: newRow([ (ui.ssmAdd = newButton(undefined, onButtonClick, {icon:''})), (ui.ssmDun = newButton(undefined, onButtonClick, {icon:''})), diff --git a/src/kiri/mode/fdm/init-ui.js b/src/kiri/mode/fdm/init-ui.js index 957ab9c8..3a7819c1 100644 --- a/src/kiri/mode/fdm/init-ui.js +++ b/src/kiri/mode/fdm/init-ui.js @@ -306,7 +306,8 @@ export function init() { if (x || y) { clearWidgetSupports(widget); } else { - // todo rotate supports when it's only a Z rotation + // rotate supports when rotation is constrained to Z axis + rotateWidgetPaint(widget, z); } }); @@ -326,7 +327,6 @@ export function init() { if (!(addingSupports && isFdmMode)) { return; } - const { int, type, point, event } = data; }); } @@ -334,3 +334,22 @@ function clearWidgetSupports(widget) { delete widget.anno.support; widget.anno.paint = []; } + +function rotateWidgetPaint(widget, angle) { + if (!widget.anno.paint?.length) { + return; + } + + // Z rotation angle in radians + const cos = Math.cos(angle); + const sin = Math.sin(angle); + + // Rotate each paint point around the Z axis + for (let paintPoint of widget.anno.paint) { + const { point } = paintPoint; + const x = point.x; + const y = point.y; + point.x = x * cos - y * sin; + point.y = x * sin + y * cos; + } +} \ No newline at end of file diff --git a/src/kiri/mode/fdm/slice.js b/src/kiri/mode/fdm/slice.js index b37c85d1..714a5e93 100644 --- a/src/kiri/mode/fdm/slice.js +++ b/src/kiri/mode/fdm/slice.js @@ -440,9 +440,9 @@ export function sliceOne(settings, widget, onupdate, ondone) { async function processSlices(slices) { /** - * Process shadow-based support generation + * Process automatic and manual shadow-based support generation */ - async function processAutoSupport() { + async function processSupports() { if (process.sliceSupportType === 'disabled') { return; } @@ -452,10 +452,6 @@ export function sliceOne(settings, widget, onupdate, ondone) { let zAngNorm = Math.sin(process.sliceSupportAngle * Math.PI / 180); let manual = process.sliceSupportType === 'manual'; - await widget.computeShadowStack(indices, progress => { - trackupdate(progress, 0.05, 0.10, "shadow"); - }, zAngNorm); - // sort bottom up so shadows do not accumulate // since that is done later and clipped to slice.clips stack.sort((a,b) => a.z - b.z); @@ -481,9 +477,14 @@ export function sliceOne(settings, widget, onupdate, ondone) { } // create automatic shadows supports when on manual paint - if (!manual) - for (let slice of stack) { - slice.shadow = await widget.shadowAt(slice.z, true); + if (!manual) { + await widget.computeShadowStack(indices, progress => { + trackupdate(progress, 0.05, 0.10, "shadow"); + }, zAngNorm); + + for (let slice of stack) { + slice.shadow = await widget.shadowAt(slice.z, true); + } } // 1. accumulate / union shadow coverage top down @@ -787,7 +788,7 @@ export function sliceOne(settings, widget, onupdate, ondone) { } // new auto support demonstrator using cast shadow - await processAutoSupport(); + await processSupports(); // process solid layers (top/bottom) processSolidLayers(); diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index c477fda1..77bd7e5e 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -137,8 +137,6 @@ self.lang['en-us'] = { dv_xtab_l: "extrusion moves absolute", dv_orgc_s: "origin center", dv_orgc_l: "bed origin center", - // dv_orgt_s: "origin top", - // dv_orgt_l: "part z origin top", dv_bedc_s: "circular bed", dv_bedc_l: "device bed is circular", dv_belt_s: "belt bed", @@ -468,8 +466,6 @@ self.lang['en-us'] = { sp_type_l: ["automatic = detect","manual = paint on"], sp_dens_s: "density", sp_dens_l: ["fraction 0.0 - 1.0","recommended 0.15","0 to disable"], - // sp_size_s: "pillar size", - // sp_size_l: ["pillar width in millimeters","smaller values exponentially","increase detection times"], sp_offs_s: "part offset", sp_offs_l: ["offset from part","in millimeters"], sp_gaps_s: "layer gap", @@ -478,18 +474,12 @@ self.lang['en-us'] = { sp_span_l: ["unsupported span that causes","a new support to be generated","in millimeters"], sp_angl_s: "angle", sp_angl_l: ["max overhang angle before","supporting pillar is generated","normal values 45-60","belt values 0-10"], - // sp_area_s: "min area", - // sp_area_l: ["minimum area for","a support column","in millimeters","smaller values will","slow detection"], sp_xpnd_s: "expand", sp_xpnd_l: ["expand support area","beyond part boundary","in millimeters"], - // sp_grow_s: "grow", - // sp_grow_l: ["grow support column to fill small gaps","in millimeters"], sp_nozl_s: "tool", sp_nozl_l: ["in multi-extruder systems","the toolhead to use for","support material"], sp_outl_s: "enclosed", sp_outl_l: ["enclose support pattern","inside a perimeter shell"], - // sp_auto_s: "automatic", - // sp_auto_l: ["enable generated supports","using at-slice-time geometry","supports will only appear","after slicing completes"], sp_tree_s: "tree type", sp_tree_l: ["use tree type support structure"],