re-enable and update belt bed / slice rotation

This commit is contained in:
Stewart Allen 2020-12-04 19:44:31 -05:00
commit a0f08f0776
11 changed files with 63 additions and 41 deletions

View file

@ -61,20 +61,18 @@
# CAM # CAM
* `B` starting export during animation unleashes chaos * `B` starting export during animation unleashes chaos
* `B` crossing interior open spaces doesn't lift high enough
* https://forum.grid.space/t/g0-movement-hits-the-stock-using-custom-tabs-positioning/171/2
* `B` climb vs conventional not fully consistent after refactor * `B` climb vs conventional not fully consistent after refactor
* `B` outside cutting direction in roughing mode inverted * `B` outside cutting direction in roughing mode inverted
* `B` top clearing operations should use linear, not offset, passes * `B` top clearing operations should use linear, not offset, passes
* `F` exports separate files for each operation
* `F` animation should clear the mesh in areas where the cuts go through the stock?
* `F` switch z top offset to an z anchor (top/bottom) + offset
* `F` use 3 registration holes to prevent rotation accidents (midline offset one axis) * `F` use 3 registration holes to prevent rotation accidents (midline offset one axis)
* `F` exports separate files for each operation
* `F` switch z top offset to a z anchor (top/bottom) + offset
* `F` A-B linked cutting profiles for double-sided milling / part flips
* `F` parameterize dropping close points in prep.js. ensure long segments remain straight * `F` parameterize dropping close points in prep.js. ensure long segments remain straight
* `F` flat and volumetric rendering of paths * `F` flat and volumetric rendering of paths
* `F` z bounded slices (extension of z bottom offset feature) * `F` z bounded slices (extension of z bottom offset feature)
* `F` z planar settings visualizations * `F` z planar settings visualizations
* `F` use arcs to connect acute angles * `F` convert acute angles to arcs
* `F` extend acute roughing on inside polys to clear small voids * `F` extend acute roughing on inside polys to clear small voids
* `F` lead-in milling * `F` lead-in milling
* `F` adaptive clearing in roughing mode * `F` adaptive clearing in roughing mode
@ -84,7 +82,7 @@
* `F` add option to spiral in vs out (optimal tool life) vs mixed (optimal path) * `F` add option to spiral in vs out (optimal tool life) vs mixed (optimal path)
* `F` add support for tapered ball mills * `F` add support for tapered ball mills
* `F` warn when part > stock or cuts go outside bed * `F` warn when part > stock or cuts go outside bed
* `F` A-B linked cutting profiles for double-sided milling / part flips * `F` animation should clear the mesh in areas where the cuts go through the stock?
* `P` crossing open space check point is outside camshell before returning max z * `P` crossing open space check point is outside camshell before returning max z
* `P` detect render message backlog and pause or warn * `P` detect render message backlog and pause or warn
* `P` redo all path route / planning in prepare to account for terrain before camOut * `P` redo all path route / planning in prepare to account for terrain before camOut

View file

@ -145,10 +145,10 @@ KIRI.work = {
slice: function(settings, widget, callback) { slice: function(settings, widget, callback) {
CLIENT.sync(widget); CLIENT.sync(widget);
slicing[widget.id] = callback; slicing[widget.id] = callback;
send("slice", { send("slice", {
id: widget.id, id: widget.id,
settings: settings, settings: settings
rotation: (Math.PI/180) * (settings.process.sliceRotation || 0)
}, function(reply) { }, function(reply) {
if (reply.done || reply.error) { if (reply.done || reply.error) {
delete slicing[widget.id]; delete slicing[widget.id];

View file

@ -108,6 +108,7 @@
bedWidth: valueOf(set.bed_width, 300), bedWidth: valueOf(set.bed_width, 300),
bedDepth: valueOf(set.bed_depth, 175), bedDepth: valueOf(set.bed_depth, 175),
bedRound: valueOf(set.bed_circle, false), bedRound: valueOf(set.bed_circle, false),
bedBelt: valueOf(set.bed_belt, false),
maxHeight: valueOf(set.build_height, 150), maxHeight: valueOf(set.build_height, 150),
originCenter: valueOf(set.origin_center, false), originCenter: valueOf(set.origin_center, false),
extrudeAbs: valueOf(set.extrude_abs, false), extrudeAbs: valueOf(set.extrude_abs, false),
@ -257,6 +258,7 @@
bedDepth: 175, bedDepth: 175,
bedHeight: 2.5, bedHeight: 2.5,
bedRound: false, bedRound: false,
bedBelt: false,
originCenter: false, originCenter: false,
maxHeight: 150, maxHeight: 150,
gcodePre: [], gcodePre: [],
@ -334,8 +336,7 @@
sliceAdaptive: false, sliceAdaptive: false,
zHopDistance: 0.2, zHopDistance: 0.2,
antiBacklash: 1, antiBacklash: 1,
gcodePause: "", gcodePause: ""
sliceRotation: 0
} }
}, },
sla:{ sla:{

View file

@ -662,6 +662,7 @@
dev.deviceName = devicename; dev.deviceName = devicename;
UI.deviceName.value = devicename; UI.deviceName.value = devicename;
UI.deviceBelt.checked = dev.bedBelt;
UI.deviceRound.checked = dev.bedRound; UI.deviceRound.checked = dev.bedRound;
UI.deviceOrigin.checked = dev.outputOriginCenter || dev.originCenter; UI.deviceOrigin.checked = dev.outputOriginCenter || dev.originCenter;
@ -699,6 +700,7 @@
UI.extrudeAbs, UI.extrudeAbs,
UI.deviceOrigin, UI.deviceOrigin,
UI.deviceRound, UI.deviceRound,
UI.deviceBelt,
UI.gcodeFan, UI.gcodeFan,
UI.gcodeTrack, UI.gcodeTrack,
UI.gcodeLayer, UI.gcodeLayer,
@ -1435,6 +1437,7 @@
spindleMax: UC.newInput(LANG.dv_spmx_s, {title:LANG.dv_spmx_l, convert:UC.toInt, size: 6, modes:CAM}), spindleMax: UC.newInput(LANG.dv_spmx_s, {title:LANG.dv_spmx_l, convert:UC.toInt, size: 6, modes:CAM}),
deviceOrigin: UC.newBoolean(LANG.dv_orgc_s, onBooleanClick, {title:LANG.dv_orgc_l, modes:FDM_LASER_SLA}), deviceOrigin: UC.newBoolean(LANG.dv_orgc_s, onBooleanClick, {title:LANG.dv_orgc_l, modes:FDM_LASER_SLA}),
deviceRound: UC.newBoolean(LANG.dv_bedc_s, onBooleanClick, {title:LANG.dv_bedc_l, modes:FDM}), deviceRound: UC.newBoolean(LANG.dv_bedc_s, onBooleanClick, {title:LANG.dv_bedc_l, modes:FDM}),
deviceBelt: UC.newBoolean(LANG.dv_belt_s, onBooleanClick, {title:LANG.dv_belt_l, modes:FDM}),
extruder: UC.newGroup(LANG.dv_gr_ext, $('device'), {group:"dext", inline:true, modes:FDM}), extruder: UC.newGroup(LANG.dv_gr_ext, $('device'), {group:"dext", inline:true, modes:FDM}),
extFilament: UC.newInput(LANG.dv_fila_s, {title:LANG.dv_fila_l, convert:UC.toFloat, modes:FDM}), extFilament: UC.newInput(LANG.dv_fila_s, {title:LANG.dv_fila_l, convert:UC.toFloat, modes:FDM}),
@ -1714,7 +1717,6 @@
zHopDistance: UC.newInput(LANG.ad_zhop_s, {title:LANG.ad_zhop_l, bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM, expert:true}), zHopDistance: UC.newInput(LANG.ad_zhop_s, {title:LANG.ad_zhop_l, bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM, expert:true}),
antiBacklash: UC.newInput(LANG.ad_abkl_s, {title:LANG.ad_abkl_l, bound:UC.bound(0,3), convert:UC.toInt, modes:FDM, expert:true}), antiBacklash: UC.newInput(LANG.ad_abkl_s, {title:LANG.ad_abkl_l, bound:UC.bound(0,3), convert:UC.toInt, modes:FDM, expert:true}),
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}), fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
sliceRotation: LOCAL ? UC.newInput(LANG.ad_slrt_s, {title:LANG.ad_slrt_l, bound:UC.bound(-45,45), convert:UC.toFloat, modes:FDM, expert:true}) : null,
gcodePauseLayers: UC.newInput(LANG.ag_paws_s, {title:LANG.ag_paws_l, modes:FDM, expert:true, comma:true}), gcodePauseLayers: UC.newInput(LANG.ag_paws_s, {title:LANG.ag_paws_l, modes:FDM, expert:true, comma:true}),
outputLayerRetract: UC.newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l, modes:FDM, expert:true}), outputLayerRetract: UC.newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l, modes:FDM, expert:true}),

View file

@ -759,9 +759,6 @@
mode = settings.mode, mode = settings.mode,
now = Date.now(); now = Date.now();
// require topo be sent back from worker for local printing
settings.synth.sendTopo = false;
setOpacity(color.slicing_opacity); setOpacity(color.slicing_opacity);
STACKS.clear(); STACKS.clear();
@ -790,6 +787,10 @@
} }
// on done // on done
segtimes[`${segNumber}_draw`] = widget.render(stack); segtimes[`${segNumber}_draw`] = widget.render(stack);
// rotate stack for belt beds
if (settings.device.bedBelt && widget.rotinfo) {
STACKS.rotate(widget.rotinfo);
}
updateSliderMax(true); updateSliderMax(true);
setVisibleLayer(-1, 0); setVisibleLayer(-1, 0);
// clear wireframe // clear wireframe
@ -904,6 +905,10 @@
output.forEach(layer => { output.forEach(layer => {
stack.add(layer); stack.add(layer);
}); });
// rotate stack for belt beds
if (settings.device.bedBelt && WIDGETS[0].rotinfo) {
STACKS.rotate(WIDGETS[0].rotinfo);
}
segtimes[`${segNumber}_draw`] = Date.now() - startTime; segtimes[`${segNumber}_draw`] = Date.now() - startTime;
} }
@ -1708,6 +1713,7 @@
} }
const mode = settings.mode; const mode = settings.mode;
settings.sproc[mode].default = settings.process; settings.sproc[mode].default = settings.process;
settings.device.bedBelt = UI.deviceBelt.checked;
settings.device.bedRound = UI.deviceRound.checked; settings.device.bedRound = UI.deviceRound.checked;
settings.device.originCenter = UI.deviceOrigin.checked; settings.device.originCenter = UI.deviceOrigin.checked;
SDB.setItem('ws-settings', JSON.stringify(settings)); SDB.setItem('ws-settings', JSON.stringify(settings));

View file

@ -25,6 +25,11 @@
this.view.visible = true; this.view.visible = true;
} }
rotate(set) {
this.view.rotation.y = -set.angle * (Math.PI/180);
this.view.position.x = +set.centerz - set.movez;
}
destroy() { destroy() {
this._view.remove(this.view); this._view.remove(this.view);
this.view = this.slices = this.meshes = null; this.view = this.slices = this.meshes = null;

View file

@ -41,6 +41,12 @@
labels.innerHTML = ''; labels.innerHTML = '';
} }
function rotate(set) {
Object.values(stacks).forEach(stack => {
stack.obj.rotate(set);
});
}
function getStack(name) { function getStack(name) {
return stacks[name]; return stacks[name];
} }
@ -107,6 +113,7 @@
KIRI.stacks = { KIRI.stacks = {
clear, clear,
create, create,
rotate,
remove, remove,
getStack, getStack,
getRange, getRange,

View file

@ -599,12 +599,15 @@
if (reply.slice) { if (reply.slice) {
widget.slices.push(KIRI.codec.decode(reply.slice, {mesh:widget.mesh})); widget.slices.push(KIRI.codec.decode(reply.slice, {mesh:widget.mesh}));
} }
if (reply.error) { if (reply.rotinfo) {
ondone(false, reply.error); widget.rotinfo = reply.rotinfo;
} }
if (reply.done) { if (reply.done) {
ondone(true); ondone(true);
} }
if (reply.error) {
ondone(false, reply.error);
}
}); });
} }

View file

@ -46,6 +46,8 @@ KIRI.worker = {
// do it here so cancel can work // do it here so cancel can work
cache[data.id] = widget; cache[data.id] = widget;
// stored for possible future rotations
widget.vertices = vertices;
// fake mesh object to satisfy printing // fake mesh object to satisfy printing
widget.track = data.tracking; widget.track = data.tracking;
@ -58,24 +60,7 @@ KIRI.worker = {
}, },
slice: function(data, send) { slice: function(data, send) {
let { id, settings, rotation } = data; let { id, settings } = data;
// let centerz;
// let movez;
// if (rotation) {
// let bbox1 = widget.getBoundingBox(true);
// widget._rotate(0,rotation,0,true);
// widget.center();
// let bbox2 = widget.getBoundingBox(true);
// centerz = (bbox2.max.z - bbox2.min.z)/2;
// movez = centerz - (bbox1.max.z - bbox1.min.z)/2;
// }
// let vertices = widget.getGeoVertices().buffer.slice(0);
// // snapshot = KIRI.api.view.snapshot;
// if (rotation) {
// widget._rotate(0,-rotation,0,true);
// widget.center();
// }
send.data({update:0.05, updateStatus:"slicing"}); send.data({update:0.05, updateStatus:"slicing"});
@ -85,17 +70,31 @@ KIRI.worker = {
try { try {
let rotation = (Math.PI/180) * (settings.device.bedBelt ? 45 : 0);
if (rotation && !widget.rotated) {
widget.mesh = null;
widget.points = null;
widget.loadVertices(widget.vertices);
let bbox1 = widget.getBoundingBox(true);
widget._rotate(0,rotation,0,true);
widget.center();
widget.rotated = true;
let bbox2 = widget.getBoundingBox(true);
let centerz = (bbox2.max.z - bbox2.min.z) / 2;
let movez = centerz - (bbox1.max.z - bbox1.min.z) / 2;
widget.rotinfo = { centerz, movez, angle: 45 };
}
widget.slice(settings, function(error) { widget.slice(settings, function(error) {
if (error) { if (error) {
// delete cache[id];
send.data({error: error}); send.data({error: error});
} else { } else {
const slices = widget.slices || []; const slices = widget.slices || [];
send.data({send_start: time()}); send.data({send_start: time()});
send.data({ send.data({
topo: settings.synth.sendTopo ? widget.topo : null,
stats: widget.stats, stats: widget.stats,
slices: slices.length slices: slices.length,
rotinfo: widget.rotinfo
}); });
slices.forEach(function(slice,index) { slices.forEach(function(slice,index) {
const state = { zeros: [] }; const state = { zeros: [] };

View file

@ -461,6 +461,7 @@ th, tr, td, label {
text-align: center; text-align: center;
flex-grow: 1; flex-grow: 1;
margin-top: 3px; margin-top: 3px;
height: 75%;
} }
.txt-sel { .txt-sel {
background-color: #eee; background-color: #eee;
@ -1092,7 +1093,7 @@ th, tr, td, label {
justify-content: center; justify-content: center;
border-radius: 2px; border-radius: 2px;
padding: 1px 0 2px 0; padding: 1px 0 2px 0;
margin: 5px 0 5px 0; margin: 2px 0 3px 0;
} }
.set-group { .set-group {
align-items: center; align-items: center;

View file

@ -36,6 +36,8 @@ kiri.lang['en-us'] = {
dv_orgt_l: "part z origin top", dv_orgt_l: "part z origin top",
dv_bedc_s: "circular bed", dv_bedc_s: "circular bed",
dv_bedc_l: "device bed is circular", dv_bedc_l: "device bed is circular",
dv_belt_s: "belt bed",
dv_belt_l: "continuous printing bed",
dv_fanp_s: "fan power", dv_fanp_s: "fan power",
dv_fanp_l: "set cooling fan power", dv_fanp_l: "set cooling fan power",
dv_prog_s: "progress", dv_prog_s: "progress",
@ -451,8 +453,6 @@ kiri.lang['en-us'] = {
ad_zhop_l: "amount to raise z\non retraction moves\nin millimeters\n0 to disable", ad_zhop_l: "amount to raise z\non retraction moves\nin millimeters\n0 to disable",
ad_abkl_s: "anti-backlash", ad_abkl_s: "anti-backlash",
ad_abkl_l: "use micro-movements to cancel\nbacklash during fills\nin millimeters", ad_abkl_l: "use micro-movements to cancel\nbacklash during fills\nin millimeters",
ad_slrt_s: "slice rotation",
ad_slrt_l: "slice object on a bias\nangle in the y axis.\nuseful for extremely\nlarge format prints",
ad_lret_s: "layer retract", ad_lret_s: "layer retract",
ad_lret_l: "force filament retraction\nbetween layers", ad_lret_l: "force filament retraction\nbetween layers",
ad_play_s: "polish layers", ad_play_s: "polish layers",