From 32e9ceca55c30f32ccf453335774f43b1e263c2a Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sun, 20 Feb 2022 14:31:27 -0500 Subject: [PATCH] update add, data, geo to use gapp.register() --- app.js | 2 +- src/add/array.js | 6 +- src/add/class.js | 8 +- src/add/three.js | 6 +- src/data/index.js | 9 +- src/data/local.js | 9 +- src/geo/base.js | 8 +- src/geo/bounds.js | 19 +- src/geo/csg.js | 15 +- src/geo/gyroid.js | 13 +- src/geo/line.js | 17 +- src/geo/mesh.js | 729 ++++++++++++++++++++++---------------------- src/geo/paths.js | 9 +- src/geo/point.js | 22 +- src/geo/points.js | 14 +- src/geo/polygon.js | 20 +- src/geo/polygons.js | 11 +- src/geo/slicer.js | 20 +- src/geo/slope.js | 24 +- src/geo/wasm.js | 52 ++-- src/kiri/minion.js | 4 +- src/kiri/worker.js | 6 +- src/main/kiri.js | 32 +- 23 files changed, 535 insertions(+), 520 deletions(-) diff --git a/app.js b/app.js index 76614248..1daa0cde 100644 --- a/app.js +++ b/app.js @@ -399,7 +399,7 @@ const script = { "kiri/tools", "kiri/frame", "@devices", - "@icons" + "@icons", ], kiri_work : [ "main/gapp", diff --git a/src/add/array.js b/src/add/array.js index 0ab16f58..0918ea78 100644 --- a/src/add/array.js +++ b/src/add/array.js @@ -3,9 +3,7 @@ "use strict"; // extend Array, String, Number, Math -(function() { - -gapp.register('add.array'); +gapp.register("add.array", [], (root, exports) => { let AP = {}; @@ -234,4 +232,4 @@ Number.prototype.round = function(digits) { return Math.round(this.valueOf() * pow) / pow; }; -})(); +}); diff --git a/src/add/class.js b/src/add/class.js index 969d03cb..31d4cdcf 100644 --- a/src/add/class.js +++ b/src/add/class.js @@ -2,11 +2,7 @@ "use strict"; -(function() { - -if (self.ArrayWriter) return; - -gapp.register('add.class'); +gapp.register("add.class", [], (root, exports) => { self.ArrayWriter = class ArrayWriter { constructor() { @@ -174,4 +170,4 @@ self.DataReader = class DataReader { } } -})(); +}); diff --git a/src/add/three.js b/src/add/three.js index 2e463933..c9924b94 100644 --- a/src/add/three.js +++ b/src/add/three.js @@ -2,12 +2,10 @@ "use strict"; -(function() { - // dep: ext.three // dep: ext.three-bgu // dep: ext.three-svg -gapp.register('add.three'); +gapp.register("add.three", [], (root, exports) => { let MP = THREE.Mesh.prototype, XP = THREE.Box3.prototype, @@ -129,4 +127,4 @@ THREE.Object3D.prototype.removeAll = function() { this.children = []; }; -})(); +}); diff --git a/src/data/index.js b/src/data/index.js index acf43fe8..24278294 100644 --- a/src/data/index.js +++ b/src/data/index.js @@ -2,12 +2,9 @@ "use strict"; -(function() { +gapp.register("data.index", [], (root, exports) => { -gapp.register('data.index'); - -let data = self.data = self.data || {}; -if (data.Index) return; +const { data } = root; data.Index = IDBStore; @@ -322,4 +319,4 @@ SP.clear = function(key, store = this.current) { .objectStore(store).clear(); }; -})(); +}); diff --git a/src/data/local.js b/src/data/local.js index e81fb575..e2c849dd 100644 --- a/src/data/local.js +++ b/src/data/local.js @@ -2,12 +2,9 @@ "use strict"; -(function() { +gapp.register("data.local", [], (root, exports) => { -gapp.register('data.local'); - -let data = self.data = self.data || {}; -if (data.local) return; +const { data } = root; function Local() { this.__data__ = {}; @@ -47,4 +44,4 @@ try { // alert(msg); } -})(); +}); diff --git a/src/geo/base.js b/src/geo/base.js index deee4282..2c2b9fbe 100644 --- a/src/geo/base.js +++ b/src/geo/base.js @@ -2,11 +2,9 @@ "use strict"; -(function() { +gapp.register("geo.base", [], (root, exports) => { -if (self.base) return; - -const base = self.base = {}; +const base = root.base = {}; const round_decimal_precision = 5; function time() { @@ -580,4 +578,4 @@ base.util = { zInPlane }; -})(); +}); diff --git a/src/geo/bounds.js b/src/geo/bounds.js index 2cccf563..2212f53e 100644 --- a/src/geo/bounds.js +++ b/src/geo/bounds.js @@ -3,12 +3,10 @@ "use strict"; // dep: geo.base -(function() { +gapp.register("geo.bounds", [], (root, exports) => { -let base = self.base; -if (base.Bounds) return; - -let { config, util } = base; +const { base } = root; +const { config, util } = base; class Bounds { constructor() { @@ -132,9 +130,12 @@ class Bounds { centery() { return this.miny + this.height() / 2; - }} + } +} -base.Bounds = Bounds; -base.newBounds = function() { return new Bounds() }; +gapp.overlay(base, { + Bounds, + newBounds() { return new Bounds() } +}); -})(); +}); diff --git a/src/geo/csg.js b/src/geo/csg.js index 4ff1418b..cf07c37d 100644 --- a/src/geo/csg.js +++ b/src/geo/csg.js @@ -2,13 +2,12 @@ "use strict"; -(function() { - // dep: geo.base -let base = self.base; -if (base.CSG) return; +gapp.register("geo.csg", [], (root, exports) => { -base.CSG = { +const { base } = root; + +const CSG = { union() { return jscadModeling.booleans.union(...arguments); @@ -52,4 +51,8 @@ base.CSG = { }; -})(); +gapp.overlay(base, { + CSG +}); + +}); diff --git a/src/geo/gyroid.js b/src/geo/gyroid.js index d6ec1b82..d28e0f6d 100644 --- a/src/geo/gyroid.js +++ b/src/geo/gyroid.js @@ -2,11 +2,10 @@ "use strict"; -(function() { +// dep: geo.base +gapp.register("geo.gyroid", [], (root, exports) => { -if (self.base.gyroid) return; - -const base = self.base; +const { base } = root; const PI2 = Math.PI * 2; let cache = {}; @@ -215,6 +214,8 @@ function distTo(a, b, dir) { return Math.sqrt(dx * dx + dy * dy); } -base.gyroid = { slice }; +gapp.overlay(base, { + gyroid: { slice } +}) -})(); +}); diff --git a/src/geo/line.js b/src/geo/line.js index 8e151d1c..f391c7bd 100644 --- a/src/geo/line.js +++ b/src/geo/line.js @@ -2,11 +2,10 @@ "use strict"; -(function() { +// dep: geo.base +gapp.register("geo.line", [], (root, exports) => { -if (self.base.Line) return; - -const base = self.base; +const { base } = root; class Line { constructor(p1, p2, key) { @@ -63,8 +62,10 @@ function newOrderedLine(p1, p2, key) { return p1.key < p2.key ? newLine(p1,p2,key) : newLine(p2,p1,key); } -base.Line = Line; -base.newLine = newLine; -base.newOrderedLine = newOrderedLine; +gapp.overlay(base, { + Line, + newLine, + newOrderedLine +}); -})(); +}); diff --git a/src/geo/mesh.js b/src/geo/mesh.js index 8e72e04b..a4d1165c 100644 --- a/src/geo/mesh.js +++ b/src/geo/mesh.js @@ -2,387 +2,386 @@ "use strict"; -(function() { +// dep: geo.base +gapp.register("geo.mesh", [], (root, exports) => { - const BASE = self.base = self.base || {}; - const TEST = 0; +const { base } = root; +const TEST = 0; - if (BASE.Mesh) { - return; +class Mesh { + constructor(params = {}) { + this.precision = Math.pow(10, params.precision || 6); + if (params.vertices) { + this.setData(params.vertices, params.faces); + } } - BASE.Mesh = class Mesh { - constructor(params = {}) { - this.precision = Math.pow(10, params.precision || 6); - if (params.vertices) { - this.setData(params.vertices, params.faces); - } + /** + * set vertices and faces of the mesh. if only vertices are provided + * then the data is assumed to be un-indexed and will be indexed into + * faces. if faces are provided, they are assumed to be index references + * into the vertex data. removes invalid faces. + * + * the end result is face data mapped to an indexed set of unique vertices. + * + * @param {number[]} vertices + * @param {number[]} faces + */ + setData(vertices, faces) { + if (!vertices) { + throw "missing vertices"; } - - /** - * set vertices and faces of the mesh. if only vertices are provided - * then the data is assumed to be un-indexed and will be indexed into - * faces. if faces are provided, they are assumed to be index references - * into the vertex data. removes invalid faces. - * - * the end result is face data mapped to an indexed set of unique vertices. - * - * @param {number[]} vertices - * @param {number[]} faces - */ - setData(vertices, faces) { - if (!vertices) { - throw "missing vertices"; - } - if (vertices.length % 3 !== 0) { - throw "invalid vertices"; - } - // when face/index data is missing, vertices need to be normalized - if (!faces) { - if (TEST) console.time('generate faces'); - faces = []; - let fcac = {}; // seen face hash - let fnew = []; // accumulate vertex triplets - let nuvt = []; // new vertex list - let hash = {}; // find vertex matches - let prec = this.precision; - let dups = 0; - // let cull = 0; - for (let i=0, l=vertices.length; i l !== this && !l.used && l.faces.length === 1); - } - - adjacentUsed() { - return vmap[this.v1] - .concat(vmap[this.v2]) - .filter(l => l !== this && l.used && l.faces.length === 1); - } - - touches(line) { - return this.v1 === line.v1 || - this.v1 === line.v2 || - this.v2 === line.v1 || - this.v2 === line.v2; - } - - unitVector() { - if (this.unit !== undefined) { - return this.unit; - } - let v1 = this.v1; - let v2 = this.v2; - let d = [ - vertices[v1] - vertices[v2], - vertices[v1 + 1] - vertices[v2 + 1], - vertices[v1 + 2] - vertices[v2 + 2], - ]; - let max = Math.max(...d.map(v => Math.abs(v))); - // console.log({d, max}); - return this.unit = d.map(v => v / max); - } - } - - function diffUnitVector(uv1, uv2) { - let diff = 0; - for (let i=0; i<3; i++) { - diff += Math.abs(uv1[i] - uv2[i]); - } - return diff; - } - - function getLine(v1, v2) { - let s1 = vertices[v1] + vertices[v1+1]*1000 + vertices[v1+2]*100000; - let s2 = vertices[v2] + vertices[v2+1]*1000 + vertices[v2+2]*100000; - let key = s1 <= s2 ? [v1,v2].join('-') : [v2,v1].join('-'); - let line = hash[key]; - if (!line) { - // point order will be swapped for reconstructed faces - // to preserve chirality (assuming face normals are correct) - line = hash[key] = new Line(v1, v2); - line.key = key; - lines.push(line); - let lm1 = vmap[v1] = vmap[v1] || []; - let lm2 = vmap[v2] = vmap[v2] || []; - lm1.push(line); - lm2.push(line); - } - return line; - } - - function getXYZ(v) { - return {x: vertices[v], y: vertices[v+1], z: vertices[v+2]}; - } - - for (let i=0, l=this.faces.length; i l.faces.length === 1); - let loops = this.loops = []; - - // connect edge lines into closed loops - for (let i=0, l=edges.length; i 2) { - // console.log('cannot start on a split'); - continue; - } - // line.used = true; - let loop = [ ]; - // build line through adjacent lines - while (true) { - let adjacent = line.adjacentUnused(); - if (adjacent.length === 0) { - let first = loop[0]; - let last = loop.last(); - loop.open = loop.length < 3 - || (first.v1 !== last.v1 - && first.v2 !== last.v2 - && first.v1 !== last.v2 - && first.v2 !== last.v1); - // console.log({term: line, adj: line.adjacentUsed(), open, loop}); - break; - } else if (adjacent.length === 1) { - if (line.v2 !== adjacent[0].v1) { - let tmp = adjacent[0].v1; - adjacent[0].v1 = adjacent[0].v2; - adjacent[0].v2 = tmp; - if (TEST > 1) console.log('chirality mismatch fixed'); - } - line = adjacent[0]; - } else if (adjacent.length === 2) { - // follow edges according to chirality - line = adjacent[0].v1 === line.v2 ? - adjacent[0] : - adjacent[1] + fnew.push(vpos); + if (fnew.length === 3) { + // cull invalid faces (shares 2 or more points) + // if (fnew[0] === fnew[1] || fnew[0] === fnew[2] || fnew[1] === fnew[2]) { + // fnew = []; + // cull++; + // continue; + // } + let key = fnew.slice().sort().join('-'); + // drop duplicate faces (sort handles reverse order) + if (!fcac[key]) { + faces.appendAll(fnew); } else { - if (TEST > 1) console.log('error adjacent', line, adjacent, loops.length, loop.length); - line.split = adjacent; - line = adjacent[0]; + dups++; } - loop.push(line); - line.used = true; - } - if (loop.length) { - loops.push(loop); + fcac[key] = key; + fnew = []; } } + vertices = nuvt; + if (TEST) console.timeEnd('generate faces'); + if (TEST) console.log({dups, faces:faces.length/3}); + } + this.vertices = vertices; + this.faces = faces; + return this; + } - // attempt to connect open loops - if (loops.length > 1) { - outer: for (let i=0; i l !== this && !l.used && l.faces.length === 1); + } + + adjacentUsed() { + return vmap[this.v1] + .concat(vmap[this.v2]) + .filter(l => l !== this && l.used && l.faces.length === 1); + } + + touches(line) { + return this.v1 === line.v1 || + this.v1 === line.v2 || + this.v2 === line.v1 || + this.v2 === line.v2; + } + + unitVector() { + if (this.unit !== undefined) { + return this.unit; + } + let v1 = this.v1; + let v2 = this.v2; + let d = [ + vertices[v1] - vertices[v2], + vertices[v1 + 1] - vertices[v2 + 1], + vertices[v1 + 2] - vertices[v2 + 2], + ]; + let max = Math.max(...d.map(v => Math.abs(v))); + // console.log({d, max}); + return this.unit = d.map(v => v / max); + } + } + + function diffUnitVector(uv1, uv2) { + let diff = 0; + for (let i=0; i<3; i++) { + diff += Math.abs(uv1[i] - uv2[i]); + } + return diff; + } + + function getLine(v1, v2) { + let s1 = vertices[v1] + vertices[v1+1]*1000 + vertices[v1+2]*100000; + let s2 = vertices[v2] + vertices[v2+1]*1000 + vertices[v2+2]*100000; + let key = s1 <= s2 ? [v1,v2].join('-') : [v2,v1].join('-'); + let line = hash[key]; + if (!line) { + // point order will be swapped for reconstructed faces + // to preserve chirality (assuming face normals are correct) + line = hash[key] = new Line(v1, v2); + line.key = key; + lines.push(line); + let lm1 = vmap[v1] = vmap[v1] || []; + let lm2 = vmap[v2] = vmap[v2] || []; + lm1.push(line); + lm2.push(line); + } + return line; + } + + function getXYZ(v) { + return {x: vertices[v], y: vertices[v+1], z: vertices[v+2]}; + } + + for (let i=0, l=this.faces.length; i l.faces.length === 1); + let loops = this.loops = []; + + // connect edge lines into closed loops + for (let i=0, l=edges.length; i 2) { + // console.log('cannot start on a split'); + continue; + } + // line.used = true; + let loop = [ ]; + // build line through adjacent lines + while (true) { + let adjacent = line.adjacentUnused(); + if (adjacent.length === 0) { + let first = loop[0]; + let last = loop.last(); + loop.open = loop.length < 3 + || (first.v1 !== last.v1 + && first.v2 !== last.v2 + && first.v1 !== last.v2 + && first.v2 !== last.v1); + // console.log({term: line, adj: line.adjacentUsed(), open, loop}); + break; + } else if (adjacent.length === 1) { + if (line.v2 !== adjacent[0].v1) { + let tmp = adjacent[0].v1; + adjacent[0].v1 = adjacent[0].v2; + adjacent[0].v2 = tmp; + if (TEST > 1) console.log('chirality mismatch fixed'); + } + line = adjacent[0]; + } else if (adjacent.length === 2) { + // follow edges according to chirality + line = adjacent[0].v1 === line.v2 ? + adjacent[0] : + adjacent[1] + } else { + if (TEST > 1) console.log('error adjacent', line, adjacent, loops.length, loop.length); + line.split = adjacent; + line = adjacent[0]; + } + loop.push(line); + line.used = true; + } + if (loop.length) { + loops.push(loop); + } + } + + // attempt to connect open loops + if (loops.length > 1) { + outer: for (let i=0; i l && l.length <= 2); - if (TEST) console.log({edges, loops, shorts: this.shorts}); - - // filter out null and short loops - this.loops = loops = loops.filter(l => l && l.length > 2); - if (TEST > 1) console.log({loops_filtered: loops}); - - // rotate/flatten to Z plane and use earcut to generate faces - // because earcut emits point indexes, no need to un-rotate - function emitLoop(loop) { - let lastPoint; - let pindex = []; - let points = []; - let dx = 0, dy = 0, dz = 0; - - // gather points, find axis with least deviaton to swap with Z - let loop1 = loop.slice(); - loop1.push(loop[0]); - for (let i=0; i= 0) { - dx = Math.max(dx, Math.abs(vertices[lastPoint] - vertices[nextPoint])); - dy = Math.max(dy, Math.abs(vertices[lastPoint+1] - vertices[nextPoint+1])); - dz = Math.max(dz, Math.abs(vertices[lastPoint+2] - vertices[nextPoint+2])); - } - lastPoint = nextPoint; - } - - // swap Z axis with least delta axis - let swap = 2; - if (dy < dx && dy < dz) { - // swap y,z - swap = 1; - } else if (dx < dy && dx < dz) { - // swap x,z - swap = 0; - } - if (swap < 2) { - // console.log({swap_axis: swap}); - for (let point of points) { - let tmpz = point[2]; - point[2] = point[swap]; - point[swap] = tmpz; - } - } - - let fpoints = points.flat(); - let ec = earcut(fpoints, undefined, 3); - if (TEST > 2) console.log({points, fpoints, ec, dx, dy, dz}); - - for (let point of ec) { - faces.push(pindex[point]); - } - } - - // emit loops - let faceCount = this.faces.length; - for (let loop of loops) { - emitLoop(loop); - } - - this.newFaces = this.faces.length - faceCount; - if (TEST) console.log({newFaces: this.newFaces}); - - if (TEST) console.timeEnd('heal'); - return this; } - }; -})(); + // store invalid loops for display / culling + this.shorts = loops.filter(l => l && l.length <= 2); + if (TEST) console.log({edges, loops, shorts: this.shorts}); + + // filter out null and short loops + this.loops = loops = loops.filter(l => l && l.length > 2); + if (TEST > 1) console.log({loops_filtered: loops}); + + // rotate/flatten to Z plane and use earcut to generate faces + // because earcut emits point indexes, no need to un-rotate + function emitLoop(loop) { + let lastPoint; + let pindex = []; + let points = []; + let dx = 0, dy = 0, dz = 0; + + // gather points, find axis with least deviaton to swap with Z + let loop1 = loop.slice(); + loop1.push(loop[0]); + for (let i=0; i= 0) { + dx = Math.max(dx, Math.abs(vertices[lastPoint] - vertices[nextPoint])); + dy = Math.max(dy, Math.abs(vertices[lastPoint+1] - vertices[nextPoint+1])); + dz = Math.max(dz, Math.abs(vertices[lastPoint+2] - vertices[nextPoint+2])); + } + lastPoint = nextPoint; + } + + // swap Z axis with least delta axis + let swap = 2; + if (dy < dx && dy < dz) { + // swap y,z + swap = 1; + } else if (dx < dy && dx < dz) { + // swap x,z + swap = 0; + } + if (swap < 2) { + // console.log({swap_axis: swap}); + for (let point of points) { + let tmpz = point[2]; + point[2] = point[swap]; + point[swap] = tmpz; + } + } + + let fpoints = points.flat(); + let ec = earcut(fpoints, undefined, 3); + if (TEST > 2) console.log({points, fpoints, ec, dx, dy, dz}); + + for (let point of ec) { + faces.push(pindex[point]); + } + } + + // emit loops + let faceCount = this.faces.length; + for (let loop of loops) { + emitLoop(loop); + } + + this.newFaces = this.faces.length - faceCount; + if (TEST) console.log({newFaces: this.newFaces}); + + if (TEST) console.timeEnd('heal'); + return this; + } +}; + +gapp.overlay(base, { Mesh }); + +}); diff --git a/src/geo/paths.js b/src/geo/paths.js index 260be776..24069381 100644 --- a/src/geo/paths.js +++ b/src/geo/paths.js @@ -3,9 +3,12 @@ "use strict"; // path & routing output utilities -(function() { -const { base } = self; +// dep: geo.base +// dep: geo.point +gapp.register("geo.paths", [], (root, exports) => { + +const { base } = root; const { util, config, newPoint } = base; const { sqr, numOrDefault } = util; @@ -107,4 +110,4 @@ base.paths = { tip2tipEmit }; -})(); +}); diff --git a/src/geo/point.js b/src/geo/point.js index 3035c4df..7db39d45 100644 --- a/src/geo/point.js +++ b/src/geo/point.js @@ -2,11 +2,10 @@ "use strict"; -(function() { +// dep: geo.base +gapp.register("geo.point", [], (root, exports) => { -if (self.base.Point) return; - -const base = self.base; +const { base } = root; const { util, config, key } = base; const { round } = util; @@ -564,14 +563,19 @@ function p2l(p, l1, l2) { }; return d(p, pb); } + function newPoint(x, y, z, key) { return new Point(x, y, z, key); } -base.Point = Point; -base.newPoint = newPoint; -base.pointFromClipper = function(cp, z) { +function pointFromClipper(cp, z) { return newPoint(cp.X / config.clipper, cp.Y / config.clipper, z); -}; +} -})(); +gapp.overlay(base, { + Point, + newPoint, + pointFromClipper +}); + +}); diff --git a/src/geo/points.js b/src/geo/points.js index 9409d1a5..4366eb1f 100644 --- a/src/geo/points.js +++ b/src/geo/points.js @@ -2,13 +2,17 @@ "use strict"; -(function() { +// dep: geo.base +// dep: geo.point +gapp.register("geo.points", [], (root, exports) => { -const base = self.base; +const { base } = root; const { config } = base; -base.verticesToPoints = verticesToPoints; -base.pointsToVertices = pointsToVertices; +gapp.overlay(base, { + verticesToPoints, + pointsToVertices +}); /** * converts a geometry point array into a kiri point array @@ -125,4 +129,4 @@ function pointsToVertices(points) { return vertices; } -})(); +}); diff --git a/src/geo/polygon.js b/src/geo/polygon.js index 19039518..6d09aa9a 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -3,14 +3,14 @@ "use strict"; // dep: ext.clip2 +// dep: geo.point // dep: geo.bounds -// dep: geo.polygons -(function() { - -const base = self.base; -if (base.Polygon) return; +// use: geo.polygons +gapp.register("geo.polygon", [], (root, exports) => { +const { base } = root; const { config, util, polygons, newBounds, newPoint } = base; + const POLY = polygons, DEG2RAD = Math.PI / 180, clib = self.ClipperLib, @@ -1804,11 +1804,13 @@ function newPolygon(points) { return new Polygon(points); } -base.Polygon = Polygon; -base.newPolygon = newPolygon; - Polygon.fromArray = function(array) { return newPolygon().fromArray(array); }; -})(); +gapp.overlay(base, { + Polygon, + newPolygon +}); + +}); diff --git a/src/geo/polygons.js b/src/geo/polygons.js index d958ecdc..61a0736a 100644 --- a/src/geo/polygons.js +++ b/src/geo/polygons.js @@ -2,11 +2,12 @@ "use strict"; -(function() { - -const base = self.base; -if (base.polygons) return; +// dep: geo.base +// dep: geo.point +// use: geo.polygon +gapp.register("base.polygons", [], (root, exports) => { +const { base } = root; const { util, config, newPoint } = base; const { sqr, numOrDefault } = util; @@ -954,4 +955,4 @@ function route(polys, start) { return routed.map(r => r.poly); } -})(); +}); diff --git a/src/geo/slicer.js b/src/geo/slicer.js index 973cfe71..b21c9818 100644 --- a/src/geo/slicer.js +++ b/src/geo/slicer.js @@ -6,11 +6,13 @@ * basic slice and line connection. In future, replace kiri's fdm and cam slicers * with wrappers on this one. */ -(function() { - -const base = self.base; -if (base.slice) return; +// dep: geo.base +// dep: geo.line +// dep: geo.point +// dep: geo.polygon +gapp.register("geo.slicer", [], (root, exports) => { +const { base } = root; const { config, util, polygons } = base const { newOrderedLine, newPolygon, newPoint } = base; @@ -819,8 +821,10 @@ function removeDuplicateLines(lines) { return output; } -base.slice = slice; -base.sliceZ = sliceZ; -base.slicePost = {}; +gapp.overlay(base, { + slice, + sliceZ, + slicePost: {} +}); -})(); +}); diff --git a/src/geo/slope.js b/src/geo/slope.js index c93227ef..9fc6e67d 100644 --- a/src/geo/slope.js +++ b/src/geo/slope.js @@ -2,12 +2,14 @@ "use strict"; -(function() { - -const base = self.base; -if (base.Slope) return; +// dep: geo.base +// use: geo.line +// use: geo.point +gapp.register("geo.slope", [], (root, exports) => { +const { base } = root; const { config } = base; + const ABS = Math.abs, DEG2RAD = Math.PI / 180, RAD2DEG = 180 / Math.PI; @@ -96,13 +98,17 @@ function newSlope(p1, p2, dx, dy) { return new Slope(p1, p2, dx, dy); } -base.Slope = Slope; -base.newSlope = newSlope; -base.newSlopeFromAngle = function(angle) { +function newSlopeFromAngle(angle) { return newSlope(0,0, Math.cos(angle * DEG2RAD), Math.sin(angle * DEG2RAD) ); -}; +} -})(); +gapp.overlay(base, { + Slope, + newSlope, + newSlopeFromAngle +}); + +}); diff --git a/src/geo/wasm.js b/src/geo/wasm.js index aa5bc42f..0e08be8d 100644 --- a/src/geo/wasm.js +++ b/src/geo/wasm.js @@ -2,10 +2,15 @@ "use strict"; -// only active in workers -if (!self.window) (function() { +// dep: geo.base +// dep: ext.clip2 +gapp.register("geo.wasm", [], (root, exports) => { -if (!self.geo) self.geo = { +const { base } = root; +const { config } = base; + +const factor = config.clipper; +const wasm_ctrl = { enable, disable, count: { @@ -15,8 +20,7 @@ if (!self.geo) self.geo = { } }; -const factor = self.base.config.clipper; -const geo = self.geo; +gapp.overlay(base, { wasm_ctrl }); function log() { console.log(...arguments); @@ -76,9 +80,9 @@ function readPolys(view, z, out = []) { } function polyOffset(polys, offset, z, clean, simple) { - geo.count.offset++; - let wasm = geo.wasm, - buffer = geo.wasm.shared, + wasm_ctrl.count.offset++; + let wasm = base.wasm, + buffer = wasm.shared, pcount = writePolys(new DataWriter(wasm.heap, buffer), polys), resat = wasm.fn.offset(buffer, pcount, offset * factor, clean, simple), out = readPolys(new DataReader(wasm.heap, resat), z); @@ -86,9 +90,9 @@ function polyOffset(polys, offset, z, clean, simple) { } function polyUnion(polys, z) { - geo.count.union++; - let wasm = geo.wasm, - buffer = geo.wasm.shared, + wasm_ctrl.count.union++; + let wasm = base.wasm, + buffer = wasm.shared, pcount = writePolys(new DataWriter(wasm.heap, buffer), polys), resat = wasm.fn.union(buffer, pcount), out = readPolys(new DataReader(wasm.heap, resat), z); @@ -96,13 +100,13 @@ function polyUnion(polys, z) { } function polyDiff(polysA, polysB, z, AB, BA) { - geo.count.diff++; - let wasm = geo.wasm, - buffer = geo.wasm.shared, + wasm_ctrl.count.diff++; + let wasm = base.wasm, + buffer = wasm.shared, writer = new DataWriter(wasm.heap, buffer), pcountA = writePolys(writer, polysA), pcountB = writePolys(writer, polysB), - resat = wasm.fn.diff(buffer, pcountA, pcountB, AB?1:0, BA?1:0, base.config.clipperClean), + resat = wasm.fn.diff(buffer, pcountA, pcountB, AB?1:0, BA?1:0, config.clipperClean), reader = new DataReader(wasm.heap, resat); if (AB) { AB.appendAll(polyNest(readPolys(reader, z))); @@ -141,7 +145,7 @@ function polyNest(polys) { } function readString(pos, len) { - let view = new DataReader(geo.wasm.heap, pos); + let view = new DataReader(base.wasm.heap, pos); let out = []; while (len-- > 0) { out.push(String.fromCharCode(view.readU8())); @@ -150,10 +154,10 @@ function readString(pos, len) { } function enable() { - if (geo.wasm || geo._wasm) { + if (base.wasm || base._wasm) { return; } - geo._wasm = 'loading'; + base._wasm = 'loading'; fetch('/wasm/kiri-geo.wasm') .then(response => response.arrayBuffer()) .then(bytes => WebAssembly.instantiate(bytes, { @@ -169,12 +173,12 @@ function enable() { } })) .then(results => { - // console.log({enabled: geo.wasm}); - delete geo._wasm; + // console.log({enabled: base.wasm}); + delete base._wasm; let { module, instance } = results; let { exports } = instance; let heap = new DataView(exports.memory.buffer); - let wasm = geo.wasm = { + let wasm = base.wasm = { heap, exports, memory: exports.memory, @@ -197,10 +201,10 @@ function enable() { } function disable() { - if (geo.wasm) { - delete geo.wasm; + if (base.wasm) { + delete base.wasm; // console.log({disabled: geo}); } } -})(); +}); diff --git a/src/kiri/minion.js b/src/kiri/minion.js index 7457fc8f..c562541a 100644 --- a/src/kiri/minion.js +++ b/src/kiri/minion.js @@ -115,9 +115,9 @@ const funcs = { wasm: data => { if (data.enable) { - geo.enable(); + base.wasm_ctrl.enable(); } else { - geo.disable(); + base.wasm_ctrl.disable(); } }, diff --git a/src/kiri/worker.js b/src/kiri/worker.js index 4b157085..b7de7f2c 100644 --- a/src/kiri/worker.js +++ b/src/kiri/worker.js @@ -3,7 +3,7 @@ "use strict"; const { base, kiri } = self; -const { util, polygons } = base; +const { util, polygons, wasm_ctrl } = base; const { codec } = kiri; const { time } = util; const POLY = polygons; @@ -798,9 +798,9 @@ kiri.worker = { wasm: function(data, send) { if (data.enable) { - geo.enable(); + wasm_ctrl.enable(); } else { - geo.disable(); + wasm_ctrl.disable(); } minwork.wasm(data.enable); send.done({ wasm: data }); diff --git a/src/main/kiri.js b/src/main/kiri.js index 8ecf4c59..53ce45e5 100644 --- a/src/main/kiri.js +++ b/src/main/kiri.js @@ -2,24 +2,22 @@ "use strict"; -(function () { +gapp.register("main.kiri", [], (root) => { - if (!self.kiri) { - let modfns = self.kirimod = []; +const modfns = root.kirimod = []; - let kiri = self.kiri = { - beta: 3303, - driver: {}, // driver modules - load(fn) { - modfns.push(fn); - }, - load_exec(api) { - // complete module loading - modfns.forEach(modfn => { modfn(api || kiri.api)} ); - // rewrite load() to be immediate post-finalize - kiri.load = (modfn) => { modfn(api || kiri.api) }; - } - }; +const kiri = root.kiri = { + beta: 3303, + driver: {}, // driver modules + load(fn) { + modfns.push(fn); + }, + load_exec(api) { + // complete module loading + modfns.forEach(modfn => { modfn(api || kiri.api)} ); + // rewrite load() to be immediate post-finalize + kiri.load = (modfn) => { modfn(api || kiri.api) }; } +}; -})(); +});