add 'true shadow' computation. still a little buggy for inside-only roughing

This commit is contained in:
Stewart Allen 2021-05-31 15:50:58 -04:00
commit f9c6b13676
4 changed files with 49 additions and 3 deletions

View file

@ -523,6 +523,7 @@
outputInvertX: false,
outputInvertY: false,
camExpertFast: false,
camTrueShadow: false,
ops: [], // current ops
op2: [] // flip ops
}

View file

@ -1804,7 +1804,8 @@
camOriginTop: UC.newBoolean(LANG.or_topp_s, onBooleanClick, {title:LANG.or_topp_l, modes:CAM}),
camExpert: UC.newGroup(LANG.op_xprt_s, null, {group: "cam_expert", modes:CAM, marker: false}),
camExpertFast: UC.newBoolean(LANG.cx_fast_s, onBooleanClick, {title:LANG.cx_fast_l, modes:CAM}),
camExpertFast: UC.newBoolean(LANG.cx_fast_s, onBooleanClick, {title:LANG.cx_fast_l, modes:CAM, show: () => !UI.camTrueShadow.checked }),
camTrueShadow: UC.newBoolean(LANG.cx_true_s, onBooleanClick, {title:LANG.cx_true_l, modes:CAM, show: () => !UI.camExpertFast.checked }),
advanced: UC.newGroup(LANG.ad_menu, null, {modes:FDM}),
outputRetractDist: UC.newInput(LANG.ad_rdst_s, {title:LANG.ad_rdst_l, convert:UC.toFloat, modes:FDM}),

View file

@ -118,6 +118,7 @@
let roughDown = op.down;
let roughLeave = op.leave;
let toolDiam = new CAM.Tool(settings, op.tool).fluteDiameter();
let trueShadow = process.camTrueShadow === true;
// create facing slices
if (roughTop) {
@ -203,7 +204,11 @@
progress((index / total) * 0.5);
}, genso: true });
shadow = POLY.union(shadow.appendAll(shadowTop.tops), 0.01, true);
if (trueShadow) {
shadow = tshadow.clone(true);
} else {
shadow = POLY.union(shadow.appendAll(shadowTop.tops), 0.01, true);
}
// inset or eliminate thru holes from shadow
shadow = POLY.flatten(shadow.clone(true), [], true);
@ -1110,6 +1115,7 @@
let rough = real.filter(op => op.type === 'rough').length > 0;
let outline = real.filter(op => op.type === 'outline').length > 0;
let outlineOut = real.filter(op => op.type === 'outline' && op.outside).length > 0;
let trueShadow = state.settings.process.camTrueShadow === true;
let minStepDown = real
.map(op => (op.down || 3) / 3)
@ -1127,7 +1133,14 @@
}
let terrain = slicer.slice(tzindex, { each: (data, index, total) => {
tshadow = POLY.union(tshadow.slice().appendAll(data.tops), 0.01, true);
let downfaces = trueShadow ? CAM.angledFaces(widget, data.z).map(a => {
return newPolygon()
.add(a[0].x,a[0].y,a[0].z)
.add(a[1].x,a[1].y,a[1].z)
.add(a[2].x,a[2].y,a[2].z);
}) : [];
let downunion = POLY.union(downfaces, 0.0001, true);
tshadow = POLY.union(tshadow.slice().appendAll(data.tops).appendAll(downunion), 0.01, true);
tslices.push(data.slice);
if (false) {
const slice = data.slice;
@ -1166,6 +1179,35 @@
}
}
CAM.angledFaces = function(widget, z) {
let geo = new THREE.BufferGeometry();
geo.setAttribute('position', new THREE.BufferAttribute(widget.vertices, 3));
let rad = (Math.PI / 180);
let deg = (180 / Math.PI);
let angle = rad * 1;
let thresh = -Math.sin(angle);
let found = [];
let { position } = geo.attributes;
let { itemSize, count, array } = position;
for (let i = 0; i<count; i += 3) {
let ip = i * itemSize;
let a = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
let b = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
let c = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
// skip faces below threshold
if (a.z < z || b.z < z || c.z < z) {
continue;
}
let norm = THREE.computeFaceNormal(a,b,c);
// limit to downward faces
if (norm.z > thresh) {
continue;
}
found.push([a,b,c]);
}
return found;
};
CAM.OPS = CamOp.MAP = {
"xray": OpXRay,
"shadow": OpShadow,

View file

@ -605,6 +605,8 @@ kiri.lang['en-us'] = {
// CAM EXPERT
cx_fast_s: "skip shadow",
cx_fast_l: ["disable overhang detection","can be faster and use less","memory with complex models","but fails with overhangs","try enabling if slicing","hangs during shadowing"],
cx_true_s: "true shadow",
cx_true_l: ["computationally correct shadow","will be slower but produce","better cuts for complex parts"],
// FDM GCODE
ag_menu: "gcode",