diff --git a/src/kiri-mode/cam/client.js b/src/kiri-mode/cam/client.js index b9d9a408..aa7778c1 100644 --- a/src/kiri-mode/cam/client.js +++ b/src/kiri-mode/cam/client.js @@ -93,7 +93,7 @@ CAM.init = function(kiri, api) { for (let widget of api.widgets.all()) { widget.setIndexed(camStock && isIndexed ? camStock.scale.z : 0); } - api.platform.update_top_z(); + api.platform.update_bounds(); // add or remove clock op depending on indexing const cp = current.process; if (!cp.ops) { @@ -114,7 +114,7 @@ CAM.init = function(kiri, api) { if (isCamMode && !Array.isArray(widget)) { setAnimationStyle(true); widget.setIndexed(camStock && isIndexed ? camStock.scale.z : 0); - api.platform.update_top_z(); + api.platform.update_bounds(); } }); @@ -189,6 +189,7 @@ CAM.init = function(kiri, api) { // show/hide dots in enabled process pop buttons api.ui.camTabs.marker.style.display = hasTabs ? 'flex' : 'none'; api.ui.camStock.marker.style.display = proc.camStockOn ? 'flex' : 'none'; + api.platform.update_bounds(); updateStock(settings, 'settings.saved.internal'); setAnimationStyle(); func.opRender(); @@ -202,7 +203,7 @@ CAM.init = function(kiri, api) { setAnimationStyle(); }); - api.event.on("boolean.click", api.platform.update_top_z); + api.event.on("boolean.click", api.platform.update_bounds); api.event.on([ "init-done", @@ -1660,6 +1661,7 @@ function updateStock(args, event) { } return; } + if (!isCamMode) { SPACE.world.remove(camZBottom); SPACE.world.remove(camStock); @@ -1669,52 +1671,14 @@ function updateStock(args, event) { } const refresh = (event === "selection.scale" || event === 'selection.rotate'); + const settings = API.conf.get(); - let settings = API.conf.get(); - let widgets = API.widgets.all(); - let proc = settings.process; - let enabled = UI.camStockOn.checked; - let offset = UI.camStockOffset.checked; - let stockSet = offset || (proc.camStockX && proc.camStockY && proc.camStockZ); - let topZ = API.platform.top_z(); - let delta = 0; - let csox = 0; - let csoy = 0; - let csoz = 0; - let stock = settings.stock = { }; - let compute = enabled && stockSet && widgets.length; + const { stock, process } = settings; + const { x, y, z, center } = stock; UI.func.animate.classList.add('disabled'); - // create/inject cam stock if stock size other than default - let csx = proc.camStockX; - let csy = proc.camStockY; - let csz = proc.camStockZ; - let min = { x: Infinity, y: Infinity, z: Infinity }; - let max = { x: -Infinity, y: -Infinity, z: -Infinity }; - for (let widget of widgets) { - let wbnd = widget.getBoundingBox(refresh); - let wpos = widget.track.pos; - min = { - x: Math.min(min.x, wpos.x + wbnd.min.x), - y: Math.min(min.y, wpos.y + wbnd.min.y), - z: Math.min(min.z, wpos.z + wbnd.min.z) - }; - max = { - x: Math.max(max.x, wpos.x + wbnd.max.x), - y: Math.max(max.y, wpos.y + wbnd.max.y), - z: Math.max(max.z, wpos.z + wbnd.max.z) - }; - } - if (offset) { - csx += max.x - min.x; - csy += max.y - min.y; - csz += max.z - min.z; - csox = min.x + ((max.x - min.x) / 2); - csoy = min.y + ((max.y - min.y) / 2); - csoz = csz / 2; // min.z + ((max.z - min.z) / 2); - } - if (compute) { + if (x && y && z) { UI.func.animate.classList.remove('disabled'); if (!camStock) { let geo = new THREE.BoxGeometry(1, 1, 1); @@ -1729,18 +1693,18 @@ function updateStock(args, event) { let lo = 0.5; let lidat = [ - lo,lo,lo, lo,lo,-lo, - lo,lo,lo, lo,-lo,lo, - lo,lo,lo, -lo,lo,lo, - -lo,-lo,-lo, -lo,-lo,lo, - -lo,-lo,-lo, -lo,lo,-lo, - -lo,-lo,-lo, lo,-lo,-lo, - lo,lo,-lo, -lo,lo,-lo, - lo,lo,-lo, lo,-lo,-lo, - lo,-lo,-lo, lo,-lo,lo, - lo,-lo,lo, -lo,-lo,lo, - -lo,-lo,lo, -lo,lo,lo, - -lo,lo,lo, -lo,lo,-lo + lo, lo, lo, lo, lo,-lo, + lo, lo, lo, lo,-lo, lo, + lo, lo, lo, -lo, lo, lo, + -lo,-lo,-lo, -lo,-lo, lo, + -lo,-lo,-lo, -lo, lo,-lo, + -lo,-lo,-lo, lo,-lo,-lo, + lo, lo,-lo, -lo, lo,-lo, + lo, lo,-lo, lo,-lo,-lo, + lo,-lo,-lo, lo,-lo, lo, + lo,-lo, lo, -lo,-lo, lo, + -lo,-lo, lo, -lo, lo, lo, + -lo, lo, lo, -lo, lo,-lo ]; let ligeo = new THREE.BufferGeometry(); ligeo.setAttribute('position', new THREE.BufferAttribute(lidat.toFloat32(), 3)); @@ -1751,38 +1715,23 @@ function updateStock(args, event) { SPACE.world.add(camStock); } - stock = settings.stock = { - x: csx, - y: csy, - z: csz, - center: { - x: csox, - y: csoy, - z: csoz - } - }; - camStock.scale.x = csx + 0.005; - camStock.scale.y = csy + 0.005; - camStock.scale.z = csz + 0.005; - camStock.position.x = csox; - camStock.position.y = csoy; - camStock.position.z = csoz; + camStock.scale.x = x + 0.005; + camStock.scale.y = y + 0.005; + camStock.scale.z = z + 0.005; + camStock.position.x = center.x; + camStock.position.y = center.y; + camStock.position.z = center.z; camStock.rotation.x = currentIndex || 0; - if (isIndexed) { - camStock.position.z = 0; - } - delta = csz - topZ; camStock.lines.material.color = new THREE.Color(API.space.is_dark() ? 0x555555 : 0xaaaaaa); } else if (camStock) { SPACE.world.remove(camStock); camStock = null; - delta = 0; } SPACE.world.remove(camZBottom); - if (proc.camZBottom && widgets.length) { - let max = { x: csx, y: csy, z: csz }; + if (process.camZBottom && widgets.length) { + let max = { x, y, z }; for (let w of widgets) { max.x = Math.max(max.x, w.track.box.w); max.y = Math.max(max.y, w.track.box.h); @@ -1798,16 +1747,14 @@ function updateStock(args, event) { camZBottom = new THREE.Mesh(geo, mat); camZBottom._max = max; camZBottom.renderOrder = 1; - camZBottom.position.x = csox; - camZBottom.position.y = csoy; - camZBottom.position.z = proc.camZBottom; + camZBottom.position.x = center.x; + camZBottom.position.y = center.y; + camZBottom.position.z = process.camZBottom; SPACE.world.add(camZBottom); } else { camZBottom = undefined; } - // API.platform.update_top_z(delta); - // API.platform.update_origin(); SPACE.update(); } diff --git a/src/kiri/init.js b/src/kiri/init.js index c2213ae4..1f8ae4ca 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -69,7 +69,7 @@ gapp.register("kiri.init", [], (root, exports) => { } platform.load_stl("/obj/cube.stl", function(vert) { catalog.putFile("sample cube.stl", vert); - platform.compute_max_z(); + platform.update_bounds(); space.view.home(); setTimeout(() => { api.space.save(true) },500); then(); diff --git a/src/kiri/main.js b/src/kiri/main.js index 4436837b..fb5e3d02 100644 --- a/src/kiri/main.js +++ b/src/kiri/main.js @@ -616,7 +616,7 @@ gapp.register("kiri.main", [], (root, exports) => { if (ondone) { ondone(); setTimeout(() => { - platform.update_top_z(); + platform.update_bounds(); SPACE.update(); }, 1); } diff --git a/src/kiri/platform.js b/src/kiri/platform.js index 2adf2058..4e628748 100644 --- a/src/kiri/platform.js +++ b/src/kiri/platform.js @@ -85,32 +85,6 @@ function platformUpdateOrigin() { } } -function platformUpdateTopZ(zdelta) { - const { process, stock } = current(); - const hasStock = stock.x && stock.y && stock.z; - const MODE = get_mode(); - api.widgets.each(widget => { - if (MODE === MODES.CAM && hasStock) { - const bounds = widget.getBoundingBox(); - const wzmax = bounds.max.z; - const zdelta = process.camZOffset || 0; - switch (process.camZAnchor) { - case 'top': - widget.setTopZ(stock.z - zdelta); - break; - case 'middle': - widget.setTopZ(stock.z - (stock.z - wzmax) / 2); - break; - case 'bottom': - widget.setTopZ(wzmax + zdelta); - break; - } - } else { - widget.setTopZ(0); - } - }); -} - function platformUpdateSize(updateDark = true) { const { process, device, controller } = current(); const { showRulers, units } = controller; @@ -151,18 +125,81 @@ function platformUpdateSize(updateDark = true) { platform.update_origin(); } +function platformUpdateMidZ() { + topZ = 0; + api.widgets.each(widget => { + topZ = Math.max(topZ, widget.mesh.getBoundingBox().max.z); + }); + space.platform.setMaxZ(topZ); +} + +function platformUpdateTopZ(zdelta) { + const { process, stock } = current(); + const hasStock = stock.x && stock.y && stock.z; + const MODE = get_mode(); + api.widgets.each(widget => { + if (MODE === MODES.CAM && hasStock) { + const bounds = widget.getBoundingBox(); + const wzmax = bounds.max.z; + const zdelta = process.camZOffset || 0; + switch (process.camZAnchor) { + case 'top': + widget.setTopZ(stock.z - zdelta); + break; + case 'middle': + widget.setTopZ(stock.z - (stock.z - wzmax) / 2); + break; + case 'bottom': + widget.setTopZ(wzmax + zdelta); + break; + } + } else { + widget.setTopZ(0); + } + }); +} + +function platformUpdateStock() { + const settings = current(); + const { bounds, process, mode } = settings; + const { camStockOn, camStockX, camStockY, camStockZ, camStockOffset, camStockIndexed } = process; + if (mode === 'CAM' && camStockOn) { + let stock = settings.stock = { + x: camStockX, + y: camStockY, + z: camStockZ + }; + if (camStockOffset) { + stock.x += bounds.max.x - bounds.min.x; + stock.y += bounds.max.y - bounds.min.y; + stock.z += bounds.max.z - bounds.min.z; + } + stock.center = { + x: (bounds.max.x + bounds.min.x) / 2, + y: (bounds.max.y + bounds.min.y) / 2, + z: camStockIndexed ? 0 : stock.z / 2 + }; + } else { + settings.stock = {}; + } +} + function platformUpdateBounds() { - const bounds = new THREE.Box3(); - api.widgets.each(widget => { - let wp = widget.track.pos; - let wb = widget.mesh.getBoundingBox().clone(); - wb.min.x += wp.x; - wb.max.x += wp.x; - wb.min.y += wp.y; - wb.max.y += wp.y; - bounds.union(wb); - }); - return current().bounds = bounds; + const bounds = new THREE.Box3(); + api.widgets.each(widget => { + let wp = widget.track.pos; + let wb = widget.getBoundingBox(); + wb.min.x += wp.x; + wb.max.x += wp.x; + wb.min.y += wp.y; + wb.max.y += wp.y; + bounds.union(wb); + }); + current().bounds = bounds; + platformUpdateStock(); + platformUpdateTopZ(); + platformUpdateMidZ(); + return bounds; } function platformSelectedCount() { @@ -363,14 +400,6 @@ function platformLoadURL(url, options = {}) { }); } -function platformComputeMaxZ() { - topZ = 0; - api.widgets.each(widget => { - topZ = Math.max(topZ, widget.mesh.getBoundingBox().max.z); - }); - space.platform.setMaxZ(topZ); -} - function platformGroup() { grouping = true; } @@ -398,7 +427,7 @@ function platformAdd(widget, shift, nolayout, defer) { deferTimeout = setTimeout(platformAddDeferred, 150); } else { platform.select(widget, shift); - platform.compute_max_z(); + platform.update_bounds(); api.space.auto_save(); platformChanged(); api.event.emit('widget.add', widget); @@ -426,7 +455,7 @@ function platformAddDeferred() { platformGroupDone(); } api.event.emit('widget.add', deferred.map(r => r.widget)); - platform.compute_max_z(); + platform.update_bounds(); api.space.auto_save(); platformChanged(); deferred = []; @@ -506,7 +535,7 @@ function platformDelete(widget, defer) { function platformDeletePost() { api.view.update_slider_max(); - platform.compute_max_z(); + platform.update_bounds(); if (get_mode() !== MODES.FDM) { platform.layout(); } @@ -824,7 +853,6 @@ const platform = api.platform = { select: platformSelect, select_all: platformSelectAll, selected_count: platformSelectedCount, - compute_max_z: platformComputeMaxZ, update_origin: platformUpdateOrigin, update_bounds: platformUpdateBounds, update_size: platformUpdateSize, diff --git a/src/kiri/selection.js b/src/kiri/selection.js index b45dc45e..8a1ca5bf 100644 --- a/src/kiri/selection.js +++ b/src/kiri/selection.js @@ -150,7 +150,6 @@ function mirror() { } for_widgets(widget => { widget.mirror(); - api.event.emit("widget.mirror", widget); }); space.update(); api.space.auto_save(); @@ -162,7 +161,6 @@ function scale() { } let args = [...arguments]; for_groups(w => w.scale(...args)); - api.platform.compute_max_z(); selection.update_bounds(); api.platform.update_bounds(); api.event.emit('selection.scale', args); @@ -170,26 +168,21 @@ function scale() { if (args.last() === false) { return; } - update_info(); - space.update(); api.space.auto_save(); + selection.update_info(); + space.update(); } function rotate(x, y, z) { if (!api.view.is_arrange()) { return; } - for_groups(w => { - w.rotate(x, y, z); - api.event.emit('widget.rotate', {widget: w, x, y, z}); - }); + for_groups(w => w.rotate(x, y, z)); selection.update_bounds(); api.platform.update_bounds(); - api.platform.compute_max_z(); - api.platform.update_top_z(); api.event.emit('selection.rotate', {x, y, z}); - selection.update_info(); api.space.auto_save(); + selection.update_info(); space.update(); } diff --git a/src/kiri/widget.js b/src/kiri/widget.js index ab8150c6..55d116cd 100644 --- a/src/kiri/widget.js +++ b/src/kiri/widget.js @@ -489,7 +489,8 @@ class Widget { setTopZ(z) { let mesh = this.mesh, track = this.track, - mbz = mesh.getBoundingBox().max.z; + mbb = mesh.getBoundingBox(), + mbz = mbb.max.z; if (z) { track.top = z; } else { @@ -504,6 +505,10 @@ class Widget { this.group.forEach(w => { w._move(x, y, z, abs); }); + // allow for use in engine / cli + if ((x || y || z) && api && api.event) { + api.event.emit('widget.move', {widget: this, pos}); + } } _move(x, y, z, abs) { @@ -524,10 +529,6 @@ class Widget { if (x || y || z) { this.setModified(); this._updateMeshPosition(); - // allow for use in engine / cli - if (api && api.event) { - api.event.emit('widget.move', {widget: this, pos}); - } } } @@ -538,7 +539,6 @@ class Widget { top = track.top, tz = tzoff !== top ? -tzoff : 0, { x, y, z } = track.pos; - // console.trace('ump', {top, tz, tzoff}); if (track.indexed) { let rad = track.indexRad; let ln = track.box.d / 2; @@ -558,6 +558,9 @@ class Widget { w._scale(x, y, z); }); this.center(false); + if (api && api.event) { + api.event.emit('widget.scale', {widget: this, x, y, z}); + } } _scale(x, y, z) { @@ -580,6 +583,9 @@ class Widget { if (center) { this.center(false); } + if ((x || y || z) && api && api.event) { + api.event.emit('widget.rotate', {widget: this, x, y, z}); + } } _rotate(x, y, z, temp) { @@ -621,6 +627,9 @@ class Widget { w._mirror(); }); this.center(); + if (api && api.event) { + api.event.emit('widget.mirror', {widget: this}); + } } _mirror() { @@ -647,7 +656,6 @@ class Widget { arr[i*3+8] = z; } pos.needsUpdate = true; - // geo.computeVertexNormals(); ot.mirror = !ot.mirror; this.setModified(); this.points = null; @@ -695,8 +703,7 @@ class Widget { getBoundingBox(refresh) { if (!this.bounds || refresh || this.modified) { - // console.trace('gbb', refresh); - this.bounds = new THREE.Box3().setFromPoints(this.getPoints()); + this.bounds = new THREE.Box3().setFromArray(this.getGeoVertices()); this.modified = false; } return this.bounds;