@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
1,737 lines (1,444 loc) • 1.24 MB
JavaScript
(self["webpackChunk_polygonjs_polygonjs"] = self["webpackChunk_polygonjs_polygonjs"] || []).push([[191],{
/***/ 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