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
* `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` outside cutting direction in roughing mode inverted
* `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` 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` flat and volumetric rendering of paths
* `F` z bounded slices (extension of z bottom offset feature)
* `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` lead-in milling
* `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 support for tapered ball mills
* `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` detect render message backlog and pause or warn
* `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) {
CLIENT.sync(widget);
slicing[widget.id] = callback;
send("slice", {
id: widget.id,
settings: settings,
rotation: (Math.PI/180) * (settings.process.sliceRotation || 0)
settings: settings
}, function(reply) {
if (reply.done || reply.error) {
delete slicing[widget.id];

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -46,6 +46,8 @@ KIRI.worker = {
// do it here so cancel can work
cache[data.id] = widget;
// stored for possible future rotations
widget.vertices = vertices;
// fake mesh object to satisfy printing
widget.track = data.tracking;
@ -58,24 +60,7 @@ KIRI.worker = {
},
slice: function(data, send) {
let { id, settings, rotation } = 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();
// }
let { id, settings } = data;
send.data({update:0.05, updateStatus:"slicing"});
@ -85,17 +70,31 @@ KIRI.worker = {
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) {
if (error) {
// delete cache[id];
send.data({error: error});
} else {
const slices = widget.slices || [];
send.data({send_start: time()});
send.data({
topo: settings.synth.sendTopo ? widget.topo : null,
stats: widget.stats,
slices: slices.length
slices: slices.length,
rotinfo: widget.rotinfo
});
slices.forEach(function(slice,index) {
const state = { zeros: [] };

View file

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

View file

@ -36,6 +36,8 @@ kiri.lang['en-us'] = {
dv_orgt_l: "part z origin top",
dv_bedc_s: "circular bed",
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_l: "set cooling fan power",
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_abkl_s: "anti-backlash",
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_l: "force filament retraction\nbetween layers",
ad_play_s: "polish layers",