UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

1,737 lines (1,444 loc) 1.22 MB
(self["webpackChunk_polygonjs_polygonjs"] = self["webpackChunk_polygonjs_polygonjs"] || []).push([[527],{ /***/ 79242: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const cssColors = __webpack_require__(32575) /** * Converts a CSS color name to RGB color. * * @param {String} s - the CSS color name * @return {Array} the RGB color, or undefined if not found * @alias module:modeling/colors.colorNameToRgb * @example * let mysphere = colorize(colorNameToRgb('lightblue'), sphere()) */ const colorNameToRgb = (s) => cssColors[s.toLowerCase()] module.exports = colorNameToRgb /***/ }), /***/ 78039: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const flatten = __webpack_require__(61979) const geom2 = __webpack_require__(88934) const geom3 = __webpack_require__(18206) const path2 = __webpack_require__(84345) const poly3 = __webpack_require__(71516) const colorGeom2 = (color, object) => { const newgeom2 = geom2.clone(object) newgeom2.color = color return newgeom2 } const colorGeom3 = (color, object) => { const newgeom3 = geom3.clone(object) newgeom3.color = color return newgeom3 } const colorPath2 = (color, object) => { const newpath2 = path2.clone(object) newpath2.color = color return newpath2 } const colorPoly3 = (color, object) => { const newpoly = poly3.clone(object) newpoly.color = color return newpoly } /** * Assign the given color to the given objects. * @param {Array} color - RGBA color values, where each value is between 0 and 1.0 * @param {Object|Array} objects - the objects of which to apply the given color * @return {Object|Array} new object, or list of new objects with an additional attribute 'color' * @alias module:modeling/colors.colorize * * @example * let redSphere = colorize([1,0,0], sphere()) // red * let greenCircle = colorize([0,1,0,0.8], circle()) // green transparent * let blueArc = colorize([0,0,1], arc()) // blue * let wildcylinder = colorize(colorNameToRgb('fuchsia'), cylinder()) // CSS color */ const colorize = (color, ...objects) => { if (!Array.isArray(color)) throw new Error('color must be an array') if (color.length < 3) throw new Error('color must contain R, G and B values') if (color.length === 3) color = [color[0], color[1], color[2], 1.0] // add alpha objects = flatten(objects) if (objects.length === 0) throw new Error('wrong number of arguments') const results = objects.map((object) => { if (geom2.isA(object)) return colorGeom2(color, object) if (geom3.isA(object)) return colorGeom3(color, object) if (path2.isA(object)) return colorPath2(color, object) if (poly3.isA(object)) return colorPoly3(color, object) object.color = color return object }) return results.length === 1 ? results[0] : results } module.exports = colorize /***/ }), /***/ 32575: /***/ ((module) => { /** * @alias module:modeling/colors.cssColors * @see CSS color table from http://www.w3.org/TR/css3-color/ * @enum {Array} * @example * let newshape = colorize(cssColors.red, oldshape) */ const cssColors = { // basic color keywords black: [0 / 255, 0 / 255, 0 / 255], silver: [192 / 255, 192 / 255, 192 / 255], gray: [128 / 255, 128 / 255, 128 / 255], white: [255 / 255, 255 / 255, 255 / 255], maroon: [128 / 255, 0 / 255, 0 / 255], red: [255 / 255, 0 / 255, 0 / 255], purple: [128 / 255, 0 / 255, 128 / 255], fuchsia: [255 / 255, 0 / 255, 255 / 255], green: [0 / 255, 128 / 255, 0 / 255], lime: [0 / 255, 255 / 255, 0 / 255], olive: [128 / 255, 128 / 255, 0 / 255], yellow: [255 / 255, 255 / 255, 0 / 255], navy: [0 / 255, 0 / 255, 128 / 255], blue: [0 / 255, 0 / 255, 255 / 255], teal: [0 / 255, 128 / 255, 128 / 255], aqua: [0 / 255, 255 / 255, 255 / 255], // extended color keywords aliceblue: [240 / 255, 248 / 255, 255 / 255], antiquewhite: [250 / 255, 235 / 255, 215 / 255], // 'aqua': [ 0 / 255, 255 / 255, 255 / 255 ], aquamarine: [127 / 255, 255 / 255, 212 / 255], azure: [240 / 255, 255 / 255, 255 / 255], beige: [245 / 255, 245 / 255, 220 / 255], bisque: [255 / 255, 228 / 255, 196 / 255], // 'black': [ 0 / 255, 0 / 255, 0 / 255 ], blanchedalmond: [255 / 255, 235 / 255, 205 / 255], // 'blue': [ 0 / 255, 0 / 255, 255 / 255 ], blueviolet: [138 / 255, 43 / 255, 226 / 255], brown: [165 / 255, 42 / 255, 42 / 255], burlywood: [222 / 255, 184 / 255, 135 / 255], cadetblue: [95 / 255, 158 / 255, 160 / 255], chartreuse: [127 / 255, 255 / 255, 0 / 255], chocolate: [210 / 255, 105 / 255, 30 / 255], coral: [255 / 255, 127 / 255, 80 / 255], cornflowerblue: [100 / 255, 149 / 255, 237 / 255], cornsilk: [255 / 255, 248 / 255, 220 / 255], crimson: [220 / 255, 20 / 255, 60 / 255], cyan: [0 / 255, 255 / 255, 255 / 255], darkblue: [0 / 255, 0 / 255, 139 / 255], darkcyan: [0 / 255, 139 / 255, 139 / 255], darkgoldenrod: [184 / 255, 134 / 255, 11 / 255], darkgray: [169 / 255, 169 / 255, 169 / 255], darkgreen: [0 / 255, 100 / 255, 0 / 255], darkgrey: [169 / 255, 169 / 255, 169 / 255], darkkhaki: [189 / 255, 183 / 255, 107 / 255], darkmagenta: [139 / 255, 0 / 255, 139 / 255], darkolivegreen: [85 / 255, 107 / 255, 47 / 255], darkorange: [255 / 255, 140 / 255, 0 / 255], darkorchid: [153 / 255, 50 / 255, 204 / 255], darkred: [139 / 255, 0 / 255, 0 / 255], darksalmon: [233 / 255, 150 / 255, 122 / 255], darkseagreen: [143 / 255, 188 / 255, 143 / 255], darkslateblue: [72 / 255, 61 / 255, 139 / 255], darkslategray: [47 / 255, 79 / 255, 79 / 255], darkslategrey: [47 / 255, 79 / 255, 79 / 255], darkturquoise: [0 / 255, 206 / 255, 209 / 255], darkviolet: [148 / 255, 0 / 255, 211 / 255], deeppink: [255 / 255, 20 / 255, 147 / 255], deepskyblue: [0 / 255, 191 / 255, 255 / 255], dimgray: [105 / 255, 105 / 255, 105 / 255], dimgrey: [105 / 255, 105 / 255, 105 / 255], dodgerblue: [30 / 255, 144 / 255, 255 / 255], firebrick: [178 / 255, 34 / 255, 34 / 255], floralwhite: [255 / 255, 250 / 255, 240 / 255], forestgreen: [34 / 255, 139 / 255, 34 / 255], // 'fuchsia': [ 255 / 255, 0 / 255, 255 / 255 ], gainsboro: [220 / 255, 220 / 255, 220 / 255], ghostwhite: [248 / 255, 248 / 255, 255 / 255], gold: [255 / 255, 215 / 255, 0 / 255], goldenrod: [218 / 255, 165 / 255, 32 / 255], // 'gray': [ 128 / 255, 128 / 255, 128 / 255 ], // 'green': [ 0 / 255, 128 / 255, 0 / 255 ], greenyellow: [173 / 255, 255 / 255, 47 / 255], grey: [128 / 255, 128 / 255, 128 / 255], honeydew: [240 / 255, 255 / 255, 240 / 255], hotpink: [255 / 255, 105 / 255, 180 / 255], indianred: [205 / 255, 92 / 255, 92 / 255], indigo: [75 / 255, 0 / 255, 130 / 255], ivory: [255 / 255, 255 / 255, 240 / 255], khaki: [240 / 255, 230 / 255, 140 / 255], lavender: [230 / 255, 230 / 255, 250 / 255], lavenderblush: [255 / 255, 240 / 255, 245 / 255], lawngreen: [124 / 255, 252 / 255, 0 / 255], lemonchiffon: [255 / 255, 250 / 255, 205 / 255], lightblue: [173 / 255, 216 / 255, 230 / 255], lightcoral: [240 / 255, 128 / 255, 128 / 255], lightcyan: [224 / 255, 255 / 255, 255 / 255], lightgoldenrodyellow: [250 / 255, 250 / 255, 210 / 255], lightgray: [211 / 255, 211 / 255, 211 / 255], lightgreen: [144 / 255, 238 / 255, 144 / 255], lightgrey: [211 / 255, 211 / 255, 211 / 255], lightpink: [255 / 255, 182 / 255, 193 / 255], lightsalmon: [255 / 255, 160 / 255, 122 / 255], lightseagreen: [32 / 255, 178 / 255, 170 / 255], lightskyblue: [135 / 255, 206 / 255, 250 / 255], lightslategray: [119 / 255, 136 / 255, 153 / 255], lightslategrey: [119 / 255, 136 / 255, 153 / 255], lightsteelblue: [176 / 255, 196 / 255, 222 / 255], lightyellow: [255 / 255, 255 / 255, 224 / 255], // 'lime': [ 0 / 255, 255 / 255, 0 / 255 ], limegreen: [50 / 255, 205 / 255, 50 / 255], linen: [250 / 255, 240 / 255, 230 / 255], magenta: [255 / 255, 0 / 255, 255 / 255], // 'maroon': [ 128 / 255, 0 / 255, 0 / 255 ], mediumaquamarine: [102 / 255, 205 / 255, 170 / 255], mediumblue: [0 / 255, 0 / 255, 205 / 255], mediumorchid: [186 / 255, 85 / 255, 211 / 255], mediumpurple: [147 / 255, 112 / 255, 219 / 255], mediumseagreen: [60 / 255, 179 / 255, 113 / 255], mediumslateblue: [123 / 255, 104 / 255, 238 / 255], mediumspringgreen: [0 / 255, 250 / 255, 154 / 255], mediumturquoise: [72 / 255, 209 / 255, 204 / 255], mediumvioletred: [199 / 255, 21 / 255, 133 / 255], midnightblue: [25 / 255, 25 / 255, 112 / 255], mintcream: [245 / 255, 255 / 255, 250 / 255], mistyrose: [255 / 255, 228 / 255, 225 / 255], moccasin: [255 / 255, 228 / 255, 181 / 255], navajowhite: [255 / 255, 222 / 255, 173 / 255], // 'navy': [ 0 / 255, 0 / 255, 128 / 255 ], oldlace: [253 / 255, 245 / 255, 230 / 255], // 'olive': [ 128 / 255, 128 / 255, 0 / 255 ], olivedrab: [107 / 255, 142 / 255, 35 / 255], orange: [255 / 255, 165 / 255, 0 / 255], orangered: [255 / 255, 69 / 255, 0 / 255], orchid: [218 / 255, 112 / 255, 214 / 255], palegoldenrod: [238 / 255, 232 / 255, 170 / 255], palegreen: [152 / 255, 251 / 255, 152 / 255], paleturquoise: [175 / 255, 238 / 255, 238 / 255], palevioletred: [219 / 255, 112 / 255, 147 / 255], papayawhip: [255 / 255, 239 / 255, 213 / 255], peachpuff: [255 / 255, 218 / 255, 185 / 255], peru: [205 / 255, 133 / 255, 63 / 255], pink: [255 / 255, 192 / 255, 203 / 255], plum: [221 / 255, 160 / 255, 221 / 255], powderblue: [176 / 255, 224 / 255, 230 / 255], // 'purple': [ 128 / 255, 0 / 255, 128 / 255 ], // 'red': [ 255 / 255, 0 / 255, 0 / 255 ], rosybrown: [188 / 255, 143 / 255, 143 / 255], royalblue: [65 / 255, 105 / 255, 225 / 255], saddlebrown: [139 / 255, 69 / 255, 19 / 255], salmon: [250 / 255, 128 / 255, 114 / 255], sandybrown: [244 / 255, 164 / 255, 96 / 255], seagreen: [46 / 255, 139 / 255, 87 / 255], seashell: [255 / 255, 245 / 255, 238 / 255], sienna: [160 / 255, 82 / 255, 45 / 255], // 'silver': [ 192 / 255, 192 / 255, 192 / 255 ], skyblue: [135 / 255, 206 / 255, 235 / 255], slateblue: [106 / 255, 90 / 255, 205 / 255], slategray: [112 / 255, 128 / 255, 144 / 255], slategrey: [112 / 255, 128 / 255, 144 / 255], snow: [255 / 255, 250 / 255, 250 / 255], springgreen: [0 / 255, 255 / 255, 127 / 255], steelblue: [70 / 255, 130 / 255, 180 / 255], tan: [210 / 255, 180 / 255, 140 / 255], // 'teal': [ 0 / 255, 128 / 255, 128 / 255 ], thistle: [216 / 255, 191 / 255, 216 / 255], tomato: [255 / 255, 99 / 255, 71 / 255], turquoise: [64 / 255, 224 / 255, 208 / 255], violet: [238 / 255, 130 / 255, 238 / 255], wheat: [245 / 255, 222 / 255, 179 / 255], // 'white': [ 255 / 255, 255 / 255, 255 / 255 ], whitesmoke: [245 / 255, 245 / 255, 245 / 255], // 'yellow': [ 255 / 255, 255 / 255, 0 / 255 ], yellowgreen: [154 / 255, 205 / 255, 50 / 255] } module.exports = cssColors /***/ }), /***/ 72995: /***/ ((module) => { /** * Converts CSS color notations (string of hex values) to RGB values. * * @see https://www.w3.org/TR/css-color-3/ * @param {String} notation - color notation * @return {Array} RGB color values * @alias module:modeling/colors.hexToRgb * * @example * let mysphere = colorize(hexToRgb('#000080'), sphere()) // navy blue */ const hexToRgb = (notation) => { notation = notation.replace('#', '') if (notation.length < 6) throw new Error('the given notation must contain 3 or more hex values') const r = parseInt(notation.substring(0, 2), 16) / 255 const g = parseInt(notation.substring(2, 4), 16) / 255 const b = parseInt(notation.substring(4, 6), 16) / 255 if (notation.length >= 8) { const a = parseInt(notation.substring(6, 8), 16) / 255 return [r, g, b, a] } return [r, g, b] } module.exports = hexToRgb /***/ }), /***/ 16371: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const flatten = __webpack_require__(61979) const hueToColorComponent = __webpack_require__(12915) /** * Converts HSL color values to RGB color values. * * @see http://en.wikipedia.org/wiki/HSL_color_space * @param {...Number|Array} values - HSL or HSLA color values * @return {Array} RGB or RGBA color values * @alias module:modeling/colors.hslToRgb * * @example * let mysphere = colorize(hslToRgb([0.9166666666666666, 1, 0.5]), sphere()) */ const hslToRgb = (...values) => { values = flatten(values) if (values.length < 3) throw new Error('values must contain H, S and L values') const h = values[0] const s = values[1] const l = values[2] let r = l // default is achromatic let g = l let b = l if (s !== 0) { const q = l < 0.5 ? l * (1 + s) : l + s - l * s const p = 2 * l - q r = hueToColorComponent(p, q, h + 1 / 3) g = hueToColorComponent(p, q, h) b = hueToColorComponent(p, q, h - 1 / 3) } if (values.length > 3) { // add alpha value if provided const a = values[3] return [r, g, b, a] } return [r, g, b] } module.exports = hslToRgb /***/ }), /***/ 82699: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const flatten = __webpack_require__(61979) /** * Converts HSV color values to RGB color values. * * @see http://en.wikipedia.org/wiki/HSV_color_space. * @param {...Number|Array} values - HSV or HSVA color values * @return {Array} RGB or RGBA color values * @alias module:modeling/colors.hsvToRgb * * @example * let mysphere = colorize(hsvToRgb([0.9166666666666666, 1, 1]), sphere()) */ const hsvToRgb = (...values) => { values = flatten(values) if (values.length < 3) throw new Error('values must contain H, S and V values') const h = values[0] const s = values[1] const v = values[2] let r = 0 let g = 0 let b = 0 const i = Math.floor(h * 6) const f = h * 6 - i const p = v * (1 - s) const q = v * (1 - f * s) const t = v * (1 - (1 - f) * s) switch (i % 6) { case 0: r = v g = t b = p break case 1: r = q g = v b = p break case 2: r = p g = v b = t break case 3: r = p g = q b = v break case 4: r = t g = p b = v break case 5: r = v g = p b = q break } if (values.length > 3) { // add alpha value if provided const a = values[3] return [r, g, b, a] } return [r, g, b] } module.exports = hsvToRgb /***/ }), /***/ 12915: /***/ ((module) => { /** * Convert hue values to a color component (ie one of r, g, b) * @param {Number} p * @param {Number} q * @param {Number} t * @return {Number} color component * @alias module:modeling/colors.hueToColorComponent */ const hueToColorComponent = (p, q, t) => { if (t < 0) t += 1 if (t > 1) t -= 1 if (t < 1 / 6) return p + (q - p) * 6 * t if (t < 1 / 2) return q if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6 return p } module.exports = hueToColorComponent /***/ }), /***/ 81457: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * All shapes (primitives or the results of operations) can be assigned a color (RGBA). * In all cases, the function returns the results, and never changes the original shapes. * @module modeling/colors * @example * const { colorize, hexToRgb } = require('@jscad/modeling').colors */ module.exports = { colorize: __webpack_require__(78039), colorNameToRgb: __webpack_require__(79242), cssColors: __webpack_require__(32575), hexToRgb: __webpack_require__(72995), hslToRgb: __webpack_require__(16371), hsvToRgb: __webpack_require__(82699), hueToColorComponent: __webpack_require__(12915), rgbToHex: __webpack_require__(65831), rgbToHsl: __webpack_require__(49142), rgbToHsv: __webpack_require__(18615) } /***/ }), /***/ 65831: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const flatten = __webpack_require__(61979) /** * Convert the given RGB color values to CSS color notation (string) * @see https://www.w3.org/TR/css-color-3/ * @param {...Number|Array} values - RGB or RGBA color values * @return {String} CSS color notation * @alias module:modeling/colors.rgbToHex */ const rgbToHex = (...values) => { values = flatten(values) if (values.length < 3) throw new Error('values must contain R, G and B values') const r = values[0] * 255 const g = values[1] * 255 const b = values[2] * 255 let s = `#${Number(0x1000000 + r * 0x10000 + g * 0x100 + b).toString(16).substring(1, 7)}` if (values.length > 3) { // convert alpha to opacity s = s + Number(values[3] * 255).toString(16) } return s } module.exports = rgbToHex /***/ }), /***/ 49142: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const flatten = __webpack_require__(61979) /** * Converts an RGB color value to HSL. * * @see http://en.wikipedia.org/wiki/HSL_color_space. * @see http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c * @param {...Number|Array} values - RGB or RGBA color values * @return {Array} HSL or HSLA color values * @alias module:modeling/colors.rgbToHsl */ const rgbToHsl = (...values) => { values = flatten(values) if (values.length < 3) throw new Error('values must contain R, G and B values') const r = values[0] const g = values[1] const b = values[2] const max = Math.max(r, g, b) const min = Math.min(r, g, b) let h let s const l = (max + min) / 2 if (max === min) { h = s = 0 // achromatic } else { const d = max - min s = l > 0.5 ? d / (2 - max - min) : d / (max + min) switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0) break case g: h = (b - r) / d + 2 break case b: h = (r - g) / d + 4 break } h /= 6 } if (values.length > 3) { // add alpha value if provided const a = values[3] return [h, s, l, a] } return [h, s, l] } module.exports = rgbToHsl /***/ }), /***/ 18615: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const flatten = __webpack_require__(61979) /** * Converts an RGB color value to HSV. * * @see http://en.wikipedia.org/wiki/HSV_color_space. * @param {...Number|Array} values - RGB or RGBA color values * @return {Array} HSV or HSVA color values * @alias module:modeling/colors.rgbToHsv */ const rgbToHsv = (...values) => { values = flatten(values) if (values.length < 3) throw new Error('values must contain R, G and B values') const r = values[0] const g = values[1] const b = values[2] const max = Math.max(r, g, b) const min = Math.min(r, g, b) let h const v = max const d = max - min const s = max === 0 ? 0 : d / max if (max === min) { h = 0 // achromatic } else { switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0) break case g: h = (b - r) / d + 2 break case b: h = (r - g) / d + 4 break } h /= 6 } if (values.length > 3) { // add alpha if provided const a = values[3] return [h, s, v, a] } return [h, s, v] } module.exports = rgbToHsv /***/ }), /***/ 9590: /***/ ((module) => { /** * Represents a bezier easing function. * @typedef {Object} bezier * @property {Array} points - The control points for the bezier curve. The first and last point will also be the start and end of the curve * @property {string} pointType - A reference to the type and dimensionality of the points that the curve was created from * @property {number} dimensions - The dimensionality of the bezier * @property {Array} permutations - A pre-calculation of the bezier algorithm's co-efficients * @property {Array} tangentPermutations - A pre-calculation of the bezier algorithm's tangent co-efficients * */ /** * Creates an object representing a bezier easing curve. * Curves can have both an arbitrary number of control points, and an arbitrary number of dimensions. * * @example * const b = bezier.create([0,10]) // a linear progression from 0 to 10 * const b = bezier.create([0, 0, 10, 10]) // a symmetrical cubic easing curve that starts slowly and ends slowly from 0 to 10 * const b = bezier.create([0,0,0], [0,5,10], [10,0,-5], [10,10,10]]) // a cubic 3 dimensional easing curve that can generate position arrays for modelling * // Usage * let position = bezier.valueAt(t,b) // where 0 < t < 1 * let tangent = bezier.tangentAt(t,b) // where 0 < t < 1 * * @param {Array} points An array with at least 2 elements of either all numbers, or all arrays of numbers that are the same size. * @returns {bezier} a new bezier data object * @alias module:modeling/curves/bezier.create */ const create = (points) => { if (!Array.isArray(points)) throw new Error('Bezier points must be a valid array/') if (points.length < 2) throw new Error('Bezier points must contain at least 2 values.') const pointType = getPointType(points) return { points: points, pointType: pointType, dimensions: pointType === 'float_single' ? 0 : points[0].length, permutations: getPermutations(points.length - 1), tangentPermutations: getPermutations(points.length - 2) } } const getPointType = function (points) { let firstPointType = null points.forEach((point) => { let pType = '' if (Number.isFinite(point)) { pType = 'float_single' } else if (Array.isArray(point)) { point.forEach((val) => { if (!Number.isFinite(val)) throw new Error('Bezier point values must all be numbers.') }) pType = 'float_' + point.length } else throw new Error('Bezier points must all be numbers or arrays of number.') if (firstPointType == null) { firstPointType = pType } else { if (firstPointType !== pType) { throw new Error('Bezier points must be either all numbers or all arrays of numbers of the same size.') } } }) return firstPointType } const getPermutations = function (c) { const permutations = [] for (let i = 0; i <= c; i++) { permutations.push(factorial(c) / (factorial(i) * factorial(c - i))) } return permutations } const factorial = function (b) { let out = 1 for (let i = 2; i <= b; i++) { out *= i } return out } module.exports = create /***/ }), /***/ 45235: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * Represents a bezier easing function. * @see {@link bezier} for data structure information. * @module modeling/curves/bezier */ module.exports = { create: __webpack_require__(9590), valueAt: __webpack_require__(87501), tangentAt: __webpack_require__(48542) } /***/ }), /***/ 48542: /***/ ((module) => { /** * Calculates the tangent at a specific position along a bezier easing curve. * For multidimensional curves, the tangent is the slope of each dimension at that point. * See the example called extrudeAlongPath.js * * @example * const b = bezier.create([[0,0,0], [0,5,10], [10,0,-5], [10,10,10]]) // a cubic 3 dimensional easing curve that can generate position arrays for modelling * let tangent = bezier.tangentAt(t, b) * * @param {number} t : the position of which to calculate the bezier's tangent value; 0 < t < 1 * @param {Object} bezier : an array with at least 2 elements of either all numbers, or all arrays of numbers that are the same size. * @return {array | number} the tangent at the requested position. * @alias module:modeling/curves/bezier.tangentAt */ const tangentAt = (t, bezier) => { if (t < 0 || t > 1) { throw new Error('Bezier tangentAt() input must be between 0 and 1') } if (bezier.pointType === 'float_single') { return bezierTangent(bezier, bezier.points, t) } else { const result = [] for (let i = 0; i < bezier.dimensions; i++) { const singleDimensionPoints = [] for (let j = 0; j < bezier.points.length; j++) { singleDimensionPoints.push(bezier.points[j][i]) } result.push(bezierTangent(bezier, singleDimensionPoints, t)) } return result } } const bezierTangent = function (bezier, p, t) { // from https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-der.html const n = p.length - 1 let result = 0 for (let i = 0; i < n; i++) { const q = n * (p[i + 1] - p[i]) result += bezier.tangentPermutations[i] * Math.pow(1 - t, n - 1 - i) * Math.pow(t, i) * q } return result } module.exports = tangentAt /***/ }), /***/ 87501: /***/ ((module) => { /** * Calculates the value at a specific position along a bezier easing curve. * For multidimensional curves, the tangent is the slope of each dimension at that point. * See the example called extrudeAlongPath.js to see this in use. * Math and explanation comes from {@link https://www.freecodecamp.org/news/nerding-out-with-bezier-curves-6e3c0bc48e2f/} * * @example * const b = bezier.create([0,0,0], [0,5,10], [10,0,-5], [10,10,10]]) // a cubic 3 dimensional easing curve that can generate position arrays for modelling * let position = bezier.valueAt(t,b) // where 0 < t < 1 * * @param {number} t : the position of which to calculate the value; 0 < t < 1 * @param {Object} bezier : a bezier curve created with bezier.create(). * @returns {array | number} the value at the requested position. * @alias module:modeling/curves/bezier.valueAt */ const valueAt = (t, bezier) => { if (t < 0 || t > 1) { throw new Error('Bezier valueAt() input must be between 0 and 1') } if (bezier.pointType === 'float_single') { return bezierFunction(bezier, bezier.points, t) } else { const result = [] for (let i = 0; i < bezier.dimensions; i++) { const singleDimensionPoints = [] for (let j = 0; j < bezier.points.length; j++) { singleDimensionPoints.push(bezier.points[j][i]) } result.push(bezierFunction(bezier, singleDimensionPoints, t)) } return result } } const bezierFunction = function (bezier, p, t) { const n = p.length - 1 let result = 0 for (let i = 0; i <= n; i++) { result += bezier.permutations[i] * Math.pow(1 - t, n - i) * Math.pow(t, i) * p[i] } return result } module.exports = valueAt /***/ }), /***/ 50164: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * Curves are n-dimensional mathematical constructs that define a path from point 0 to point 1. * @module modeling/curves * @example * const { bezier } = require('@jscad/modeling').curves */ module.exports = { bezier: __webpack_require__(45235) } /***/ }), /***/ 10580: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const mat4 = __webpack_require__(36028) const vec2 = __webpack_require__(4138) /* * Apply the transforms of the given geometry. * NOTE: This function must be called BEFORE exposing any data. See toSides(). * @param {geom2} geometry - the geometry to transform * @returns {geom2} the given geometry * * @example * geometry = applyTransforms(geometry) */ const applyTransforms = (geometry) => { if (mat4.isIdentity(geometry.transforms)) return geometry // apply transforms to each side geometry.sides = geometry.sides.map((side) => { const p0 = vec2.transform(vec2.create(), side[0], geometry.transforms) const p1 = vec2.transform(vec2.create(), side[1], geometry.transforms) return [p0, p1] }) geometry.transforms = mat4.create() return geometry } module.exports = applyTransforms /***/ }), /***/ 29584: /***/ ((module) => { /** * Performs a shallow clone of the given geometry. * @param {geom2} geometry - the geometry to clone * @returns {geom2} new geometry * @alias module:modeling/geometries/geom2.clone */ const clone = (geometry) => Object.assign({}, geometry) module.exports = clone /***/ }), /***/ 95771: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const mat4 = __webpack_require__(36028) /** * Represents a 2D geometry consisting of a list of sides. * @typedef {Object} geom2 * @property {Array} sides - list of sides, each side containing two points * @property {mat4} transforms - transforms to apply to the sides, see transform() */ /** * Create a new 2D geometry composed of unordered sides (two connected points). * @param {Array} [sides] - list of sides where each side is an array of two points * @returns {geom2} a new geometry * @alias module:modeling/geometries/geom2.create */ const create = (sides) => { if (sides === undefined) { sides = [] // empty contents } return { sides: sides, transforms: mat4.create() } } module.exports = create /***/ }), /***/ 1683: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const mat4 = __webpack_require__(36028) const vec2 = __webpack_require__(4138) const create = __webpack_require__(95771) /** * Create a new 2D geometry from the given compact binary data. * @param {Array} data - compact binary data * @returns {geom2} a new geometry * @alias module:modeling/geometries/geom2.fromCompactBinary */ const fromCompactBinary = (data) => { if (data[0] !== 0) throw new Error('invalid compact binary data') const created = create() created.transforms = mat4.clone(data.slice(1, 17)) for (let i = 21; i < data.length; i += 4) { const point0 = vec2.fromValues(data[i + 0], data[i + 1]) const point1 = vec2.fromValues(data[i + 2], data[i + 3]) created.sides.push([point0, point1]) } // transfer known properties, i.e. color if (data[17] >= 0) { created.color = [data[17], data[18], data[19], data[20]] } // TODO: how about custom properties or fields ? return created } module.exports = fromCompactBinary /***/ }), /***/ 74017: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const vec2 = __webpack_require__(4138) const create = __webpack_require__(95771) /** * Create a new 2D geometry from the given points. * The direction (rotation) of the points is not relevant, * as the points can define a convex or a concave polygon. * The geometry must not self intersect, i.e. the sides cannot cross. * @param {Array} points - list of points in 2D space * @returns {geom2} a new geometry * @alias module:modeling/geometries/geom2.fromPoints */ const fromPoints = (points) => { if (!Array.isArray(points)) { throw new Error('the given points must be an array') } let length = points.length if (length < 3) { throw new Error('the given points must define a closed geometry with three or more points') } // adjust length if the given points are closed by the same point if (vec2.equals(points[0], points[length - 1])) --length const sides = [] let prevpoint = points[length - 1] for (let i = 0; i < length; i++) { const point = points[i] sides.push([vec2.clone(prevpoint), vec2.clone(point)]) prevpoint = point } return create(sides) } module.exports = fromPoints /***/ }), /***/ 88934: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * Represents a 2D geometry consisting of a list of sides. * @see {@link geom2} for data structure information. * @module modeling/geometries/geom2 * * @example * colorize([0.5,0,1,1], square()) // purple square * * @example * { * "sides": [[[-1,1],[-1,-1]],[[-1,-1],[1,-1]],[[1,-1],[1,1]],[[1,1],[-1,1]]], * "transforms": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1], * "color": [0.5,0,1,1] * } */ module.exports = { clone: __webpack_require__(29584), create: __webpack_require__(95771), fromPoints: __webpack_require__(74017), fromCompactBinary: __webpack_require__(1683), isA: __webpack_require__(8176), reverse: __webpack_require__(76506), toOutlines: __webpack_require__(75494), toPoints: __webpack_require__(12863), toSides: __webpack_require__(17999), toString: __webpack_require__(5519), toCompactBinary: __webpack_require__(68423), transform: __webpack_require__(69843), validate: __webpack_require__(4164) } /***/ }), /***/ 8176: /***/ ((module) => { /** * Determine if the given object is a 2D geometry. * @param {Object} object - the object to interrogate * @returns {Boolean} true, if the object matches a geom2 based object * @alias module:modeling/geometries/geom2.isA */ const isA = (object) => { if (object && typeof object === 'object') { if ('sides' in object && 'transforms' in object) { if (Array.isArray(object.sides) && 'length' in object.transforms) { return true } } } return false } module.exports = isA /***/ }), /***/ 76506: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const create = __webpack_require__(95771) const toSides = __webpack_require__(17999) /** * Reverses the given geometry so that the sides are flipped in the opposite order. * This swaps the left (interior) and right (exterior) edges. * @param {geom2} geometry - the geometry to reverse * @returns {geom2} the new reversed geometry * @alias module:modeling/geometries/geom2.reverse * * @example * let newgeometry = reverse(geometry) */ const reverse = (geometry) => { const oldsides = toSides(geometry) const newsides = oldsides.map((side) => [side[1], side[0]]) newsides.reverse() // is this required? return create(newsides) } module.exports = reverse /***/ }), /***/ 68423: /***/ ((module) => { /** * Produces a compact binary representation from the given geometry. * @param {geom2} geometry - the geometry * @returns {TypedArray} compact binary representation * @alias module:modeling/geometries/geom2.toCompactBinary */ const toCompactBinary = (geometry) => { const sides = geometry.sides const transforms = geometry.transforms let color = [-1, -1, -1, -1] if (geometry.color) color = geometry.color // FIXME why Float32Array? const compacted = new Float32Array(1 + 16 + 4 + (sides.length * 4)) // type + transforms + color + sides data compacted[0] = 0 // type code: 0 => geom2, 1 => geom3 , 2 => path2 compacted[1] = transforms[0] compacted[2] = transforms[1] compacted[3] = transforms[2] compacted[4] = transforms[3] compacted[5] = transforms[4] compacted[6] = transforms[5] compacted[7] = transforms[6] compacted[8] = transforms[7] compacted[9] = transforms[8] compacted[10] = transforms[9] compacted[11] = transforms[10] compacted[12] = transforms[11] compacted[13] = transforms[12] compacted[14] = transforms[13] compacted[15] = transforms[14] compacted[16] = transforms[15] compacted[17] = color[0] compacted[18] = color[1] compacted[19] = color[2] compacted[20] = color[3] for (let i = 0; i < sides.length; i++) { const ci = i * 4 + 21 const point0 = sides[i][0] const point1 = sides[i][1] compacted[ci + 0] = point0[0] compacted[ci + 1] = point0[1] compacted[ci + 2] = point1[0] compacted[ci + 3] = point1[1] } // TODO: how about custom properties or fields ? return compacted } module.exports = toCompactBinary /***/ }), /***/ 75494: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const vec2 = __webpack_require__(4138) const toSides = __webpack_require__(17999) /* * Create a list of edges which SHARE vertices. * This allows the edges to be traversed in order. */ const toSharedVertices = (sides) => { const unique = new Map() // {key: vertex} const getUniqueVertex = (vertex) => { const key = vertex.toString() if (unique.has(key)) { return unique.get(key) } else { unique.set(key, vertex) return vertex } } return sides.map((side) => side.map(getUniqueVertex)) } /* * Convert a list of sides into a map from vertex to edges. */ const toVertexMap = (sides) => { const vertexMap = new Map() // first map to edges with shared vertices const edges = toSharedVertices(sides) // construct adjacent edges map edges.forEach((edge) => { if (vertexMap.has(edge[0])) { vertexMap.get(edge[0]).push(edge) } else { vertexMap.set(edge[0], [edge]) } }) return vertexMap } /** * Create the outline(s) of the given geometry. * @param {geom2} geometry - geometry to create outlines from * @returns {Array} an array of outlines, where each outline is an array of ordered points * @alias module:modeling/geometries/geom2.toOutlines * * @example * let geometry = subtract(rectangle({size: [5, 5]}), rectangle({size: [3, 3]})) * let outlines = toOutlines(geometry) // returns two outlines */ const toOutlines = (geometry) => { const vertexMap = toVertexMap(toSides(geometry)) // {vertex: [edges]} const outlines = [] while (true) { let startSide for (const [vertex, edges] of vertexMap) { startSide = edges.shift() if (!startSide) { vertexMap.delete(vertex) continue } break } if (startSide === undefined) break // all starting sides have been visited const connectedVertexPoints = [] const startVertex = startSide[0] while (true) { connectedVertexPoints.push(startSide[0]) const nextVertex = startSide[1] if (nextVertex === startVertex) break // the outline has been closed const nextPossibleSides = vertexMap.get(nextVertex) if (!nextPossibleSides) { throw new Error(`geometry is not closed at vertex ${nextVertex}`) } const nextSide = popNextSide(startSide, nextPossibleSides) if (nextPossibleSides.length === 0) { vertexMap.delete(nextVertex) } startSide = nextSide } // inner loop // due to the logic of fromPoints() // move the first point to the last if (connectedVertexPoints.length > 0) { connectedVertexPoints.push(connectedVertexPoints.shift()) } outlines.push(connectedVertexPoints) } // outer loop vertexMap.clear() return outlines } // find the first counter-clockwise edge from startSide and pop from nextSides const popNextSide = (startSide, nextSides) => { if (nextSides.length === 1) { return nextSides.pop() } const v0 = vec2.create() const startAngle = vec2.angleDegrees(vec2.subtract(v0, startSide[1], startSide[0])) let bestAngle let bestIndex nextSides.forEach((nextSide, index) => { const nextAngle = vec2.angleDegrees(vec2.subtract(v0, nextSide[1], nextSide[0])) let angle = nextAngle - startAngle if (angle < -180) angle += 360 if (angle >= 180) angle -= 360 if (bestIndex === undefined || angle > bestAngle) { bestIndex = index bestAngle = angle } }) const nextSide = nextSides[bestIndex] nextSides.splice(bestIndex, 1) // remove side from list return nextSide } module.exports = toOutlines /***/ }), /***/ 12863: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const toSides = __webpack_require__(17999) /** * Produces an array of points from the given geometry. * The returned array should not be modified as the points are shared with the geometry. * NOTE: The points returned do NOT define an order. Use toOutlines() for ordered points. * @param {geom2} geometry - the geometry * @returns {Array} an array of points * @alias module:modeling/geometries/geom2.toPoints * * @example * let sharedpoints = toPoints(geometry) */ const toPoints = (geometry) => { const sides = toSides(geometry) const points = sides.map((side) => side[0]) // due to the logic of fromPoints() // move the first point to the last if (points.length > 0) { points.push(points.shift()) } return points } module.exports = toPoints /***/ }), /***/ 17999: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const applyTransforms = __webpack_require__(10580) /** * Produces an array of sides from the given geometry. * The returned array should not be modified as the data is shared with the geometry. * NOTE: The sides returned do NOT define an order. Use toOutlines() for ordered points. * @param {geom2} geometry - the geometry * @returns {Array} an array of sides * @alias module:modeling/geometries/geom2.toSides * * @example * let sharedsides = toSides(geometry) */ const toSides = (geometry) => applyTransforms(geometry).sides module.exports = toSides /***/ }), /***/ 5519: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const vec2 = __webpack_require__(4138) const toSides = __webpack_require__(17999) /** * Create a string representing the contents of the given geometry. * @param {geom2} geometry - the geometry * @returns {String} a representative string * @alias module:modeling/geometries/geom2.toString * * @example * console.out(toString(geometry)) */ const toString = (geometry) => { const sides = toSides(geometry) let result = 'geom2 (' + sides.length + ' sides):\n[\n' sides.forEach((side) => { result += ' [' + vec2.toString(side[0]) + ', ' + vec2.toString(side[1]) + ']\n' }) result += ']\n' return result } module.exports = toString /***/ }), /***/ 69843: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const mat4 = __webpack_require__(36028) /** * Transform the given geometry using the given matrix. * This is a lazy transform of the sides, as this function only adjusts the transforms. * The transforms are applied when accessing the sides via toSides(). * @param {mat4} matrix - the matrix to transform with * @param {geom2} geometry - the geometry to transform * @returns {geom2} a new geometry * @alias module:modeling/geometries/geom2.transform * * @example * let newgeometry = transform(fromZRotation(degToRad(90)), geometry) */ const transform = (matrix, geometry) => { const transforms = mat4.multiply(mat4.create(), matrix, geometry.transforms) return Object.assign({}, geometry, { transforms }) } module.exports = transform /***/ }), /***/ 4164: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const vec2 = __webpack_require__(4138) const isA = __webpack_require__(8176) const toOutlines = __webpack_require__(75494) /** * Determine if the given object is a valid geom2. * Checks for closedness, self-edges, and valid data points. * * **If the geometry is not valid, an exception will be thrown with details of the geometry error.** * * @param {Object} object - the object to interrogate * @throws {Error} error if the geometry is not valid * @alias module:modeling/geometries/geom2.validate */ const validate = (object) => { if (!isA(object)) { throw new Error('invalid geom2 structure') } // check for closedness toOutlines(object) // check for self-edges object.sides.forEach((side) => { if (vec2.equals(side[0], side[1])) { throw new Error(`geom2 self-edge ${side[0]}`) } }) // check transforms if (!object.transforms.every(Number.isFinite)) { throw new Error(`geom2 invalid transforms ${object.transforms}`) } } module.exports = validate /***/ }), /***/ 58865: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const mat4 = __webpack_require__(36028) const poly3 = __webpack_require__(71516) /* * Apply the transforms of the given geometry. * NOTE: This function must be called BEFORE exposing any data. See toPolygons. * @param {geom3} geometry - the geometry to transform * @returns {geom3} the given geometry * @example * geometry = applyTransforms(geometry) */ const applyTransforms = (geometry) => { if (mat4.isIdentity(geometry.transforms)) return geometry // apply transforms to each polygon geometry.polygons = geometry.polygons.map((polygon) => poly3.transform(geometry.transforms, polygon)) // reset transforms geometry.transforms = mat4.create() return geometry } module.exports = applyTransforms /***/ }), /***/ 47565: /***/ ((module) => { /** * Performs a shallow clone of the given geometry. * @param {geom3} geometry - the geometry to clone * @returns {geom3} a new geometry * @alias module:modeling/geometries/geom3.clone */ const clone = (geometry) => Object.assign({}, geometry) module.exports = clone /***/ }), /***/ 6997: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const mat4 = __webpack_require__(36028) /** * Represents a 3D geometry consisting of a list of polygons. * @typedef {Object} geom3 * @property {Array} polygons - list of polygons, each polygon containing three or more points * @property {mat4} transforms - transforms to apply to the polygons, see transform() */ /** * Create a new 3D geometry composed of the given polygons. * @param {Array} [polygons] - list of polygons, or undefined * @returns {geom3} a new geometry * @alias module:modeling/geometries/geom3.create */ const create = (polygons) => { if (polygons === undefined) { polygons = [] // empty contents } return { polygons, transforms: mat4.create() } } module.exports = create /***/ }), /***/ 60922: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const vec3 = __webpack_require__(14171) const mat4 = __webpack_require__(36028) const poly3 = __webpack_require__(71516) const create = __webpack_require__(6997) /** * Construct a new 3D geometry from the given compact binary data. * @param {TypedArray} data - compact binary data * @returns {geom3} a new geometry * @alias module:modeling/geometries/geom3.fromCompactBinary */ const fromCompactBinary = (data) => { if (data[0] !== 1) throw new Error('invalid compact binary data') const created = create() created.transforms = mat4.clone(data.slice(1, 17)) const numberOfVertices = data[21] let ci = 22 let vi = data.length - (numberOfVertices * 3) while (vi < data.length) { const verticesPerPolygon = data[ci] ci++ const vertices = [] for (let i = 0; i < verticesPerPolygon; i++) { vertices.push(vec3.fromValues(data[vi], data[vi + 1], data[vi + 2])) vi += 3 } created.polygons.push(poly3.create(vertices)) } // transfer known properties, i.e. color if (data[17] >= 0) { created.color = [data[17], data[18], data[19], data[20]] } // TODO: how about custom properties or fields ? return created } module.exports = fromCompactBinary /***/ }), /***/ 30412: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const poly3 = __webpack_require__(71516) const create = __webpack_require__(6997) /** * Construct a new 3D geometry from a list of points. * The list of points should contain sub-arrays, each defining a single polygon of points. * In addition, the points should follow the right-hand rule for rotation in order to * define an external facing polygon. * @param {Array} listofpoints - list of lists, where each list is a set of points to construct a polygon * @returns {geom3} a new geometry * @alias module:modeling/geometries/geom3.fromPoints */ const fromPoints = (listofpoints) => { if (!Array.isArray(listofpoints)) { throw new Error('the given points must be an array') } const polygons = listofpoints.map((points, index) => { // TODO catch the error, and rethrow with index const polygon = poly3.create(points) return polygon }) const result = create(polygons) return result } module.exports = fromPoints /***/ }), /***/ 18206: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * Represents a 3D geometry consisting of a list of polygons. * @see {@link geom3} for data structure information. * @module modeling/geometries/geom3 * * @example * colorize([0,0.5,1,0.6], cube()) // transparent ice cube * * @example * { * "polygons": [ * {"vertices": [[-1,-1,-1], [-1,-1,1], [-1,1,1], [-1,1,-1]]}, * {"vertices": [[1,-1,-1], [1,1,-1], [1,1,1], [1,-1,1]]}, * {"vertices": [[-1,-1,-1], [1,-1,-1], [1,-1,1], [-1,-1,1]]}, * {"vertices": [[-1,1,-1], [-1,1,1], [1,1,1], [1,1,-1]]}, * {"vertices": [[-1,-1,-1], [-1,1,-1], [1,1,-1], [1,-1,-1]]}, * {"vertices": [[-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1]]} * ], * "transforms": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1], * "color": [0,0.5,1,0.6] * } */ module.exports = { clone: __webpack_require__(47565), create: __webpack_require__(6997), fromPoints: __webpack_require__(30412), fromCompactBinary: __webpack_require__(60922), invert: __webpack_require__(35208), isA: __webpack_require__(35165), toPoints: __webpack_require__(6986), toPolygons: __webpack_require__(48356), toString: __webpack_require__(98390), toCompactBinary: __webpack_require__(61622), transform: __webpack_require__(48634), validate: __webpack_require__(59739) } /***/ }), /***/ 35208: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const poly3 = __webpack_require__(71516) const create = __webpack_require__(6997) const toPolygons = __webpack_require__(48356) /** * Invert the given geometry, transposing solid and empty space. * @param {geom3} geometry - the geometry to invert * @return {geom3} a new geometry * @alias module:modeling/geometries/geom3.invert */ const invert = (geometry) => { const polygons = toPolygons(geometry) const newpolygons = polygons.map((polygon) => poly3.invert(polygon)) return create(newpolygons) } module.exports = invert /***/ }), /***/ 35165: /***/ ((module) => { /** * Determine if the given object is a 3D geometry. * @param {Object} object - the object to interrogate * @returns {Boolean} true if the object matches a geom3 * @alias module:modeling/geometries/geom3.isA */ const isA = (object) => { if (object && typeof object === 'object') { if ('polygons' in object && 'transforms' in object) { if (Array.isArray(object.polygons) && 'length' in object.transforms) { return true } } } return false } module.exports = isA /***/ }), /***/ 61622: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const poly3 = __webpack_require__(71516) /** * Return the given geometry in compact binary representation. * @param {geom3} geometry - the geometry * @return {TypedArray} compact binary representation * @alias module:modeling/geometries/geom3.toCompactBinary */ const