diff --git a/notes.md b/notes.md index 51712c50..4c7f9c32 100644 --- a/notes.md +++ b/notes.md @@ -76,6 +76,7 @@ * `B` need to force cut line at synthetic z bottom (midlines, etc) * `B` contour does not honor clip to stock +* `F` get gcode coordinates off a part with point/click or hover? * `F` include tools in default devices (Carvera) * `F` add `match faces` option in `outline` operation * `F` add {progress} substitution and maybe {time-remaining} if can be calc'd diff --git a/package.json b/package.json index f5b4ce02..49d12420 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grid-apps", - "version": "3.8.6D", + "version": "3.8.8D", "description": "grid.space 3d slice & modeling tools", "author": "Stewart Allen ", "license": "MIT", diff --git a/release.md b/release.md index 7f56ef30..89bffd35 100644 --- a/release.md +++ b/release.md @@ -15,6 +15,8 @@ Full docs @ https://docs.grid.space/projects/kiri-moto * add CAM origin offset optional parameters * remove auto-decimation on object import * fix FDM raft line fill strategy +* slicing memory reduction from team lychee +* option to control first CAM output point order - refactor object/group storage model in Mesh:Tool diff --git a/src/geo/polygon.js b/src/geo/polygon.js index d6be990c..9b92a220 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -1285,6 +1285,18 @@ class Polygon { return this; } + freeParentRefs() { + if (this.inner && this.inner.length > 0) { + for (let inner of this.inner) { + inner.freeParentRefs(); + delete inner.parent; + } + } + for (let p of this.points) { + delete p.poly; + } + } + newUndeleted() { let poly = newPolygon(); this.forEachPoint(p => { diff --git a/src/geo/slicer.js b/src/geo/slicer.js index 88bbaf9e..16a38ec9 100644 --- a/src/geo/slicer.js +++ b/src/geo/slicer.js @@ -45,7 +45,6 @@ async function slice(points, options = {}) { zScale, // bucket span in z units zSum = 0.0, // sanity check that points enclose non-zere volume buckets = [], // banded/grouped faces to speed up slice/search - bucketMap = {}, overlapMax = options.overlap || 0.75, bucketMax = options.bucketMax || 100, onupdate = options.onupdate || function() {}, @@ -162,6 +161,11 @@ async function slice(points, options = {}) { return {}; } + // create empty buckets + for (i = 0; i < bucketCount; i++) { + buckets.push({ points: [], slices: [] }); + } + if (bucketCount > 1) { let failAt = (points.length * overlapMax) | 0, bucket; // copy triples into all matching z-buckets @@ -175,12 +179,7 @@ async function slice(points, options = {}) { bM = Math.min(Math.ceil(zM * zScale), bucketCount); // add point to all buckets in range for (j = bm; j < bM; j++) { - let map = bucketMap[j]; - if (!map) { - map = bucketMap[j] = { points: [], slices: [] }; - buckets.push(map); - } - bucket = map.points; + bucket = buckets[j].points; bucket.push(p1); bucket.push(p2); bucket.push(p3); @@ -197,7 +196,6 @@ async function slice(points, options = {}) { // fallback if we can't partition point space if (bucketCount === 1) { buckets = [{ points, slices: [] }]; - bucketMap[0] = buckets[0]; } // create buckets data structure @@ -206,7 +204,11 @@ async function slice(points, options = {}) { index = bucketCount <= 1 ? 0 : Math.min(Math.floor(z * zScale), bucketCount - 1), bucket = buckets[index]; - if (bucket) bucket.slices.push(z); else console.log({skip: index}); + if (bucket) { + bucket.slices.push(z); + } else { + console.log({ missing_bucket: z, index }); + } onupdate((i / zIndexes.length) * 0.1); } @@ -402,6 +404,23 @@ async function sliceZ(z, points, options = {}) { if (fn) fn(rval, options); } + // free objects to be re-claimed and reduce memory pressure + if (true) { + delete rval.groups + delete rval.lines + delete rval.clip.m_AllPolys + + for (let top of rval.tops) { + top.poly.freeParentRefs(); + top.simple.freeParentRefs(); + for (let shell of top.shells) shell.freeParentRefs(); + for (let fillo of top.fill_off) fillo.freeParentRefs(); + for (let last of top.last) last.freeParentRefs(); + } + + for (let clip of rval.clip) clip.freeParentRefs(); + } + if (each) each(rval); return rval; } diff --git a/src/kiri-mode/cam/export.js b/src/kiri-mode/cam/export.js index ecc9fd51..10962578 100644 --- a/src/kiri-mode/cam/export.js +++ b/src/kiri-mode/cam/export.js @@ -211,20 +211,37 @@ CAM.export = function(print, online) { if (points === 0) { pos.x = pos.y = pos.z = 0; points++; - moveTo({ - // speed: Infinity, - tool: out.tool, - point: { x: newpos.x, y: newpos.y, z: pos.z, a: pos.a } - }, { - dx: 1, dy: 1, dz: 0, time: 0 - }); - moveTo({ - // speed: Infinity, - tool: out.tool, - point: { x: newpos.x, y: newpos.y, z: newpos.z, a: newpos.a } - }, { - dx: 0, dy: 0, dz: 1, time: 0 - }); + if (spro.camFirstZMax) { + moveTo({ + // speed: Infinity, + tool: out.tool, + point: { x: pos.x, y: pos.y, z: newpos.z, a: newpos.a } + }, { + dx: 0, dy: 0, dz: 1, time: 0 + }); + moveTo({ + // speed: Infinity, + tool: out.tool, + point: { x: newpos.x, y: newpos.y, z: newpos.z, a: pos.a } + }, { + dx: 1, dy: 1, dz: 0, time: 0 + }); + } else if (newpos.z <= pos.z) { + moveTo({ + // speed: Infinity, + tool: out.tool, + point: { x: newpos.x, y: newpos.y, z: pos.z, a: pos.a } + }, { + dx: 1, dy: 1, dz: 0, time: 0 + }); + moveTo({ + // speed: Infinity, + tool: out.tool, + point: { x: newpos.x, y: newpos.y, z: newpos.z, a: newpos.a } + }, { + dx: 0, dy: 0, dz: 1, time: 0 + }); + } points--; return; } diff --git a/src/kiri/conf.js b/src/kiri/conf.js index 119a5b66..ef84e43a 100644 --- a/src/kiri/conf.js +++ b/src/kiri/conf.js @@ -581,6 +581,7 @@ const conf = exports({ camExpertFast: false, camTrueShadow: false, camForceZMax: false, + camFirstZMax: false, ops: [], // current ops op2: [] // flip ops } diff --git a/src/kiri/init.js b/src/kiri/init.js index 8f0ba94f..d6f3478f 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -1974,6 +1974,8 @@ gapp.register("kiri.init", [], (root, exports) => { camConventional: uc.newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l, modes:CAM}), camEaseDown: uc.newBoolean(LANG.cr_ease_s, onBooleanClick, {title:LANG.cr_ease_l, modes:CAM}), camDepthFirst: uc.newBoolean(LANG.ou_depf_s, onBooleanClick, {title:LANG.ou_depf_l, modes:CAM}), + fdmSep: uc.newBlank({class:"pop-sep", modes:FDM_CAM}), + camFirstZMax: uc.newBoolean(LANG.ou_z1st_s, onBooleanClick, {title:LANG.ou_z1st_l, modes:CAM}), camForceZMax: uc.newBoolean(LANG.ou_forz_s, onBooleanClick, {title:LANG.ou_forz_l, modes:CAM}), outputOriginBounds: uc.newBoolean(LANG.or_bnds_s, onBooleanClick, {title:LANG.or_bnds_l, modes:LASER}), outputOriginCenter: uc.newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l, modes:LASER}), @@ -1982,9 +1984,9 @@ gapp.register("kiri.init", [], (root, exports) => { camOriginTop: uc.newBoolean(LANG.or_topp_s, onBooleanClick, {title:LANG.or_topp_l, modes:CAM}), camOriginCenter: uc.newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l, modes:CAM}), camSep: uc.newBlank({class:"pop-sep", modes:CAM}), - camOriginOffX: uc.newInput(LANG.co_offx_s, {title:LANG.co_offx_l, convert:uc.toInt, modes:CAM}), - camOriginOffY: uc.newInput(LANG.co_offy_s, {title:LANG.co_offy_l, convert:uc.toInt, modes:CAM}), - camOriginOffZ: uc.newInput(LANG.co_offz_s, {title:LANG.co_offz_l, convert:uc.toInt, modes:CAM}), + camOriginOffX: uc.newInput(LANG.co_offx_s, {title:LANG.co_offx_l, convert:uc.toFloat, modes:CAM}), + camOriginOffY: uc.newInput(LANG.co_offy_s, {title:LANG.co_offy_l, convert:uc.toFloat, modes:CAM}), + camOriginOffZ: uc.newInput(LANG.co_offz_s, {title:LANG.co_offz_l, convert:uc.toFloat, modes:CAM}), camExpert: uc.newGroup(LANG.op_xprt_s, null, {group: "cam_expert", modes:CAM, marker: false}), camExpertFast: uc.newBoolean(LANG.cx_fast_s, onBooleanClick, {title:LANG.cx_fast_l, modes:CAM, show: () => !ui.camTrueShadow.checked }), diff --git a/src/main/kiri.js b/src/main/kiri.js index 03b2b9e2..91765bc9 100644 --- a/src/main/kiri.js +++ b/src/main/kiri.js @@ -15,7 +15,7 @@ gapp.main("main.kiri", [], (root) => { const modfns = root.kirimod = ( root.kirimod || [] ); const kiri = root.kiri = { - beta: 3806, + beta: 3808, driver: {}, // driver modules load(fn) { modfns.push(fn); diff --git a/src/moto/license.js b/src/moto/license.js index d6537c57..a24eb707 100644 --- a/src/moto/license.js +++ b/src/moto/license.js @@ -5,7 +5,7 @@ let terms = { COPYRIGHT: "Copyright (C) Stewart Allen - All Rights Reserved", LICENSE: "See the license.md file included with the source distribution", - VERSION: (is_self ? self : this).debug_version || "3.8.D6" + VERSION: (is_self ? self : this).debug_version || "3.8.D8" }; if (typeof(module) === 'object') { diff --git a/web/kiri/lang/en.js b/web/kiri/lang/en.js index df7d6ffe..027f6608 100644 --- a/web/kiri/lang/en.js +++ b/web/kiri/lang/en.js @@ -678,6 +678,8 @@ self.kiri.lang['en-us'] = { ou_depf_l: ["optimize pocket cuts","with depth priority"], ou_forz_s: "force z max", ou_forz_l: "all moves between pockets will go to z max (above stock). this is usually required if you are not performing a roughing operation before pocketing operations.", + ou_z1st_s: "first z max", + ou_z1st_l: "first move in the job will be to Z max (travel distance above stock)", // CAM STOCK cs_menu: "stock",