refactor platform grid and axis labels. checkpoint belt updates

This commit is contained in:
Stewart Allen 2021-01-08 21:56:46 -05:00
commit bab96a1faa
5 changed files with 222 additions and 163 deletions

View file

@ -968,6 +968,7 @@
found.classList.remove("selected"); found.classList.remove("selected");
} }
found = opt; found = opt;
API.platform.layout();
}; };
if (loc) { if (loc) {
UI.deviceMy.appendChild(opt); UI.deviceMy.appendChild(opt);

View file

@ -976,6 +976,9 @@
}); });
// rotate stack for belt beds // rotate stack for belt beds
if (settings.device.bedBelt && WIDGETS[0].rotinfo) { if (settings.device.bedBelt && WIDGETS[0].rotinfo) {
let ri = WIDGETS[0].rotinfo;
console.log({ri})
ri.dy = ri.dz = 0;
STACKS.rotate(WIDGETS[0].rotinfo); STACKS.rotate(WIDGETS[0].rotinfo);
} }
segtimes[`${segNumber}_draw`] = Date.now() - startTime; segtimes[`${segNumber}_draw`] = Date.now() - startTime;
@ -1280,15 +1283,17 @@
y = -b.min.y y = -b.min.y
} else { } else {
x = -dev.bedWidth / 2; x = -dev.bedWidth / 2;
y = isBelt ? 0 : dev.bedDepth / 2; y = dev.bedDepth / 2;
} }
} }
} else if (hasStock) { } else if (hasStock) {
x = stockCenter.x; x = stockCenter.x;
y = -stockCenter.y; y = -stockCenter.y;
} else if (isBelt) {
y = dev.bedDepth / 2;
} }
settings.origin = {x, y, z}; settings.origin = {x, y, z};
SPACE.platform.setRulers(ruler, ruler, center, 1/unitScale()); SPACE.platform.setRulers(ruler, ruler, 1/unitScale(), 'X', isBelt ? 'Z' : 'Y');
if (settings.controller.showOrigin && MODE !== MODES.SLA) { if (settings.controller.showOrigin && MODE !== MODES.SLA) {
SPACE.platform.setOrigin(x,y,z); SPACE.platform.setOrigin(x,y,z);
} else { } else {
@ -1326,6 +1331,7 @@
function platformUpdateSize() { function platformUpdateSize() {
let dev = settings.device, let dev = settings.device,
isBelt = dev.bedBelt,
width, depth, width, depth,
height = Math.round(Math.max(dev.bedHeight, dev.bedWidth/100, dev.bedDepth/100)); height = Math.round(Math.max(dev.bedHeight, dev.bedWidth/100, dev.bedDepth/100));
SPACE.platform.setRound(dev.bedRound); SPACE.platform.setRound(dev.bedRound);
@ -1352,7 +1358,7 @@
SPACE.setSkyColor(0xffffff); SPACE.setSkyColor(0xffffff);
DOC.body.classList.remove('dark'); DOC.body.classList.remove('dark');
} }
SPACE.platform.setRulers(ruler, ruler, proc.outputOriginCenter, 1/unitScale()); SPACE.platform.setRulers(ruler, ruler, 1 / unitScale(), 'X', isBelt ? 'Z' : 'Y');
SPACE.platform.setGZOff(height/2 - 0.1); SPACE.platform.setGZOff(height/2 - 0.1);
platform.update_origin(); platform.update_origin();
} }
@ -1614,6 +1620,8 @@
function platformLayout(event, space) { function platformLayout(event, space) {
let auto = UI.autoLayout.checked, let auto = UI.autoLayout.checked,
proc = settings.process, proc = settings.process,
dev = settings.device,
isBelt = dev.bedBelt,
oldmode = viewMode, oldmode = viewMode,
layout = (viewMode === VIEWS.ARRANGE && auto); layout = (viewMode === VIEWS.ARRANGE && auto);
@ -1676,6 +1684,11 @@
// m.material.visible = true; // m.material.visible = true;
} }
if (isBelt) {
let bounds = platformUpdateBounds(), movey = -(dev.bedDepth / 2 + bounds.min.y);
forAllWidgets(widget => widget.move(0, movey + 10, 0));
}
platform.update_origin(); platform.update_origin();
API.event.emit('platform.layout'); API.event.emit('platform.layout');

View file

@ -194,7 +194,7 @@
} }
// synthesize a support widget, if needed // synthesize a support widget, if needed
{ if (!isBelt) {
let swidget = KIRI.newWidget(); let swidget = KIRI.newWidget();
let sslices = swidget.slices = []; let sslices = swidget.slices = [];
widgets.forEach(function(widget) { widgets.forEach(function(widget) {
@ -284,6 +284,8 @@
} }
} }
const center = {x:0, y:0, z:0};
// increment layer count until no widget has remaining slices // increment layer count until no widget has remaining slices
for (;;) { for (;;) {
// create list of mesh slice arrays with their platform offsets // create list of mesh slice arrays with their platform offsets
@ -292,12 +294,18 @@
if (!mesh.widget) { if (!mesh.widget) {
continue; continue;
} }
let mslices = mesh.widget.slices; let widget = mesh.widget;
let mslices = widget.slices;
if (mslices && mslices[layer]) { if (mslices && mslices[layer]) {
let offset = mesh.position || center;
if (isBelt) {
offset = Object.clone(offset);
offset.y -= widget.belt_offset || 0;
}
slices.push({ slices.push({
slice: mslices[layer], slice: mslices[layer],
offset: mesh.position || {x:0, y:0, z:0}, offset: offset,
widget: mesh.widget widget: widget
}); });
} }
} }

View file

@ -267,13 +267,13 @@
}, "render"); }, "render");
} }
// if (isBelt) { if (isBelt) {
// let bounds = BASE.newBounds(); let bounds = BASE.newBounds();
// for (let top of slices[0].tops) { for (let top of slices[0].tops) {
// bounds.merge(top.poly.bounds); bounds.merge(top.poly.bounds);
// } }
// console.log({z_anchor_bounds: bounds}); widget.belt_offset = bounds.miny;
// } }
// report slicing complete // report slicing complete
ondone(); ondone();

View file

@ -34,6 +34,7 @@
showSkyGrid = false, showSkyGrid = false,
showPlatform = true, showPlatform = true,
hidePlatformBelow = true, hidePlatformBelow = true,
origin = {x:0, y:0, z: 0},
trackcam = addLight(0, 0, 0, lightIntensity/3), trackcam = addLight(0, 0, 0, lightIntensity/3),
trackDelta = {x:0, y:0, z:0}, trackDelta = {x:0, y:0, z:0},
mouse = {x: 0, y: 0}, mouse = {x: 0, y: 0},
@ -46,21 +47,28 @@
mouseDown, mouseDown,
mouseHover, mouseHover,
mouseDrag, mouseDrag,
gridOrigin, grid = {
gridUnitMinor, origin: undefined,
gridUnitMajor, unitMinor: 0,
gridColorMajor, unitMajor: 0,
gridColorMinor, colorMinor: 0,
gridView, colorMajor: 0,
rulersView, zoff: 0,
rulerXFirst = null, view: undefined
rulerXLast = null, },
rulerYFirst = null, ruler = {
rulerYLast = null, x1: 0,
rulerX = true, x2: 0,
rulerY = true, y1: 0,
rulerCenter = true, y2: 0,
rulerFactor = 1, xlabel: 'X',
ylabel: 'Y',
xon: undefined,
yon: undefined,
factor: undefined,
view: undefined
},
timers = {},
fontColor = '#333333', fontColor = '#333333',
fontScale = 1.4, // computed relative to grid size fontScale = 1.4, // computed relative to grid size
rulerColor, rulerColor,
@ -120,6 +128,11 @@
lastAction = Date.now(); lastAction = Date.now();
} }
function delayed(key, time, fn) {
clearTimeout(timers[key]);
timers[key] = setTimeout(fn, time);
}
/** ****************************************************************** /** ******************************************************************
* TWEENing Functions * TWEENing Functions
******************************************************************* */ ******************************************************************* */
@ -155,10 +168,8 @@
function tweenPlatform(w,h,d) { function tweenPlatform(w,h,d) {
let from = {x: platform.scale.x, y: platform.scale.y, z: platform.scale.z}, let from = {x: platform.scale.x, y: platform.scale.y, z: platform.scale.z},
to = {x:w, y:h, z:d}, to = {x:w, y:h, z:d},
gridMajor = gridUnitMajor,
gridMinor = gridUnitMinor,
start = function() { start = function() {
setGrid(0); setGrid();
}, },
update = function() { update = function() {
setPlatformSize(this.x, this.y, this.z); setPlatformSize(this.x, this.y, this.z);
@ -166,7 +177,7 @@
refresh(); refresh();
}, },
complete = function() { complete = function() {
setGrid(gridMajor, gridMinor, gridColorMajor, gridColorMinor); setGrid();
}; };
new TWEEN.Tween(from). new TWEEN.Tween(from).
to(to, 500). to(to, 500).
@ -268,7 +279,7 @@
function setPlatformSizeUpdateGrid(width, depth, height, maxz) { function setPlatformSizeUpdateGrid(width, depth, height, maxz) {
freeze = { width, depth, height, maxz }; freeze = { width, depth, height, maxz };
setPlatformSize(width, depth, height, maxz); setPlatformSize(width, depth, height, maxz);
setGrid(gridUnitMajor, gridUnitMinor); setGrid(grid.unitMajor, grid.unitMinor);
clearTimeout(freezeTo); clearTimeout(freezeTo);
freezeTo = setTimeout(() => { freeze = undefined }, 10); freezeTo = setTimeout(() => { freeze = undefined }, 10);
} }
@ -285,12 +296,12 @@
if (options.scale) fontScale = options.scale; if (options.scale) fontScale = options.scale;
if (options.axisColor) axisColor = options.axisColor; if (options.axisColor) axisColor = options.axisColor;
if (options.rulerColor) rulerColor = options.rulerColor; if (options.rulerColor) rulerColor = options.rulerColor;
setRulers(); updateRulers();
} }
function setAxes(bool) { function setAxes(bool) {
axesOn = bool; axesOn = bool;
setRulers(); updateRulers();
} }
function setVolume(bool) { function setVolume(bool) {
@ -299,163 +310,188 @@
requestRefresh(); requestRefresh();
} }
function setRulers(drawX = rulerX, drawY = rulerY, offsetCenter = rulerCenter, factor = rulerFactor) { function canvasInMesh(w, h, textAlign, textBaseline, color, size) {
rulerX = drawX; let canvas = document.createElement('canvas'),
rulerY = drawY; canvasTexture = new THREE.CanvasTexture(canvas),
rulerCenter = offsetCenter; plane = new THREE.PlaneGeometry(w, h),
rulerFactor = factor; context = canvas.getContext('2d'),
scale = 8;
let x = platform.scale.x, canvas.width = w * scale;
y = isRound ? platform.scale.z : platform.scale.y, canvas.height = h * scale;
z = isRound ? platform.scale.y : platform.scale.z,
w = x / 2,
h = y / 2,
d = z / 2,
zp = -d - platformZOff + gridZOff,
oldRulersView = rulersView,
labelSize = gridUnitMinor * fontScale;
let canvasInMesh = function(w, h, textAlign, textBaseline, color) { context.scale(scale, scale);
let canvas = document.createElement('canvas'), context.fillStyle = color || fontColor;
ctx = canvas.getContext('2d'), context.font = `${size}px sans-serif`;
scale = 8, context.textAlign = textAlign;
plane, context.textBaseline = textBaseline;
canvasTexture, canvasTexture.minFilter = THREE.LinearFilter;
material,
mesh;
canvas.width = w * scale; // set 'transparent' to false to debug mesh bounds
canvas.height = h * scale; let material = new THREE.MeshBasicMaterial({transparent: true, map: canvasTexture});
ctx.scale(scale, scale); let mesh = new THREE.Mesh(plane, material);
ctx.fillStyle = color || fontColor;
ctx.font = labelSize + 'px sans-serif';
ctx.textAlign = textAlign;
ctx.textBaseline = textBaseline;
plane = new THREE.PlaneGeometry(w, h);
canvasTexture = new THREE.CanvasTexture(canvas);
canvasTexture.minFilter = THREE.LinearFilter;
// set 'transparent' to false to debug mesh bounds
material = new THREE.MeshBasicMaterial({transparent: true, map: canvasTexture});
mesh = new THREE.Mesh(plane, material);
return {ctx: ctx, mesh: mesh};
}
if (drawX || drawY) { return { context, mesh };
rulersView = new THREE.Group();
} else {
rulersView = null;
}
if (drawX) {
const xPadding = labelSize * 4;
const canvas = canvasInMesh(x + xPadding, labelSize * 3, 'center', 'top', rulerColor);
for (let i = rulerXFirst; i <= rulerXLast; i += gridUnitMajor) {
const label = ((offsetCenter ? i - (rulerXLast + rulerXFirst) / 2 : i) * factor).round(1);
canvas.ctx.fillText('' + label, i + xPadding / 2, 0);
}
canvas.mesh.position.set(0, - h - labelSize * 2, zp);
rulersView.add(canvas.mesh);
if (axesOn) {
canvas.ctx.font = (labelSize * 0.75) + 'px sans-serif';
canvas.ctx.fillText('X', (x + xPadding)/2, labelSize * 1.5);
canvas.ctx.font = labelSize + 'px sans-serif';
}
}
if (drawY) {
const yPadding = labelSize;
const canvas = canvasInMesh(labelSize * 4, y + yPadding, 'end', 'middle', rulerColor);
for (let i = rulerYFirst; i <= rulerYLast; i += gridUnitMajor) {
const label = ((offsetCenter ? -(i - (rulerYLast + rulerYFirst) / 2) :
rulerYFirst + rulerYLast - i) * factor).round(1);
canvas.ctx.fillText('' + label, labelSize * 4, i + yPadding / 2);
}
canvas.mesh.position.set(-w - labelSize * 2 - 5, 0, zp);
rulersView.add(canvas.mesh);
if (axesOn) {
canvas.ctx.font = (labelSize * 0.75) + 'px sans-serif';
canvas.ctx.fillText('Y', labelSize*1.25, (y + yPadding)/2);
canvas.ctx.font = labelSize + 'px sans-serif';
}
}
if (oldRulersView) Space.scene.remove(oldRulersView);
if (rulersView) Space.scene.add(rulersView);
Space.refresh();
} }
function setGrid(unitMajor, unitMinor, colorMajor, colorMinor) {
if (!unitMajor) return; function setRulers(xon = ruler.xon, yon = ruler.yon, factor = ruler.factor, xl = ruler.xlabel, yl = ruler.ylabel) {
let oldGridView = gridView; if (xon !== ruler.xon || yon !== ruler.yon || factor !== ruler.factor || xl !== ruler.xlabel || yl !== ruler.ylabel) {
gridView = new THREE.Group(); ruler.factor = factor;
gridUnitMajor = unitMajor; ruler.xon = xon;
gridUnitMinor = unitMinor; ruler.yon = yon;
gridColorMajor = colorMajor || gridColorMajor; ruler.xlabel = xl;
gridColorMinor = colorMinor || gridColorMinor; ruler.ylabel = yl;
updateRulers();
}
}
function updateRulers() {
let { xon, yon, factor, xlabel, ylabel } = ruler;
let x = platform.scale.x, let x = platform.scale.x,
y = isRound ? platform.scale.z : platform.scale.y, y = isRound ? platform.scale.z : platform.scale.y,
z = isRound ? platform.scale.y : platform.scale.z, z = isRound ? platform.scale.y : platform.scale.z,
xr = Math.ceil(x/2 / unitMinor) * unitMinor,
yr = Math.ceil(y/2 / unitMinor) * unitMinor,
xo = isRound ? x/2 : xr,
yo = isRound ? y/2 : yr,
w = x / 2, w = x / 2,
h = y / 2, h = y / 2,
d = z / 2, d = z / 2,
zp = -d - platformZOff + gridZOff, zp = -d - platformZOff + gridZOff,
majors = [], minors = unitMinor ? [] : null, i; labelSize = grid.unitMinor * fontScale,
oldView = ruler.view,
view = ruler.view = new THREE.Group();
rulerXFirst = null; if (xon && axesOn) {
rulerXLast = null; let xPadding = labelSize * 4,
rulerYFirst = null; canvas = canvasInMesh(x + xPadding, labelSize * 3, 'center', 'top', rulerColor, labelSize),
rulerYLast = null; context = canvas.context,
mesh = canvas.mesh;
for (i = -xo; i <= xo; i += unitMinor) { for (let i = 0; i >= ruler.x1; i -= grid.unitMajor) {
let oh = isRound ? Math.sqrt(1-(i/xo)*(i/xo)) * h : h, context.fillText((i * factor).round(1).toString(), ruler.xo + i + xPadding / 2, 0);
dM = Math.abs(i % unitMajor);
if (i < -w || i > w) continue;
if (dM < 1 || Math.abs(unitMajor - dM) < 0.1) {
majors.append({x:i, y:-oh, z:zp}).append({x:i, y:oh, z:zp});
if (rulerXFirst === null) rulerXFirst = i + w;
rulerXLast = i + w;
} else {
minors.append({x:i, y:-oh, z:zp}).append({x:i, y:oh, z:zp});
} }
} for (let i = 0; i <= ruler.x2; i += grid.unitMajor) {
for (i = -yo; i <= yo; i += unitMinor) { context.fillText((i * factor).round(1).toString(), ruler.xo + i + xPadding / 2, 0);
let ow = isRound ? Math.sqrt(1-(i/yo)*(i/yo)) * w : w,
dM = Math.abs(i % unitMajor);
if (i < -h || i > h) continue;
if (dM < 1 || Math.abs(unitMajor - dM) < 0.1) {
majors.append({x:-ow, y:i, z:zp}).append({x:ow, y:i, z:zp});
if (rulerYFirst === null) rulerYFirst = i + h;
rulerYLast = i + h;
} else {
minors.append({x:-ow, y:i, z:zp}).append({x:ow, y:i, z:zp});
} }
context.font = (labelSize * 0.75) + 'px sans-serif';
context.fillText(xlabel, (x + xPadding) / 2, labelSize * 1.5);
mesh.position.set(0, - h - labelSize * 2, zp);
view.add(mesh);
} }
gridView.add(makeLinesFromPoints(majors, gridColorMajor || 0x999999, 1));
if (minors) gridView.add(makeLinesFromPoints(minors, gridColorMinor || 0xcccccc, 1)); if (yon && axesOn) {
if (oldGridView) Space.scene.remove(oldGridView); let yPadding = labelSize,
Space.scene.add(gridView); canvas = canvasInMesh(labelSize * 4, y + yPadding, 'end', 'middle', rulerColor, labelSize),
context = canvas.context,
mesh = canvas.mesh;
for (let i = 0; i >= ruler.y1; i -= grid.unitMajor) {
context.fillText((i * factor).round(1), labelSize * 4, y - (ruler.yo + i) + yPadding / 2);
}
for (let i = 0; i <= ruler.y2; i += grid.unitMajor) {
context.fillText((i * factor).round(1), labelSize * 4, y - (ruler.yo + i) + yPadding / 2);
}
context.font = (labelSize * 0.75) + 'px sans-serif';
context.fillText(ylabel, labelSize * 1.25, (y + yPadding) / 2);
mesh.position.set(-w - labelSize * 2 - 5, 0, zp);
view.add(mesh);
}
Space.scene.remove(oldView);
Space.scene.add(view);
requestRefresh();
}
function setGrid(unitMajor = grid.unitMajor, unitMinor = grid.unitMinor, colorMajor = grid.colorMajor, colorMinor = grid.colorMinor) {
if (!unitMajor) {
return;
}
if (unitMajor !== grid.unitMajor || unitMinor !== grid.unitMinor) {
grid.unitMajor = unitMajor;
grid.unitMinor = unitMinor;
grid.colorMajor = colorMajor || grid.colorMajor;
grid.colorMinor = colorMinor || grid.colorMinor;
updateGrid();
}
}
function updateGrid() {
let { view, unitMinor, unitMajor, colorMajor, colorMinor } = grid;
let oldView = view;
view = grid.view = new THREE.Group();
let majors = [],
minors = [],
x = platform.scale.x,
y = isRound ? platform.scale.z : platform.scale.y,
z = isRound ? platform.scale.y : platform.scale.z,
zp = -(z / 2) - platformZOff + gridZOff,
xh = x / 2,
yh = y / 2,
x1 = -xh - origin.x,
x2 = xh - origin.x,
y1 = -yh + origin.y,
y2 = yh + origin.y,
xo = x1 + xh,
yo = y1 + yh;
ruler.x1 = x1;
ruler.x2 = x2;
ruler.y1 = y1;
ruler.y2 = y2;
ruler.xo = xh - xo;
ruler.yo = yh - yo;
for (let x=0; x>x1; x -= unitMinor) {
let oh = isRound ? Math.sqrt(1-(x/xh)*(x/xh)) * yh : yh;
let arr = Math.abs(x % unitMajor) < 0.1 ? majors : minors;
arr.append({x:x-xo, y:-oh, z:zp}).append({x:x-xo, y:oh, z:zp});
}
for (let x=0; x<x2; x += unitMinor) {
let oh = isRound ? Math.sqrt(1-(x/xh)*(x/xh)) * yh : yh;
let arr = Math.abs(x % unitMajor) < 0.1 ? majors : minors;
arr.append({x:x-xo, y:-oh, z:zp}).append({x:x-xo, y:oh, z:zp});
}
for (let y=0; y>y1; y -= unitMinor) {
let ow = isRound ? Math.sqrt(1-(y/yh)*(y/yh)) * xh : xh;
let arr = Math.abs(y % unitMajor) < 0.1 ? majors : minors;
arr.append({x:-ow, y:y-yo, z:zp}).append({x:ow, y:y-yo, z:zp});
}
for (let y=0; y<y2; y += unitMinor) {
let ow = isRound ? Math.sqrt(1-(y/yh)*(y/yh)) * xh : xh;
let arr = Math.abs(y % unitMajor) < 0.1 ? majors : minors;
arr.append({x:-ow, y:y-yo, z:zp}).append({x:ow, y:y-yo, z:zp});
}
view.add(makeLinesFromPoints(majors, colorMajor || 0x999999, 1));
view.add(makeLinesFromPoints(minors, colorMinor || 0xcccccc, 1));
Space.scene.remove(oldView);
Space.scene.add(grid.view);
requestRefresh();
}
function updateDraws() {
updateGrid();
updateRulers();
requestRefresh();
} }
function setOrigin(x, y, z) { function setOrigin(x, y, z) {
if (gridOrigin) { if (grid.origin) {
if (x === gridOrigin.x && y === gridOrigin.y && z === gridOrigin.z) { if (x === grid.origin.x && y === grid.origin.y && z === grid.origin.z) {
updateDraws();
return; return;
} }
Space.scene.remove(gridOrigin.group); Space.scene.remove(grid.origin.group);
} }
if (x === undefined) { if (x === undefined) {
gridOrigin = null; origin = {x:0, y:0, z:0};
Space.update(); grid.origin = null;
updateDraws();
return; return;
} }
origin = {x, y, z};
let cmat = new THREE.MeshPhongMaterial({ let cmat = new THREE.MeshPhongMaterial({
color: 0xcceeff, color: 0xcceeff,
specular: 0xcceeff, specular: 0xcceeff,
@ -473,7 +509,7 @@
let PIP = Math.PI/2; let PIP = Math.PI/2;
let pi1, pi2, pi3, pi4; let pi1, pi2, pi3, pi4;
let group = new THREE.Group(); let group = new THREE.Group();
gridOrigin = {x, y, z, group}; grid.origin = {x, y, z, group};
group.add(pi1 = new THREE.Mesh( group.add(pi1 = new THREE.Mesh(
new THREE.CircleGeometry(4.6, 50, PIP*0, PIP*1), new THREE.CircleGeometry(4.6, 50, PIP*0, PIP*1),
cmat cmat
@ -519,11 +555,12 @@
m.renderOrder = 3; m.renderOrder = 3;
}); });
Space.scene.add(group); Space.scene.add(group);
Space.update(); updateDraws();
} }
function refresh() { function refresh() {
refreshRequested = false; refreshRequested = false;
clearTimeout(refreshTimeout);
updateLastAction(); updateLastAction();
viewControl.update(); viewControl.update();
} }
@ -830,7 +867,7 @@
onClick: function(f) { platformClick = f}, onClick: function(f) { platformClick = f},
size: function() { return platform.scale }, size: function() { return platform.scale },
isVisible: function() { return platform.visible }, isVisible: function() { return platform.visible },
showGrid: function(b) { gridView.visible = b }, showGrid: function(b) { grid.view.visible = b },
setRound: function(bool) { setRound: function(bool) {
let current = platform; let current = platform;
isRound = bool; isRound = bool;