checkpoint manual support work
This commit is contained in:
parent
ace9858018
commit
d560dff744
3 changed files with 124 additions and 44 deletions
|
|
@ -10,6 +10,7 @@
|
||||||
FDM = KIRI.driver.FDM,
|
FDM = KIRI.driver.FDM,
|
||||||
SPACE, API,
|
SPACE, API,
|
||||||
p1, p2, iw,
|
p1, p2, iw,
|
||||||
|
lastMode, lastView,
|
||||||
alert = [],
|
alert = [],
|
||||||
func = {};
|
func = {};
|
||||||
|
|
||||||
|
|
@ -17,9 +18,12 @@
|
||||||
API = api;
|
API = api;
|
||||||
SPACE = api.const.SPACE;
|
SPACE = api.const.SPACE;
|
||||||
api.event.on("mode.set", mode => {
|
api.event.on("mode.set", mode => {
|
||||||
if (mode !== 'FDM') {
|
lastMode = mode;
|
||||||
clearAllWidgetSupports();
|
updateVisiblity();
|
||||||
}
|
});
|
||||||
|
api.event.on("view.set", view => {
|
||||||
|
lastView = view;
|
||||||
|
updateVisiblity();
|
||||||
});
|
});
|
||||||
api.event.on("settings.load", (settings) => {
|
api.event.on("settings.load", (settings) => {
|
||||||
if (settings.mode !== 'FDM') return;
|
if (settings.mode !== 'FDM') return;
|
||||||
|
|
@ -50,6 +54,7 @@
|
||||||
api.event.on("fdm.supports.done", func.sdone = () => {
|
api.event.on("fdm.supports.done", func.sdone = () => {
|
||||||
delbox('intZ');
|
delbox('intZ');
|
||||||
delbox('intW');
|
delbox('intW');
|
||||||
|
delbox('supp');
|
||||||
api.hide.alert(alert);
|
api.hide.alert(alert);
|
||||||
api.feature.hover = false;
|
api.feature.hover = false;
|
||||||
});
|
});
|
||||||
|
|
@ -58,12 +63,37 @@
|
||||||
clearAllWidgetSupports();
|
clearAllWidgetSupports();
|
||||||
API.conf.save();
|
API.conf.save();
|
||||||
});
|
});
|
||||||
|
api.event.on("slice.begin", () => {
|
||||||
|
func.sdone();
|
||||||
|
updateVisiblity();
|
||||||
|
});
|
||||||
api.event.on("key.esc", () => {
|
api.event.on("key.esc", () => {
|
||||||
func.sdone()
|
func.sdone()
|
||||||
});
|
});
|
||||||
// api.event.on("selection.rotate", (x,y,z) => {
|
api.event.on("selection.rotate", rot => {
|
||||||
// console.log('rotate', x,y,z);
|
const {x, y, z} = rot;
|
||||||
// });
|
if (x || y) {
|
||||||
|
API.selection.widgets().forEach(widget => {
|
||||||
|
clearWidgetSupports(widget);
|
||||||
|
});
|
||||||
|
API.conf.save();
|
||||||
|
} else {
|
||||||
|
API.selection.widgets().forEach(widget => {
|
||||||
|
let ann = API.widgets.annotate(widget.id);
|
||||||
|
let sups = ann.support || [];
|
||||||
|
sups.forEach(sup => {
|
||||||
|
let wsup = widget.sups[sup.id];
|
||||||
|
let vc = new THREE.Vector3(sup.x, sup.y, sup.z);
|
||||||
|
let m4 = new THREE.Matrix4();
|
||||||
|
m4 = m4.makeRotationFromEuler(new THREE.Euler(x || 0, y || 0, z || 0));
|
||||||
|
vc.applyMatrix4(m4);
|
||||||
|
wsup.box.position.x = wsup.x = sup.x = vc.x;
|
||||||
|
wsup.box.position.y = wsup.y = sup.y = vc.y;
|
||||||
|
wsup.box.position.z = wsup.z = sup.z = vc.z;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
api.event.on("mouse.hover.up", int => {
|
api.event.on("mouse.hover.up", int => {
|
||||||
delbox('supp');
|
delbox('supp');
|
||||||
if (!iw) return;
|
if (!iw) return;
|
||||||
|
|
@ -97,7 +127,10 @@
|
||||||
if (int && int.face && int.face.normal.z < -0.1) {
|
if (int && int.face && int.face.normal.z < -0.1) {
|
||||||
dir.y = -1;
|
dir.y = -1;
|
||||||
}
|
}
|
||||||
let targets = api.widgets.meshes().append(SPACE.internals().platform);
|
let targets = api.widgets.meshes()
|
||||||
|
.append(SPACE.internals().platform)
|
||||||
|
.appendAll(activeSupports())
|
||||||
|
;
|
||||||
let i2 = ray.intersectObjects(targets, false);
|
let i2 = ray.intersectObjects(targets, false);
|
||||||
if (i2 && i2.length > 0) {
|
if (i2 && i2.length > 0) {
|
||||||
// prevent false matches close to origin of ray
|
// prevent false matches close to origin of ray
|
||||||
|
|
@ -118,6 +151,18 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function activeSupports() {
|
||||||
|
const active = [];
|
||||||
|
API.widgets.all().forEach(widget => {
|
||||||
|
Object.values(widget.sups || {}).forEach(support => {
|
||||||
|
active.push(support.box);
|
||||||
|
support.box.support = true;
|
||||||
|
// console.log({support});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
function restoreSupports(widgets) {
|
function restoreSupports(widgets) {
|
||||||
widgets.forEach(widget => {
|
widgets.forEach(widget => {
|
||||||
const supports = API.widgets.annotate(widget.id).support || [];
|
const supports = API.widgets.annotate(widget.id).support || [];
|
||||||
|
|
@ -137,6 +182,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateVisiblity() {
|
||||||
|
API.widgets.all().forEach(w => {
|
||||||
|
setSupportVisiblity(w, lastMode === 'FDM' && lastView === API.const.VIEWS.ARRANGE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSupportVisiblity(widget, bool) {
|
||||||
|
Object.values(widget.sups || {}).forEach(support => {
|
||||||
|
support.box.visible = bool;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function clearAllWidgetSupports() {
|
function clearAllWidgetSupports() {
|
||||||
API.widgets.all().forEach(widget => {
|
API.widgets.all().forEach(widget => {
|
||||||
clearWidgetSupports(widget);
|
clearWidgetSupports(widget);
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// synthesize a support widget, if needed
|
// synthesize a support widget, if needed
|
||||||
if (process.sliceSupportEnable) {
|
{
|
||||||
let swidget = KIRI.newWidget();
|
let swidget = KIRI.newWidget();
|
||||||
let sslices = swidget.slices = [];
|
let sslices = swidget.slices = [];
|
||||||
widgets.forEach(function(widget) {
|
widgets.forEach(function(widget) {
|
||||||
|
|
|
||||||
|
|
@ -192,9 +192,6 @@
|
||||||
slice.solids = [];
|
slice.solids = [];
|
||||||
});
|
});
|
||||||
|
|
||||||
let supportEnabled = spro.sliceSupportEnable && spro.sliceSupportDensity > 0.0,
|
|
||||||
supportMinArea = spro.sliceSupportArea;
|
|
||||||
|
|
||||||
// create shells and diff inner fillable areas
|
// create shells and diff inner fillable areas
|
||||||
forSlices(0.0, 0.2, function(slice) {
|
forSlices(0.0, 0.2, function(slice) {
|
||||||
let solid = (
|
let solid = (
|
||||||
|
|
@ -245,12 +242,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculations only relevant when supports are enabled
|
// calculations only relevant when supports are enabled
|
||||||
if (supportEnabled) {
|
// if (supportEnabled) {
|
||||||
|
{
|
||||||
|
let auto = spro.sliceSupportEnable && spro.sliceSupportDensity > 0.0,
|
||||||
|
minArea = spro.sliceSupportArea;
|
||||||
|
|
||||||
|
const fixed = Object.values(settings.widget[widget.id].support || {});
|
||||||
|
|
||||||
forSlices(0.7, 0.8, function(slice) {
|
forSlices(0.7, 0.8, function(slice) {
|
||||||
if (slice.index > 0) doSupport(slice, spro.sliceSupportOffset, spro.sliceSupportSpan, spro.sliceSupportExtra, supportMinArea, spro.sliceSupportSize, spro.sliceSupportOffset, spro.sliceSupportGap);
|
if (slice.index > 0) {
|
||||||
|
doSupport(slice, spro, auto, fixed);
|
||||||
|
}
|
||||||
}, "support");
|
}, "support");
|
||||||
forSlices(0.8, 0.9, function(slice) {
|
forSlices(0.8, 0.9, function(slice) {
|
||||||
doSupportFill(slice, nozzleSize, spro.sliceSupportDensity, supportMinArea);
|
doSupportFill(slice, nozzleSize, spro.sliceSupportDensity, minArea);
|
||||||
}, "support");
|
}, "support");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -794,17 +799,18 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculate external overhangs requiring support
|
* calculate external overhangs requiring support.
|
||||||
* this is done bottom-up
|
* this is done bottom-up except for fixed supports (manual)
|
||||||
*
|
|
||||||
* @param {number} minOffset trigger for unsupported distance
|
|
||||||
* @param {number} maxBridge max length before mid supports added
|
|
||||||
* @param {number} expand outer support clip
|
|
||||||
* @param {number} offset inner support clip
|
|
||||||
* @param {number} gap layers between supports and part
|
|
||||||
*/
|
*/
|
||||||
function doSupport(slice, minOffset, maxBridge, expand, minArea, pillarSize, offset, gap) {
|
function doSupport(slice, proc, auto, fixed) {
|
||||||
let min = minArea || 0.01,
|
let minOffset = proc.sliceSupportOffset,
|
||||||
|
maxBridge = proc.sliceSupportSpan,
|
||||||
|
expand = proc.sliceSupportExtra,
|
||||||
|
minArea = proc.supportMinArea,
|
||||||
|
pillarSize = proc.sliceSupportSize,
|
||||||
|
offset = proc.sliceSupportOffset,
|
||||||
|
gap = proc.sliceSupportGap,
|
||||||
|
min = minArea || 0.01,
|
||||||
size = (pillarSize || 1),
|
size = (pillarSize || 1),
|
||||||
mergeDist = size * 3, // pillar merge dist
|
mergeDist = size * 3, // pillar merge dist
|
||||||
tops = slice.topPolys(),
|
tops = slice.topPolys(),
|
||||||
|
|
@ -865,29 +871,47 @@
|
||||||
|
|
||||||
let supports = [];
|
let supports = [];
|
||||||
|
|
||||||
// add offset solids to supports (or fill depending)
|
// generate support polys from unsupported points
|
||||||
fill.forEachPair(function(p1,p2) { checkLineSupport(p1, p2, false) });
|
if (auto) (function() {
|
||||||
// if (top.bridges) POLY.expand(top.bridges, -maxBridge/2, top.z, supports, 1);
|
// add offset solids to supports (or fill depending)
|
||||||
|
fill.forEachPair(function(p1,p2) { checkLineSupport(p1, p2, false) });
|
||||||
|
// if (top.bridges) POLY.expand(top.bridges, -maxBridge/2, top.z, supports, 1);
|
||||||
|
|
||||||
// skip the rest if no points or supports
|
// skip the rest if no points or supports
|
||||||
if (!(points.length || supports.length)) return;
|
if (!(points.length || supports.length)) return;
|
||||||
|
|
||||||
let pillars = [];
|
let pillars = [];
|
||||||
|
|
||||||
// TODO project points down instead of unioned pillars
|
// TODO project points down instead of unioned pillars
|
||||||
// TODO merge point/rect into hull of next nearest (up to maxBridge/2 away)
|
// TODO merge point/rect into hull of next nearest (up to maxBridge/2 away)
|
||||||
// TODO eliminate unions in favor of progress hulling (using previous w/nearness)
|
// TODO eliminate unions in favor of progress hulling (using previous w/nearness)
|
||||||
// TODO align pillar diamond along line (when doing line checks)
|
// TODO align pillar diamond along line (when doing line checks)
|
||||||
|
|
||||||
// for each point, create a bounding rectangle
|
// for each point, create a bounding rectangle
|
||||||
points.forEach(function(point) {
|
points.forEach(function(point) {
|
||||||
pillars.push(BASE.newPolygon().centerRectangle(point, size/2, size/2));
|
pillars.push(BASE.newPolygon().centerRectangle(point, size/2, size/2));
|
||||||
});
|
});
|
||||||
|
|
||||||
// merge pillars and replace with convex hull of outer points (aka smoothing)
|
// merge pillars and replace with convex hull of outer points (aka smoothing)
|
||||||
pillars = POLY.union(pillars).forEach(function(pillar) {
|
pillars = POLY.union(pillars).forEach(function(pillar) {
|
||||||
supports.push(BASE.newPolygon().createConvexHull(pillar.points));
|
supports.push(BASE.newPolygon().createConvexHull(pillar.points));
|
||||||
});
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (supports.length === 0 && !(fixed && fixed.length)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixed && fixed.length) {
|
||||||
|
fixed.forEach(sup => {
|
||||||
|
let zmin = sup.z - sup.dh / 2;
|
||||||
|
let zmax = sup.z + sup.dh / 2;
|
||||||
|
if (slice.z >= zmin || slice.z <= zmax) {
|
||||||
|
let center = BASE.newPoint(sup.x, sup.y, slice.z);
|
||||||
|
supports.push(BASE.newPolygon().centerRectangle(center, sup.dw, sup.dw));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// return top.supports = supports;
|
// return top.supports = supports;
|
||||||
// then union supports
|
// then union supports
|
||||||
|
|
@ -924,8 +948,7 @@
|
||||||
down = down.down;
|
down = down.down;
|
||||||
depth++;
|
depth++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} linewidth
|
* @param {number} linewidth
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue