@jscad/modeling 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/dist/jscad-modeling.min.js +142 -139
- package/package.json +2 -2
- package/src/colors/hslToRgb.js +1 -1
- package/src/colors/hueToColorComponent.js +1 -0
- package/src/curves/bezier/create.js +3 -8
- package/src/curves/bezier/tangentAt.js +2 -2
- package/src/curves/bezier/tangentAt.test.js +1 -1
- package/src/curves/bezier/valueAt.test.js +1 -1
- package/src/curves/index.js +1 -1
- package/src/geometries/geom2/index.js +10 -0
- package/src/geometries/geom2/isA.js +2 -2
- package/src/geometries/geom2/toCompactBinary.js +4 -4
- package/src/geometries/geom2/toOutlines.js +6 -11
- package/src/geometries/geom2/toString.js +1 -1
- package/src/geometries/geom2/transform.test.js +1 -1
- package/src/geometries/geom3/create.js +1 -1
- package/src/geometries/geom3/fromCompactBinary.js +1 -1
- package/src/geometries/geom3/index.js +17 -0
- package/src/geometries/geom3/invert.js +2 -2
- package/src/geometries/geom3/isA.js +2 -2
- package/src/geometries/geom3/toCompactBinary.js +4 -4
- package/src/geometries/geom3/toPoints.js +1 -0
- package/src/geometries/geom3/toString.js +1 -1
- package/src/geometries/geom3/transform.test.js +1 -1
- package/src/geometries/index.js +8 -1
- package/src/geometries/path2/eachPoint.js +3 -3
- package/src/geometries/path2/index.js +11 -0
- package/src/geometries/path2/isA.js +2 -2
- package/src/geometries/path2/reverse.js +4 -4
- package/src/geometries/path2/toCompactBinary.js +6 -6
- package/src/geometries/path2/toString.js +1 -1
- package/src/geometries/path2/transform.test.js +1 -1
- package/src/geometries/poly2/arePointsInside.test.js +1 -1
- package/src/geometries/poly2/index.js +6 -0
- package/src/geometries/poly3/index.js +7 -1
- package/src/geometries/poly3/isA.js +2 -2
- package/src/geometries/poly3/isConvex.js +2 -2
- package/src/geometries/poly3/measureArea.js +4 -4
- package/src/geometries/poly3/measureBoundingBox.js +2 -2
- package/src/geometries/poly3/measureBoundingSphere.js +2 -2
- package/src/geometries/poly3/measureSignedVolume.js +4 -4
- package/src/geometries/poly3/toPoints.js +2 -2
- package/src/geometries/poly3/toString.js +2 -2
- package/src/geometries/poly3/transform.js +2 -2
- package/src/maths/index.js +1 -1
- package/src/maths/line2/equals.js +2 -2
- package/src/maths/line2/fromValues.js +2 -2
- package/src/maths/line2/intersectPointOfLines.js +1 -1
- package/src/maths/line2/intersectPointOfLines.test.js +1 -1
- package/src/maths/line2/reverse.test.js +1 -1
- package/src/maths/line2/transform.test.js +1 -1
- package/src/maths/line3/create.js +2 -1
- package/src/maths/line3/equals.js +2 -2
- package/src/maths/line3/reverse.test.js +1 -1
- package/src/maths/line3/transform.test.js +1 -1
- package/src/maths/mat4/fromRotation.js +1 -1
- package/src/maths/mat4/fromVectorRotation.js +1 -1
- package/src/maths/mat4/fromVectorRotation.test.js +1 -1
- package/src/maths/mat4/identity.test.js +1 -1
- package/src/maths/mat4/invert.js +18 -18
- package/src/maths/mat4/isIdentity.js +1 -1
- package/src/maths/mat4/isIdentity.test.js +0 -2
- package/src/maths/mat4/isMirroring.js +4 -4
- package/src/maths/mat4/isMirroring.test.js +1 -1
- package/src/maths/mat4/isOnlyTransformScale.js +5 -4
- package/src/maths/mat4/leftMultiplyVec3.js +2 -2
- package/src/maths/mat4/rotate.js +1 -1
- package/src/maths/mat4/toString.js +2 -2
- package/src/maths/mat4/translate.test.js +1 -1
- package/src/maths/plane/flip.test.js +1 -1
- package/src/maths/plane/fromPoints.d.ts +1 -1
- package/src/maths/plane/fromPoints.js +1 -3
- package/src/maths/plane/signedDistanceToPoint.js +1 -1
- package/src/maths/plane/transform.test.js +1 -1
- package/src/maths/utils/aboutEqualNormals.js +2 -2
- package/src/maths/vec2/abs.d.ts +1 -1
- package/src/maths/vec2/add.test.js +1 -1
- package/src/maths/vec2/angleDegrees.d.ts +1 -1
- package/src/maths/vec2/angleRadians.d.ts +1 -1
- package/src/maths/vec2/create.js +1 -1
- package/src/maths/vec2/cross.test.js +1 -1
- package/src/maths/vec2/divide.test.js +1 -1
- package/src/maths/vec2/fromAngleDegrees.js +1 -1
- package/src/maths/vec2/fromScalar.js +1 -1
- package/src/maths/vec2/length.d.ts +1 -1
- package/src/maths/vec2/length.js +1 -1
- package/src/maths/vec2/length.test.js +10 -0
- package/src/maths/vec2/lerp.test.js +1 -1
- package/src/maths/vec2/multiply.test.js +1 -1
- package/src/maths/vec2/negate.test.js +1 -1
- package/src/maths/vec2/normal.js +1 -1
- package/src/maths/vec2/normalize.d.ts +1 -1
- package/src/maths/vec2/normalize.test.js +1 -1
- package/src/maths/vec2/rotate.test.js +1 -1
- package/src/maths/vec2/squaredLength.d.ts +1 -1
- package/src/maths/vec2/squaredLength.js +3 -3
- package/src/maths/vec2/subtract.test.js +1 -1
- package/src/maths/vec2/toString.js +1 -1
- package/src/maths/vec2/transform.test.js +1 -1
- package/src/maths/vec3/abs.d.ts +1 -1
- package/src/maths/vec3/add.test.js +1 -1
- package/src/maths/vec3/angle.js +2 -2
- package/src/maths/vec3/angle.test.js +17 -0
- package/src/maths/vec3/cross.test.js +1 -1
- package/src/maths/vec3/divide.test.js +1 -1
- package/src/maths/vec3/fromScalar.js +1 -1
- package/src/maths/vec3/fromVec2.d.ts +1 -1
- package/src/maths/vec3/fromVec2.js +3 -3
- package/src/maths/vec3/length.d.ts +1 -1
- package/src/maths/vec3/length.js +4 -4
- package/src/maths/vec3/length.test.js +10 -0
- package/src/maths/vec3/lerp.test.js +1 -1
- package/src/maths/vec3/multiply.test.js +1 -1
- package/src/maths/vec3/negate.d.ts +1 -1
- package/src/maths/vec3/negate.test.js +1 -1
- package/src/maths/vec3/normalize.d.ts +1 -1
- package/src/maths/vec3/normalize.test.js +1 -1
- package/src/maths/vec3/rotateX.test.js +1 -1
- package/src/maths/vec3/rotateY.test.js +1 -1
- package/src/maths/vec3/rotateZ.test.js +1 -1
- package/src/maths/vec3/scale.test.js +1 -1
- package/src/maths/vec3/squaredLength.d.ts +1 -1
- package/src/maths/vec3/squaredLength.js +4 -4
- package/src/maths/vec3/subtract.test.js +1 -1
- package/src/maths/vec3/toString.js +1 -1
- package/src/maths/vec3/transform.test.js +1 -1
- package/src/maths/vec4/toString.js +1 -1
- package/src/maths/vec4/transform.test.js +1 -1
- package/src/measurements/measureBoundingBox.js +38 -128
- package/src/measurements/measureBoundingSphere.js +4 -4
- package/src/measurements/measureCenterOfMass.js +1 -1
- package/src/operations/booleans/mayOverlap.js +3 -3
- package/src/operations/booleans/retessellate.js +3 -5
- package/src/operations/booleans/scission.js +1 -1
- package/src/operations/booleans/subtract.js +1 -1
- package/src/operations/booleans/union.test.js +1 -1
- package/src/operations/booleans/unionGeom3Sub.js +1 -1
- package/src/operations/expansions/expand.js +3 -1
- package/src/operations/expansions/expand.test.js +3 -35
- package/src/operations/expansions/expandShell.js +24 -18
- package/src/operations/expansions/offset.js +2 -1
- package/src/operations/expansions/offset.test.js +25 -89
- package/src/operations/expansions/offsetFromPoints.js +11 -6
- package/src/operations/extrusions/extrudeLinear.js +7 -3
- package/src/operations/extrusions/extrudeLinear.test.js +25 -1
- package/src/operations/extrusions/extrudeLinearPath2.js +24 -0
- package/src/operations/extrusions/extrudeRectangular.js +3 -2
- package/src/operations/extrusions/extrudeRectangular.test.js +2 -2
- package/src/operations/extrusions/project.js +1 -1
- package/src/operations/extrusions/slice/isA.js +2 -2
- package/src/operations/extrusions/slice/toPolygons.js +1 -1
- package/src/operations/hulls/hull.test.js +1 -1
- package/src/operations/hulls/hullChain.js +1 -1
- package/src/operations/hulls/hullGeom2.js +1 -1
- package/src/operations/hulls/hullPath2.js +6 -4
- package/src/operations/hulls/hullPath2.test.js +16 -0
- package/src/operations/hulls/hullPoints2.test.js +1 -1
- package/src/operations/hulls/quickhull/QuickHull.js +2 -2
- package/src/operations/modifiers/edges.js +2 -4
- package/src/operations/modifiers/generalize.js +4 -7
- package/src/operations/modifiers/snap.test.js +3 -3
- package/src/operations/transforms/align.d.ts +1 -1
- package/src/operations/transforms/center.js +17 -17
- package/src/operations/transforms/mirror.js +11 -11
- package/src/operations/transforms/rotate.js +12 -12
- package/src/operations/transforms/scale.js +19 -19
- package/src/operations/transforms/transform.js +3 -3
- package/src/operations/transforms/translate.js +14 -14
- package/src/primitives/arc.js +1 -1
- package/src/primitives/cylinderElliptic.test.js +0 -2
- package/src/primitives/ellipse.js +1 -1
- package/src/primitives/ellipsoid.js +1 -1
- package/src/primitives/ellipsoid.test.js +0 -2
- package/src/primitives/geodesicSphere.d.ts +0 -1
- package/src/primitives/geodesicSphere.js +2 -2
- package/src/primitives/polyhedron.js +1 -1
- package/src/primitives/roundedCylinder.js +1 -1
- package/src/primitives/torus.d.ts +0 -1
- package/src/primitives/triangle.js +2 -2
- package/src/text/vectorText.js +2 -2
- package/src/utils/insertSorted.js +1 -0
- package/src/utils/padArrayToLength.js +1 -1
- package/test/helpers/comparePolygons.js +1 -3
- package/test/helpers/nearlyEqual.js +2 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jscad/modeling",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Constructive Solid Geometry (CSG) Library for JSCAD",
|
|
5
5
|
"repository": "https://github.com/jscad/OpenJSCAD.org",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"nyc": "15.1.0",
|
|
61
61
|
"uglifyify": "5.0.2"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "92fb9c75eb070fca5f5ee8c2bab6614b1f54514e"
|
|
64
64
|
}
|
package/src/colors/hslToRgb.js
CHANGED
|
@@ -5,7 +5,7 @@ const hueToColorComponent = require('./hueToColorComponent')
|
|
|
5
5
|
/**
|
|
6
6
|
* Converts HSL color values to RGB color values.
|
|
7
7
|
*
|
|
8
|
-
* @see http://en.wikipedia.org/wiki/HSL_color_space
|
|
8
|
+
* @see http://en.wikipedia.org/wiki/HSL_color_space
|
|
9
9
|
* @param {...Number|Array} values - HSL or HSLA color values
|
|
10
10
|
* @return {Array} RGB or RGBA color values
|
|
11
11
|
* @alias module:modeling/colors.hslToRgb
|
|
@@ -7,14 +7,6 @@
|
|
|
7
7
|
* @property {Array} permutations - A pre-calculation of the bezier algorithm's co-efficients
|
|
8
8
|
* @property {Array} tangentPermutations - A pre-calculation of the bezier algorithm's tangent co-efficients
|
|
9
9
|
*
|
|
10
|
-
* @example
|
|
11
|
-
* const b = bezier.create([0,10]) // a linear progression from 0 to 10
|
|
12
|
-
* const b = bezier.create([0, 0, 10, 10]) // a symmetrical cubic easing curve that starts slowly and ends slowly from 0 to 10
|
|
13
|
-
* 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
|
|
14
|
-
* Usage:
|
|
15
|
-
* let position = bezier.valueAt(t,b) // where 0 < t < 1
|
|
16
|
-
* let tangent = bezier.tangentAt(t,b) // where 0 < t < 1
|
|
17
|
-
*
|
|
18
10
|
*/
|
|
19
11
|
|
|
20
12
|
/**
|
|
@@ -25,6 +17,9 @@
|
|
|
25
17
|
* const b = bezier.create([0,10]) // a linear progression from 0 to 10
|
|
26
18
|
* const b = bezier.create([0, 0, 10, 10]) // a symmetrical cubic easing curve that starts slowly and ends slowly from 0 to 10
|
|
27
19
|
* 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
|
|
20
|
+
* // Usage
|
|
21
|
+
* let position = bezier.valueAt(t,b) // where 0 < t < 1
|
|
22
|
+
* let tangent = bezier.tangentAt(t,b) // where 0 < t < 1
|
|
28
23
|
*
|
|
29
24
|
* @param {Array} points An array with at least 2 elements of either all numbers, or all arrays of numbers that are the same size.
|
|
30
25
|
* @returns {bezier} a new bezier data object
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* See the example called extrudeAlongPath.js
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
|
-
* 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
|
|
7
|
+
* 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
|
|
8
8
|
* let tangent = bezier.tangentAt(t, b)
|
|
9
9
|
*
|
|
10
10
|
* @param {number} t : the position of which to calculate the bezier's tangent value; 0 < t < 1
|
|
11
11
|
* @param {Object} bezier : an array with at least 2 elements of either all numbers, or all arrays of numbers that are the same size.
|
|
12
|
-
* @
|
|
12
|
+
* @return {array | number} the tangent at the requested position.
|
|
13
13
|
* @alias module:modeling/curves/bezier.tangentAt
|
|
14
14
|
*/
|
|
15
15
|
const tangentAt = (t, bezier) => {
|
|
@@ -20,7 +20,7 @@ test('quadratic bezier (3 control points)', (t) => {
|
|
|
20
20
|
t.is(bezier.tangentAt(1, OneDCurve), 20)
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
-
test('quadratic bezier (3 control points, non
|
|
23
|
+
test('quadratic bezier (3 control points, non symmetric)', (t) => {
|
|
24
24
|
const OneDCurve = bezier.create([0, 0, 20])
|
|
25
25
|
t.is(bezier.tangentAt(0, OneDCurve), 0)
|
|
26
26
|
t.is(bezier.tangentAt(0.5, OneDCurve), 20)
|
|
@@ -20,7 +20,7 @@ test('quadratic bezier (3 control points)', (t) => {
|
|
|
20
20
|
t.is(bezier.valueAt(1, OneDCurve), 20)
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
-
test('quadratic bezier (3 control points, non
|
|
23
|
+
test('quadratic bezier (3 control points, non symmetric)', (t) => {
|
|
24
24
|
const OneDCurve = bezier.create([0, 0, 20])
|
|
25
25
|
t.is(bezier.valueAt(0, OneDCurve), 0)
|
|
26
26
|
t.is(bezier.valueAt(0.5, OneDCurve), 5)
|
package/src/curves/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Curves are n-dimensional mathematical constructs that define a path from point 0 to point 1
|
|
2
|
+
* Curves are n-dimensional mathematical constructs that define a path from point 0 to point 1.
|
|
3
3
|
* @module modeling/curves
|
|
4
4
|
* @example
|
|
5
5
|
* const { bezier } = require('@jscad/modeling').curves
|
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
* Represents a 2D geometry consisting of a list of sides.
|
|
3
3
|
* @see {@link geom2} for data structure information.
|
|
4
4
|
* @module modeling/geometries/geom2
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* colorize([0.5,0,1,1], square()) // purple square
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* {
|
|
11
|
+
* "sides": [[[-1,1],[-1,-1]],[[-1,-1],[1,-1]],[[1,-1],[1,1]],[[1,1],[-1,1]]],
|
|
12
|
+
* "transforms": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
|
|
13
|
+
* "color": [0.5,0,1,1]
|
|
14
|
+
* }
|
|
5
15
|
*/
|
|
6
16
|
module.exports = {
|
|
7
17
|
clone: require('./clone'),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {Object} object - the object to
|
|
2
|
+
* Determine if the given object is a 2D geometry.
|
|
3
|
+
* @param {Object} object - the object to interrogate
|
|
4
4
|
* @returns {Boolean} true, if the object matches a geom2 based object
|
|
5
5
|
* @alias module:modeling/geometries/geom2.isA
|
|
6
6
|
*/
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* @returns {TypedArray} compact binary representation
|
|
5
5
|
* @alias module:modeling/geometries/geom2.toCompactBinary
|
|
6
6
|
*/
|
|
7
|
-
const toCompactBinary = (
|
|
8
|
-
const sides =
|
|
9
|
-
const transforms =
|
|
7
|
+
const toCompactBinary = (geometry) => {
|
|
8
|
+
const sides = geometry.sides
|
|
9
|
+
const transforms = geometry.transforms
|
|
10
10
|
let color = [-1, -1, -1, -1]
|
|
11
|
-
if (
|
|
11
|
+
if (geometry.color) color = geometry.color
|
|
12
12
|
|
|
13
13
|
// FIXME why Float32Array?
|
|
14
14
|
const compacted = new Float32Array(1 + 16 + 4 + (sides.length * 4)) // type + transforms + color + sides data
|
|
@@ -7,21 +7,16 @@ const toSides = require('./toSides')
|
|
|
7
7
|
* This allows the edges to be traversed in order.
|
|
8
8
|
*/
|
|
9
9
|
const toEdges = (sides) => {
|
|
10
|
-
const
|
|
10
|
+
const vertices = {}
|
|
11
11
|
const getUniqueVertex = (vertex) => {
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
return vertex
|
|
12
|
+
const key = vertex.toString()
|
|
13
|
+
if (!vertices[key]) {
|
|
14
|
+
vertices[key] = vertex
|
|
16
15
|
}
|
|
17
|
-
return
|
|
16
|
+
return vertices[key]
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
sides.forEach((side) => {
|
|
22
|
-
edges.push([getUniqueVertex(side[0]), getUniqueVertex(side[1])])
|
|
23
|
-
})
|
|
24
|
-
return edges
|
|
19
|
+
return sides.map((side) => side.map(getUniqueVertex))
|
|
25
20
|
}
|
|
26
21
|
|
|
27
22
|
/**
|
|
@@ -5,7 +5,7 @@ const toSides = require('./toSides')
|
|
|
5
5
|
/**
|
|
6
6
|
* Create a string representing the contents of the given geometry.
|
|
7
7
|
* @param {geom2} geometry - the geometry
|
|
8
|
-
* @returns {String} a
|
|
8
|
+
* @returns {String} a representative string
|
|
9
9
|
* @alias module:modeling/geometries/geom2.toString
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
@@ -11,7 +11,7 @@ test('transform: adjusts the transforms of geom2', (t) => {
|
|
|
11
11
|
const rotation = 90 * 0.017453292519943295
|
|
12
12
|
const rotate90 = mat4.fromZRotation(mat4.create(), rotation)
|
|
13
13
|
|
|
14
|
-
// continue with typical user scenario, several
|
|
14
|
+
// continue with typical user scenario, several iterations of transforms and access
|
|
15
15
|
|
|
16
16
|
// expect lazy transform, i.e. only the transforms change
|
|
17
17
|
const expected = {
|
|
@@ -4,7 +4,7 @@ const mat4 = require('../../maths/mat4')
|
|
|
4
4
|
* Represents a 3D geometry consisting of a list of polygons.
|
|
5
5
|
* @typedef {Object} geom3
|
|
6
6
|
* @property {Array} polygons - list of polygons, each polygon containing three or more points
|
|
7
|
-
* @property {mat4} transforms - transforms to apply to the
|
|
7
|
+
* @property {mat4} transforms - transforms to apply to the polygons, see transform()
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -33,7 +33,7 @@ const fromCompactBinary = (data) => {
|
|
|
33
33
|
created.polygons.push(poly3.create(vertices))
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
// transfer known
|
|
36
|
+
// transfer known properties, i.e. color
|
|
37
37
|
if (data[17] >= 0) {
|
|
38
38
|
created.color = [data[17], data[18], data[19], data[20]]
|
|
39
39
|
}
|
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
* Represents a 3D geometry consisting of a list of polygons.
|
|
3
3
|
* @see {@link geom3} for data structure information.
|
|
4
4
|
* @module modeling/geometries/geom3
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* colorize([0,0.5,1,0.6], cube()) // transparent ice cube
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* {
|
|
11
|
+
* "polygons": [
|
|
12
|
+
* {"vertices": [[-1,-1,-1], [-1,-1,1], [-1,1,1], [-1,1,-1]]},
|
|
13
|
+
* {"vertices": [[1,-1,-1], [1,1,-1], [1,1,1], [1,-1,1]]},
|
|
14
|
+
* {"vertices": [[-1,-1,-1], [1,-1,-1], [1,-1,1], [-1,-1,1]]},
|
|
15
|
+
* {"vertices": [[-1,1,-1], [-1,1,1], [1,1,1], [1,1,-1]]},
|
|
16
|
+
* {"vertices": [[-1,-1,-1], [-1,1,-1], [1,1,-1], [1,-1,-1]]},
|
|
17
|
+
* {"vertices": [[-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1]]}
|
|
18
|
+
* ],
|
|
19
|
+
* "transforms": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
|
|
20
|
+
* "color": [0,0.5,1,0.6]
|
|
21
|
+
* }
|
|
5
22
|
*/
|
|
6
23
|
module.exports = {
|
|
7
24
|
clone: require('./clone'),
|
|
@@ -5,8 +5,8 @@ const toPolygons = require('./toPolygons')
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Invert the given geometry, transposing solid and empty space.
|
|
8
|
-
* @
|
|
9
|
-
* @
|
|
8
|
+
* @param {geom3} geometry - the geometry to invert
|
|
9
|
+
* @return {geom3} a new geometry
|
|
10
10
|
* @alias module:modeling/geometries/geom3.invert
|
|
11
11
|
*/
|
|
12
12
|
const invert = (geometry) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {object} object - the object to
|
|
2
|
+
* Determine if the given object is a 3D geometry.
|
|
3
|
+
* @param {object} object - the object to interrogate
|
|
4
4
|
* @returns {Boolean} true if the object matches a geom3
|
|
5
5
|
* @alias module:modeling/geometries/geom3.isA
|
|
6
6
|
*/
|
|
@@ -6,14 +6,14 @@ const poly3 = require('../poly3')
|
|
|
6
6
|
* @return {TypedArray} compact binary representation
|
|
7
7
|
* @alias module:modeling/geometries/geom3.toCompactBinary
|
|
8
8
|
*/
|
|
9
|
-
const toCompactBinary = (
|
|
10
|
-
const polygons =
|
|
11
|
-
const transforms =
|
|
9
|
+
const toCompactBinary = (geometry) => {
|
|
10
|
+
const polygons = geometry.polygons
|
|
11
|
+
const transforms = geometry.transforms
|
|
12
12
|
|
|
13
13
|
const numberOfPolygons = polygons.length
|
|
14
14
|
const numberOfVertices = polygons.reduce((count, polygon) => count + polygon.vertices.length, 0)
|
|
15
15
|
let color = [-1, -1, -1, -1]
|
|
16
|
-
if (
|
|
16
|
+
if (geometry.color) color = geometry.color
|
|
17
17
|
|
|
18
18
|
// FIXME why Float32Array?
|
|
19
19
|
const compacted = new Float32Array(1 + 16 + 4 + 1 + numberOfPolygons + (numberOfVertices * 3))
|
|
@@ -5,6 +5,7 @@ const toPolygons = require('./toPolygons')
|
|
|
5
5
|
/**
|
|
6
6
|
* Return the given geometry as a list of points, after applying transforms.
|
|
7
7
|
* The returned array should not be modified as the points are shared with the geometry.
|
|
8
|
+
* @param {geom3} geometry - the geometry
|
|
8
9
|
* @return {Array} list of points, where each sub-array represents a polygon
|
|
9
10
|
* @alias module:modeling/geometries/geom3.toPoints
|
|
10
11
|
*/
|
|
@@ -5,7 +5,7 @@ const toPolygons = require('./toPolygons')
|
|
|
5
5
|
/**
|
|
6
6
|
* Create a string representing the contents of the given geometry.
|
|
7
7
|
* @param {geom3} geometry - the geometry
|
|
8
|
-
* @returns {String} a
|
|
8
|
+
* @returns {String} a representative string
|
|
9
9
|
* @alias module:modeling/geometries/geom3.toString
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
@@ -11,7 +11,7 @@ test('transform: Adjusts the transforms of a populated geom3', (t) => {
|
|
|
11
11
|
const rotation = 90 * 0.017453292519943295
|
|
12
12
|
const rotate90 = mat4.fromZRotation(mat4.create(), rotation)
|
|
13
13
|
|
|
14
|
-
// continue with typical user scenario, several
|
|
14
|
+
// continue with typical user scenario, several iterations of transforms and access
|
|
15
15
|
|
|
16
16
|
// expect lazy transform, i.e. only the transforms change
|
|
17
17
|
const expected = {
|
package/src/geometries/index.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Geometries are objects that represent the contents of primitives or the results of operations.
|
|
3
|
-
* Note: Geometries are
|
|
3
|
+
* Note: Geometries are considered immutable, so never change the contents directly.
|
|
4
|
+
*
|
|
5
|
+
* @see {@link geom2} - 2D geometry consisting of sides
|
|
6
|
+
* @see {@link geom3} - 3D geometry consisting of polygons
|
|
7
|
+
* @see {@link path2} - 2D geometry consisting of ordered points
|
|
8
|
+
* @see {@link poly2} - 2D polygon consisting of ordered vertices
|
|
9
|
+
* @see {@link poly3} - 3D polygon consisting of ordered vertices
|
|
10
|
+
*
|
|
4
11
|
* @module modeling/geometries
|
|
5
12
|
* @example
|
|
6
13
|
* const { geom2, geom3, path2, poly2, poly3 } = require('@jscad/modeling').geometries
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const toPoints = require('./toPoints')
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Calls a function for each point in the
|
|
4
|
+
* Calls a function for each point in the path.
|
|
5
5
|
* @param {Object} options - options
|
|
6
6
|
* @param {Function} thunk - the function to call
|
|
7
|
-
* @param {path2}
|
|
7
|
+
* @param {path2} path - the path to traverse
|
|
8
8
|
* @alias module:modeling/geometries/path2.eachPoint
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
|
-
* eachPoint({}, accumulate,
|
|
11
|
+
* eachPoint({}, accumulate, path)
|
|
12
12
|
*/
|
|
13
13
|
const eachPoint = (options, thunk, path) => {
|
|
14
14
|
toPoints(path).forEach(thunk)
|
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
* Represents a 2D geometry consisting of a list of ordered points.
|
|
3
3
|
* @see {@link path2} for data structure information.
|
|
4
4
|
* @module modeling/geometries/path2
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* colorize([0,0,0,1], path2.fromPoints({ closed: true }, [[0,0], [4,0], [4,3]]))
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* {
|
|
11
|
+
* "points": [[0,0], [4,0], [4,3]],
|
|
12
|
+
* "isClosed": true,
|
|
13
|
+
* "transforms": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
|
|
14
|
+
* "color": [0,0,0,1]
|
|
15
|
+
* }
|
|
5
16
|
*/
|
|
6
17
|
module.exports = {
|
|
7
18
|
appendArc: require('./appendArc'),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {Object} object - the object to
|
|
2
|
+
* Determine if the given object is a path2 geometry.
|
|
3
|
+
* @param {Object} object - the object to interrogate
|
|
4
4
|
* @returns {Boolean} true if the object matches a path2
|
|
5
5
|
* @alias module:modeling/geometries/path2.isA
|
|
6
6
|
*/
|
|
@@ -3,17 +3,17 @@ const clone = require('./clone')
|
|
|
3
3
|
/**
|
|
4
4
|
* Reverses the path so that the points are in the opposite order.
|
|
5
5
|
* This swaps the left (interior) and right (exterior) edges.
|
|
6
|
-
* @param {path2} geometry - the
|
|
6
|
+
* @param {path2} geometry - the path to reverse
|
|
7
7
|
* @returns {path2} a new path
|
|
8
8
|
* @alias module:modeling/geometries/path2.reverse
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* let newpath = reverse(mypath)
|
|
12
12
|
*/
|
|
13
|
-
const reverse = (
|
|
13
|
+
const reverse = (geometry) => {
|
|
14
14
|
// NOTE: this only updates the order of the points
|
|
15
|
-
const cloned = clone(
|
|
16
|
-
cloned.points =
|
|
15
|
+
const cloned = clone(geometry)
|
|
16
|
+
cloned.points = geometry.points.slice().reverse()
|
|
17
17
|
return cloned
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Produce a compact binary representation from the given path.
|
|
3
|
-
* @param {path2} geometry - the path
|
|
3
|
+
* @param {path2} geometry - the path geometry
|
|
4
4
|
* @returns {TypedArray} compact binary representation
|
|
5
5
|
* @alias module:modeling/geometries/path2.toCompactBinary
|
|
6
6
|
*/
|
|
7
|
-
const toCompactBinary = (
|
|
8
|
-
const points =
|
|
9
|
-
const transforms =
|
|
7
|
+
const toCompactBinary = (geometry) => {
|
|
8
|
+
const points = geometry.points
|
|
9
|
+
const transforms = geometry.transforms
|
|
10
10
|
let color = [-1, -1, -1, -1]
|
|
11
|
-
if (
|
|
11
|
+
if (geometry.color) color = geometry.color
|
|
12
12
|
|
|
13
13
|
// FIXME why Float32Array?
|
|
14
14
|
const compacted = new Float32Array(1 + 16 + 1 + 4 + (points.length * 2)) // type + transforms + isClosed + color + points data
|
|
@@ -32,7 +32,7 @@ const toCompactBinary = (geom) => {
|
|
|
32
32
|
compacted[15] = transforms[14]
|
|
33
33
|
compacted[16] = transforms[15]
|
|
34
34
|
|
|
35
|
-
compacted[17] =
|
|
35
|
+
compacted[17] = geometry.isClosed ? 1 : 0
|
|
36
36
|
|
|
37
37
|
compacted[18] = color[0]
|
|
38
38
|
compacted[19] = color[1]
|
|
@@ -5,7 +5,7 @@ const toPoints = require('./toPoints')
|
|
|
5
5
|
/**
|
|
6
6
|
* Create a string representing the contents of the given path.
|
|
7
7
|
* @param {path2} geometry - the path
|
|
8
|
-
* @returns {String} a
|
|
8
|
+
* @returns {String} a representative string
|
|
9
9
|
* @alias module:modeling/geometries/path2.toString
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
@@ -11,7 +11,7 @@ test('transform: adjusts the transforms of path', (t) => {
|
|
|
11
11
|
const rotation = 90 * 0.017453292519943295
|
|
12
12
|
const rotate90 = mat4.fromZRotation(mat4.create(), rotation)
|
|
13
13
|
|
|
14
|
-
// continue with typical user scenario, several
|
|
14
|
+
// continue with typical user scenario, several iterations of transforms and access
|
|
15
15
|
|
|
16
16
|
// expect lazy transform, i.e. only the transforms change
|
|
17
17
|
const expected = {
|
|
@@ -12,7 +12,7 @@ test('poly2: arePointsInside() should return proper values', (t) => {
|
|
|
12
12
|
t.is(obs, 0)
|
|
13
13
|
|
|
14
14
|
polygon = create([[0, 0], [5, 0], [5, 5], [0, 5]])
|
|
15
|
-
// points
|
|
15
|
+
// points overlapping points
|
|
16
16
|
obs = arePointsInside([[0, 0]], polygon)
|
|
17
17
|
t.is(obs, 0)
|
|
18
18
|
obs = arePointsInside([[5, 0]], polygon)
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
* Represents a 2D polygon consisting of a list of ordered vertices.
|
|
3
3
|
* @see {@link poly2} for data structure information.
|
|
4
4
|
* @module modeling/geometries/poly2
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* poly2.create([[0,0], [4,0], [4,3]])
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* {"vertices": [[0,0], [4,0], [4,3]]}
|
|
5
11
|
*/
|
|
6
12
|
module.exports = {
|
|
7
13
|
arePointsInside: require('./arePointsInside'),
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Represents a convex 3D polygon consisting of a list of vertices.
|
|
2
|
+
* Represents a convex 3D polygon consisting of a list of ordered vertices.
|
|
3
3
|
* @see {@link poly3} for data structure information.
|
|
4
4
|
* @module modeling/geometries/poly3
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* poly3.create([[0,0,0], [4,0,0], [4,3,12]])
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* {"vertices": [[0,0,0], [4,0,0], [4,3,12]]}
|
|
5
11
|
*/
|
|
6
12
|
module.exports = {
|
|
7
13
|
clone: require('./clone'),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {Object} object - the object to
|
|
2
|
+
* Determine if the given object is a polygon.
|
|
3
|
+
* @param {Object} object - the object to interrogate
|
|
4
4
|
* @returns {Boolean} true if the object matches a poly3
|
|
5
5
|
* @alias module:modeling/geometries/poly3.isA
|
|
6
6
|
*/
|
|
@@ -3,11 +3,11 @@ const vec3 = require('../../maths/vec3')
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Check whether the given polygon is convex.
|
|
6
|
-
* @param {poly3} polygon - the polygon to
|
|
6
|
+
* @param {poly3} polygon - the polygon to interrogate
|
|
7
7
|
* @returns {Boolean} true if convex
|
|
8
8
|
* @alias module:modeling/geometries/poly3.isConvex
|
|
9
9
|
*/
|
|
10
|
-
const isConvex = (
|
|
10
|
+
const isConvex = (polygon) => areVerticesConvex(polygon.vertices)
|
|
11
11
|
|
|
12
12
|
const areVerticesConvex = (vertices) => {
|
|
13
13
|
const numvertices = vertices.length
|
|
@@ -7,15 +7,15 @@ const plane = require('./plane')
|
|
|
7
7
|
* @return {Number} area of the polygon
|
|
8
8
|
* @alias module:modeling/geometries/poly3.measureArea
|
|
9
9
|
*/
|
|
10
|
-
const measureArea = (
|
|
11
|
-
const n =
|
|
10
|
+
const measureArea = (polygon) => {
|
|
11
|
+
const n = polygon.vertices.length
|
|
12
12
|
if (n < 3) {
|
|
13
13
|
return 0 // degenerate polygon
|
|
14
14
|
}
|
|
15
|
-
const vertices =
|
|
15
|
+
const vertices = polygon.vertices
|
|
16
16
|
|
|
17
17
|
// calculate a normal vector
|
|
18
|
-
const normal = plane(
|
|
18
|
+
const normal = plane(polygon)
|
|
19
19
|
|
|
20
20
|
// determine direction of projection
|
|
21
21
|
const ax = Math.abs(normal[0])
|
|
@@ -5,8 +5,8 @@ const vec3 = require('../../maths/vec3')
|
|
|
5
5
|
* @returns {Array} an array of two vectors (3D); minimum and maximum coordinates
|
|
6
6
|
* @alias module:modeling/geometries/poly3.measureBoundingBox
|
|
7
7
|
*/
|
|
8
|
-
const measureBoundingBox = (
|
|
9
|
-
const vertices =
|
|
8
|
+
const measureBoundingBox = (polygon) => {
|
|
9
|
+
const vertices = polygon.vertices
|
|
10
10
|
const numvertices = vertices.length
|
|
11
11
|
const min = numvertices === 0 ? vec3.create() : vec3.clone(vertices[0])
|
|
12
12
|
const max = vec3.clone(min)
|
|
@@ -7,8 +7,8 @@ const measureBoundingBox = require('./measureBoundingBox')
|
|
|
7
7
|
* @returns {Array} the computed bounding sphere; center point (3D) and radius
|
|
8
8
|
* @alias module:modeling/geometries/poly3.measureBoundingSphere
|
|
9
9
|
*/
|
|
10
|
-
const measureBoundingSphere = (
|
|
11
|
-
const box = measureBoundingBox(
|
|
10
|
+
const measureBoundingSphere = (polygon) => {
|
|
11
|
+
const box = measureBoundingBox(polygon)
|
|
12
12
|
const center = box[0]
|
|
13
13
|
vec3.add(center, box[0], box[1])
|
|
14
14
|
vec3.scale(center, center, 0.5)
|
|
@@ -2,17 +2,17 @@ const vec3 = require('../../maths/vec3')
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Measure the signed volume of the given polygon, which must be convex.
|
|
5
|
-
* The volume is that formed by the
|
|
5
|
+
* The volume is that formed by the tetrahedron connected to the axis [0,0,0],
|
|
6
6
|
* and will be positive or negative based on the rotation of the vertices.
|
|
7
7
|
* @see http://chenlab.ece.cornell.edu/Publication/Cha/icip01_Cha.pdf
|
|
8
8
|
* @param {poly3} polygon - the polygon to measure
|
|
9
9
|
* @return {Number} volume of the polygon
|
|
10
10
|
* @alias module:modeling/geometries/poly3.measureSignedVolume
|
|
11
11
|
*/
|
|
12
|
-
const measureSignedVolume = (
|
|
12
|
+
const measureSignedVolume = (polygon) => {
|
|
13
13
|
let signedVolume = 0
|
|
14
|
-
const vertices =
|
|
15
|
-
// calculate based on
|
|
14
|
+
const vertices = polygon.vertices
|
|
15
|
+
// calculate based on triangular polygons
|
|
16
16
|
const cross = vec3.create()
|
|
17
17
|
for (let i = 0; i < vertices.length - 2; i++) {
|
|
18
18
|
vec3.cross(cross, vertices[i + 1], vertices[i + 2])
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Return the given
|
|
2
|
+
* Return the given polygon as a list of points.
|
|
3
3
|
* NOTE: The returned array should not be modified as the points are shared with the geometry.
|
|
4
4
|
* @param {poly3} polygon - the polygon
|
|
5
5
|
* @return {Array} list of points (3D)
|
|
6
6
|
* @alias module:modeling/geometries/poly3.toPoints
|
|
7
7
|
*/
|
|
8
|
-
const toPoints = (
|
|
8
|
+
const toPoints = (polygon) => polygon.vertices
|
|
9
9
|
|
|
10
10
|
module.exports = toPoints
|
|
@@ -5,9 +5,9 @@ const vec3 = require('../../maths/vec3/')
|
|
|
5
5
|
* @return {String} the string representation
|
|
6
6
|
* @alias module:modeling/geometries/poly3.toString
|
|
7
7
|
*/
|
|
8
|
-
const toString = (
|
|
8
|
+
const toString = (polygon) => {
|
|
9
9
|
let result = 'poly3: vertices: ['
|
|
10
|
-
|
|
10
|
+
polygon.vertices.forEach((vertex) => {
|
|
11
11
|
result += `${vec3.toString(vertex)}, `
|
|
12
12
|
})
|
|
13
13
|
result += ']'
|
|
@@ -10,8 +10,8 @@ const create = require('./create')
|
|
|
10
10
|
* @returns {poly3} a new polygon
|
|
11
11
|
* @alias module:modeling/geometries/poly3.transform
|
|
12
12
|
*/
|
|
13
|
-
const transform = (matrix,
|
|
14
|
-
const vertices =
|
|
13
|
+
const transform = (matrix, polygon) => {
|
|
14
|
+
const vertices = polygon.vertices.map((vertex) => vec3.transform(vec3.create(), vertex, matrix))
|
|
15
15
|
if (mat4.isMirroring(matrix)) {
|
|
16
16
|
// reverse the order to preserve the orientation
|
|
17
17
|
vertices.reverse()
|
package/src/maths/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Maths are computational units for fundamental Euclidean geometry. All maths operate upon array data structures.
|
|
3
|
-
* Note: Maths data
|
|
3
|
+
* Note: Maths data structures are considered immutable, so never change the contents directly.
|
|
4
4
|
* @see Most computations are based upon the glMatrix library (glmatrix.net)
|
|
5
5
|
* @module modeling/maths
|
|
6
6
|
* @example
|