@jscad/modeling 2.7.0 → 2.7.1

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 CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.7.1](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/modeling@2.7.0...@jscad/modeling@2.7.1) (2021-12-26)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **modeling:** revert measureBoundingBox to only cache per geometry ([#967](https://github.com/jscad/OpenJSCAD.org/issues/967)) ([b18c02c](https://github.com/jscad/OpenJSCAD.org/commit/b18c02c333b225981a9093caf0593795bc0861ad))
12
+
13
+
14
+
15
+
16
+
6
17
  # [2.7.0](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/modeling@2.6.1...@jscad/modeling@2.7.0) (2021-12-11)
7
18
 
8
19
 
@@ -746,9 +746,9 @@ const flatten=require("../utils/flatten"),measureVolume=require("./measureVolume
746
746
  const flatten=require("../utils/flatten"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),cache=new WeakMap,measureAreaOfPath2=()=>0,measureAreaOfGeom2=e=>{let r=cache.get(e);if(r)return r;return r=geom2.toSides(e).reduce((e,r)=>e+(r[0][0]*r[1][1]-r[0][1]*r[1][0]),0),r*=.5,cache.set(e,r),r},measureAreaOfGeom3=e=>{let r=cache.get(e);if(r)return r;return r=geom3.toPolygons(e).reduce((e,r)=>e+poly3.measureArea(r),0),cache.set(e,r),r},measureArea=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const r=e.map(e=>path2.isA(e)?0:geom2.isA(e)?measureAreaOfGeom2(e):geom3.isA(e)?measureAreaOfGeom3(e):0);return 1===r.length?r[0]:r};module.exports=measureArea;
747
747
 
748
748
  },{"../geometries/geom2":22,"../geometries/geom3":36,"../geometries/path2":57,"../geometries/poly3":73,"../utils/flatten":379}],250:[function(require,module,exports){
749
- const flatten=require("../utils/flatten"),vec2=require("../maths/vec2"),vec3=require("../maths/vec3"),mat4=require("../maths/mat4"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),cache=new WeakMap,measureBoundingBoxOfPath2Points=e=>{let o,n=cache.get(e);if(n)return n;o=0===e.length?vec2.create():vec2.clone(e[0]);const t=vec2.clone(o);return e.forEach(e=>{vec2.min(o,o,e),vec2.max(t,t,e)}),n=[[o[0],o[1],0],[t[0],t[1],0]],cache.set(e,n),n},measureBoundingBoxOfPath2=e=>{let o=cache.get(e);return o||(o=mat4.isOnlyTransformScale(e.transforms)?transformBoundingBox(measureBoundingBoxOfPath2Points(e.points),e.transforms):measureBoundingBoxOfPath2Points(path2.toPoints(e)),cache.set(e,o),o)},measureBoundingBoxOfGeom2Points=({points:e,sides:o})=>{const n=e||o;let t,r,s=cache.get(n);return s||(e?(t=0===e.length?vec2.create():vec2.clone(e[0]),r=vec2.clone(t),e.forEach(e=>{vec2.min(t,t,e),vec2.max(r,r,e)})):(t=0===o.length?vec2.create():vec2.clone(o[0][0]),r=vec2.clone(t),o.forEach(e=>{vec2.min(t,t,e[0]),vec2.max(r,r,e[0])})),s=[[t[0],t[1],0],[r[0],r[1],0]],cache.set(n,s),s)},measureBoundingBoxOfGeom2=e=>{let o=cache.get(e);return o||(o=mat4.isOnlyTransformScale(e.transforms)?transformBoundingBox(measureBoundingBoxOfGeom2Points(e),e.transforms):measureBoundingBoxOfGeom2Points({points:geom2.toPoints(e)}),cache.set(e,o),o)},measureBoundingBoxOfGeom3Polygons=e=>{let o=cache.get(e);if(o)return o;const n=vec3.create();if(e.length>0){const o=poly3.toPoints(e[0]);vec3.copy(n,o[0])}const t=vec3.clone(n);return e.forEach(e=>{poly3.toPoints(e).forEach(e=>{vec3.min(n,n,e),vec3.max(t,t,e)})}),o=[[n[0],n[1],n[2]],[t[0],t[1],t[2]]],cache.set(e,o),o},measureBoundingBoxOfGeom3=e=>{let o=cache.get(e);return o||(o=mat4.isOnlyTransformScale(e.transforms)?transformBoundingBox(measureBoundingBoxOfGeom3Polygons(e.polygons),e.transforms):measureBoundingBoxOfGeom3Polygons(geom3.toPolygons(e)),cache.set(e,o),o)},fixBound=(e,o,n)=>{if(o[e]>n[e]){const t=o[e];o[e]=n[e],n[e]=t}},transformBoundingBox=(e,o)=>(mat4.isIdentity(o)||(vec3.transform(e[0],e[0],o),vec3.transform(e[1],e[1],o),fixBound(0,...e),fixBound(1,...e),fixBound(2,...e)),e),measureBoundingBox=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const o=e.map(e=>path2.isA(e)?measureBoundingBoxOfPath2(e):geom2.isA(e)?measureBoundingBoxOfGeom2(e):geom3.isA(e)?measureBoundingBoxOfGeom3(e):[[0,0,0],[0,0,0]]);return 1===o.length?o[0]:o};module.exports=measureBoundingBox;
749
+ const flatten=require("../utils/flatten"),vec2=require("../maths/vec2"),vec3=require("../maths/vec3"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),cache=new WeakMap,measureBoundingBoxOfPath2=e=>{let o=cache.get(e);if(o)return o;const t=path2.toPoints(e);let n;n=0===t.length?vec2.create():vec2.clone(t[0]);let r=vec2.clone(n);return t.forEach(e=>{vec2.min(n,n,e),vec2.max(r,r,e)}),n=[n[0],n[1],0],r=[r[0],r[1],0],o=[n,r],cache.set(e,o),o},measureBoundingBoxOfGeom2=e=>{let o=cache.get(e);if(o)return o;const t=geom2.toPoints(e);let n;n=0===t.length?vec2.create():vec2.clone(t[0]);let r=vec2.clone(n);return t.forEach(e=>{vec2.min(n,n,e),vec2.max(r,r,e)}),n=[n[0],n[1],0],r=[r[0],r[1],0],o=[n,r],cache.set(e,o),o},measureBoundingBoxOfGeom3=e=>{let o=cache.get(e);if(o)return o;const t=geom3.toPolygons(e);let n=vec3.create();if(t.length>0){const e=poly3.toPoints(t[0]);vec3.copy(n,e[0])}let r=vec3.clone(n);return t.forEach(e=>{poly3.toPoints(e).forEach(e=>{vec3.min(n,n,e),vec3.max(r,r,e)})}),n=[n[0],n[1],n[2]],r=[r[0],r[1],r[2]],o=[n,r],cache.set(e,o),o},measureBoundingBox=(...e)=>{if(0===(e=flatten(e)).length)throw new Error("wrong number of arguments");const o=e.map(e=>path2.isA(e)?measureBoundingBoxOfPath2(e):geom2.isA(e)?measureBoundingBoxOfGeom2(e):geom3.isA(e)?measureBoundingBoxOfGeom3(e):[[0,0,0],[0,0,0]]);return 1===o.length?o[0]:o};module.exports=measureBoundingBox;
750
750
 
751
- },{"../geometries/geom2":22,"../geometries/geom3":36,"../geometries/path2":57,"../geometries/poly3":73,"../maths/mat4":137,"../maths/vec2":183,"../maths/vec3":214,"../utils/flatten":379}],251:[function(require,module,exports){
751
+ },{"../geometries/geom2":22,"../geometries/geom3":36,"../geometries/path2":57,"../geometries/poly3":73,"../maths/vec2":183,"../maths/vec3":214,"../utils/flatten":379}],251:[function(require,module,exports){
752
752
  const flatten=require("../utils/flatten"),vec2=require("../maths/vec2"),vec3=require("../maths/vec3"),geom2=require("../geometries/geom2"),geom3=require("../geometries/geom3"),path2=require("../geometries/path2"),poly3=require("../geometries/poly3"),cacheOfBoundingSpheres=new WeakMap,measureBoundingSphereOfPath2=e=>{let t=cacheOfBoundingSpheres.get(e);if(void 0!==t)return t;const r=vec3.create();let o=0;const c=path2.toPoints(e);if(c.length>0){let e=0;const t=vec3.create();c.forEach(o=>{vec3.add(r,r,vec3.fromVec2(t,o,0)),e++}),vec3.scale(r,r,1/e),c.forEach(e=>{o=Math.max(o,vec2.squaredDistance(r,e))}),o=Math.sqrt(o)}return t=[r,o],cacheOfBoundingSpheres.set(e,t),t},measureBoundingSphereOfGeom2=e=>{let t=cacheOfBoundingSpheres.get(e);if(void 0!==t)return t;const r=vec3.create();let o=0;const c=geom2.toSides(e);if(c.length>0){let e=0;const t=vec3.create();c.forEach(o=>{vec3.add(r,r,vec3.fromVec2(t,o[0],0)),e++}),vec3.scale(r,r,1/e),c.forEach(e=>{o=Math.max(o,vec2.squaredDistance(r,e[0]))}),o=Math.sqrt(o)}return t=[r,o],cacheOfBoundingSpheres.set(e,t),t},measureBoundingSphereOfGeom3=e=>{let t=cacheOfBoundingSpheres.get(e);if(void 0!==t)return t;const r=vec3.create();let o=0;const c=geom3.toPolygons(e);if(c.length>0){let e=0;c.forEach(t=>{poly3.toPoints(t).forEach(t=>{vec3.add(r,r,t),e++})}),vec3.scale(r,r,1/e),c.forEach(e=>{poly3.toPoints(e).forEach(e=>{o=Math.max(o,vec3.squaredDistance(r,e))})}),o=Math.sqrt(o)}return t=[r,o],cacheOfBoundingSpheres.set(e,t),t},measureBoundingSphere=(...e)=>{const t=(e=flatten(e)).map(e=>path2.isA(e)?measureBoundingSphereOfPath2(e):geom2.isA(e)?measureBoundingSphereOfGeom2(e):geom3.isA(e)?measureBoundingSphereOfGeom3(e):[[0,0,0],0]);return 1===t.length?t[0]:t};module.exports=measureBoundingSphere;
753
753
 
754
754
  },{"../geometries/geom2":22,"../geometries/geom3":36,"../geometries/path2":57,"../geometries/poly3":73,"../maths/vec2":183,"../maths/vec3":214,"../utils/flatten":379}],252:[function(require,module,exports){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jscad/modeling",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
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": "fbc9b90f0ae02bea4e6e7b974c65e751c3858269"
63
+ "gitHead": "c8ac21281a7acf5a5575b940c18353c598ffa1a4"
64
64
  }
@@ -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
@@ -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
@@ -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 sides, see transform()
7
+ * @property {mat4} transforms - transforms to apply to the polygons, see transform()
8
8
  */
9
9
 
10
10
  /**
@@ -3,7 +3,8 @@ const vec3 = require('../vec3')
3
3
  /**
4
4
  * Represents a unbounded line in 3D space, positioned at a point of origin.
5
5
  * A line is parametrized by a point of origin and a directional vector.
6
- * The array contents are two 3D vectors; origin and directional vector.
6
+ *
7
+ * The array contents are two 3D vectors; origin [0,0,0] and directional vector [0,0,1].
7
8
  * @see https://en.wikipedia.org/wiki/Hesse_normal_form
8
9
  * @typedef {Array} line3
9
10
  */
@@ -1,10 +1,11 @@
1
1
 
2
2
  /**
3
- * Determine whether the given matrix is translate+scale.
4
- * this code returns true for 180 rotation as it can be interpreted as scale (-1,-1)
5
- *
6
- * this method is primarily useful for measureBoundingBox
3
+ * Determine whether the given matrix is only translate and/or scale.
4
+ * This code returns true for PI rotation as it can be interpreted as scale.
7
5
  *
6
+ * @param {mat4} matrix - the matrix
7
+ * @returns {Boolean} true if matrix is for translate and/or scale
8
+ * @alias module:modeling/maths/mat4.isOnlyTransformScale
8
9
  */
9
10
  const isOnlyTransformScale = (matrix) => (
10
11
 
@@ -2,7 +2,6 @@ const flatten = require('../utils/flatten')
2
2
 
3
3
  const vec2 = require('../maths/vec2')
4
4
  const vec3 = require('../maths/vec3')
5
- const mat4 = require('../maths/mat4')
6
5
 
7
6
  const geom2 = require('../geometries/geom2')
8
7
  const geom3 = require('../geometries/geom3')
@@ -12,129 +11,86 @@ const poly3 = require('../geometries/poly3')
12
11
  const cache = new WeakMap()
13
12
 
14
13
  /*
15
- * Measure the min and max bounds of the given (path2) geometry.points.
16
- * @return {Array[]} the min and max bounds for the geometry.points
14
+ * Measure the min and max bounds of the given (path2) geometry.
15
+ * @return {Array[]} the min and max bounds for the geometry
17
16
  */
18
- const measureBoundingBoxOfPath2Points = (points) => {
19
- let boundingBox = cache.get(points)
17
+ const measureBoundingBoxOfPath2 = (geometry) => {
18
+ let boundingBox = cache.get(geometry)
20
19
  if (boundingBox) return boundingBox
21
20
 
21
+ const points = path2.toPoints(geometry)
22
+
22
23
  let minpoint
23
24
  if (points.length === 0) {
24
25
  minpoint = vec2.create()
25
26
  } else {
26
27
  minpoint = vec2.clone(points[0])
27
28
  }
28
- const maxpoint = vec2.clone(minpoint)
29
+ let maxpoint = vec2.clone(minpoint)
29
30
 
30
31
  points.forEach((point) => {
31
32
  vec2.min(minpoint, minpoint, point)
32
33
  vec2.max(maxpoint, maxpoint, point)
33
34
  })
34
- boundingBox = [[minpoint[0], minpoint[1], 0], [maxpoint[0], maxpoint[1], 0]]
35
+ minpoint = [minpoint[0], minpoint[1], 0]
36
+ maxpoint = [maxpoint[0], maxpoint[1], 0]
37
+
38
+ boundingBox = [minpoint, maxpoint]
39
+
40
+ cache.set(geometry, boundingBox)
35
41
 
36
- cache.set(points, boundingBox)
37
42
  return boundingBox
38
43
  }
39
44
 
40
45
  /*
41
- * Measure the min and max bounds of the given (path2) geometry.
46
+ * Measure the min and max bounds of the given (geom2) geometry.
42
47
  * @return {Array[]} the min and max bounds for the geometry
43
48
  */
44
- const measureBoundingBoxOfPath2 = (geometry) => {
49
+ const measureBoundingBoxOfGeom2 = (geometry) => {
45
50
  let boundingBox = cache.get(geometry)
46
51
  if (boundingBox) return boundingBox
47
52
 
48
- if (mat4.isOnlyTransformScale(geometry.transforms)) {
49
- // get boundingBox of original points and transform it
50
- boundingBox = transformBoundingBox(measureBoundingBoxOfPath2Points(geometry.points), geometry.transforms)
53
+ const points = geom2.toPoints(geometry)
54
+
55
+ let minpoint
56
+ if (points.length === 0) {
57
+ minpoint = vec2.create()
51
58
  } else {
52
- // transform the points and then caclulate the boundingBox
53
- boundingBox = measureBoundingBoxOfPath2Points(path2.toPoints(geometry))
59
+ minpoint = vec2.clone(points[0])
54
60
  }
61
+ let maxpoint = vec2.clone(minpoint)
55
62
 
56
- cache.set(geometry, boundingBox)
57
- return boundingBox
58
- }
59
-
60
- /*
61
- * Measure the min and max bounds of the given (geom2) geometry.points/sides.
62
- * @return {Array[]} the min and max bounds for the geometr.points/sidesy
63
- */
64
- const measureBoundingBoxOfGeom2Points = ({ points, sides }) => {
65
- const cacheKey = points || sides
66
-
67
- let boundingBox = cache.get(cacheKey)
68
- if (boundingBox) return boundingBox
63
+ points.forEach((point) => {
64
+ vec2.min(minpoint, minpoint, point)
65
+ vec2.max(maxpoint, maxpoint, point)
66
+ })
69
67
 
70
- let minpoint, maxpoint
68
+ minpoint = [minpoint[0], minpoint[1], 0]
69
+ maxpoint = [maxpoint[0], maxpoint[1], 0]
71
70
 
72
- if (points) {
73
- if (points.length === 0) {
74
- minpoint = vec2.create()
75
- } else {
76
- minpoint = vec2.clone(points[0])
77
- }
78
- maxpoint = vec2.clone(minpoint)
71
+ boundingBox = [minpoint, maxpoint]
79
72
 
80
- points.forEach((point) => {
81
- vec2.min(minpoint, minpoint, point)
82
- vec2.max(maxpoint, maxpoint, point)
83
- })
84
- } else { // sides
85
- // to avoid calling costly toPoints, we take advantage of the knowlege how the toPoints works
86
- if (sides.length === 0) {
87
- minpoint = vec2.create()
88
- } else {
89
- minpoint = vec2.clone(sides[0][0])
90
- }
91
- maxpoint = vec2.clone(minpoint)
92
-
93
- sides.forEach((side) => {
94
- vec2.min(minpoint, minpoint, side[0])
95
- vec2.max(maxpoint, maxpoint, side[0])
96
- })
97
- }
98
- boundingBox = [[minpoint[0], minpoint[1], 0], [maxpoint[0], maxpoint[1], 0]]
73
+ cache.set(geometry, boundingBox)
99
74
 
100
- cache.set(cacheKey, boundingBox)
101
75
  return boundingBox
102
76
  }
103
77
 
104
78
  /*
105
- * Measure the min and max bounds of the given (geom2) geometry.
79
+ * Measure the min and max bounds of the given (geom3) geometry.
106
80
  * @return {Array[]} the min and max bounds for the geometry
107
81
  */
108
- const measureBoundingBoxOfGeom2 = (geometry) => {
82
+ const measureBoundingBoxOfGeom3 = (geometry) => {
109
83
  let boundingBox = cache.get(geometry)
110
84
  if (boundingBox) return boundingBox
111
85
 
112
- if (mat4.isOnlyTransformScale(geometry.transforms)) {
113
- // get boundingBox of original points and transform it
114
- boundingBox = transformBoundingBox(measureBoundingBoxOfGeom2Points(geometry), geometry.transforms)
115
- } else {
116
- // transform the points and then caclulate the boundingBox
117
- boundingBox = measureBoundingBoxOfGeom2Points({ points: geom2.toPoints(geometry) })
118
- }
119
-
120
- cache.set(geometry, boundingBox)
121
- return boundingBox
122
- }
123
-
124
- /*
125
- * Measure the min and max bounds of the given (geom3) geometry.polygons.
126
- * @return {Array[]} the min and max bounds for the geometry.polygons
127
- */
128
- const measureBoundingBoxOfGeom3Polygons = (polygons) => {
129
- let boundingBox = cache.get(polygons)
130
- if (boundingBox) return boundingBox
86
+ const polygons = geom3.toPolygons(geometry)
131
87
 
132
- const minpoint = vec3.create()
88
+ let minpoint = vec3.create()
133
89
  if (polygons.length > 0) {
134
90
  const points = poly3.toPoints(polygons[0])
135
91
  vec3.copy(minpoint, points[0])
136
92
  }
137
- const maxpoint = vec3.clone(minpoint)
93
+ let maxpoint = vec3.clone(minpoint)
138
94
 
139
95
  polygons.forEach((polygon) => {
140
96
  poly3.toPoints(polygon).forEach((point) => {
@@ -143,59 +99,13 @@ const measureBoundingBoxOfGeom3Polygons = (polygons) => {
143
99
  })
144
100
  })
145
101
 
146
- boundingBox = [[minpoint[0], minpoint[1], minpoint[2]], [maxpoint[0], maxpoint[1], maxpoint[2]]]
102
+ minpoint = [minpoint[0], minpoint[1], minpoint[2]]
103
+ maxpoint = [maxpoint[0], maxpoint[1], maxpoint[2]]
147
104
 
148
- cache.set(polygons, boundingBox)
149
- return boundingBox
150
- }
151
-
152
- /*
153
- * Measure the min and max bounds of the given (geom3) geometry.
154
- * @return {Array[]} the min and max bounds for the geometry
155
- */
156
- const measureBoundingBoxOfGeom3 = (geometry) => {
157
- let boundingBox = cache.get(geometry)
158
- if (boundingBox) return boundingBox
159
-
160
- if (mat4.isOnlyTransformScale(geometry.transforms)) {
161
- // get boundingBox of original points and transform it
162
- boundingBox = transformBoundingBox(measureBoundingBoxOfGeom3Polygons(geometry.polygons), geometry.transforms)
163
- } else {
164
- // transform the points and then caclulate the boundingBox
165
- boundingBox = measureBoundingBoxOfGeom3Polygons(geom3.toPolygons(geometry))
166
- }
105
+ boundingBox = [minpoint, maxpoint]
167
106
 
168
107
  cache.set(geometry, boundingBox)
169
- return boundingBox
170
- }
171
108
 
172
- /*
173
- * swap values if specific axis value in the second vector has lower value than the axis value in first vector
174
- */
175
- const fixBound = (i, v1, v2) => {
176
- if (v1[i] > v2[i]) {
177
- const tmp = v1[i]
178
- v1[i] = v2[i]
179
- v2[i] = tmp
180
- }
181
- }
182
-
183
- /*
184
- * Transform the given bounding box
185
- */
186
- const transformBoundingBox = (boundingBox, transforms) => {
187
- if (!mat4.isIdentity(transforms)) {
188
- vec3.transform(boundingBox[0], boundingBox[0], transforms)
189
- vec3.transform(boundingBox[1], boundingBox[1], transforms)
190
-
191
- // we now have a new 2 vectors: [v1,v2] => [ [x1,y1,z1], [x2,y2,z2] ]
192
- // transform can move bounding box corner in such way that it is no longer true that
193
- // - v1 = [min(x1,x2),min(y1,y2),min(z1,z2)]
194
- // - v2 = [max(x1,x2),max(y1,y2),max(z1,z2)]
195
- fixBound(0, ...boundingBox) // swap x, if higher value is in first vector
196
- fixBound(1, ...boundingBox) // swap y, if higher value is in first vector
197
- fixBound(2, ...boundingBox) // swap z, if higher value is in first vector
198
- }
199
109
  return boundingBox
200
110
  }
201
111
 
@@ -10,6 +10,8 @@ const expandPath2 = require('./expandPath2')
10
10
 
11
11
  /**
12
12
  * Expand the given geometry using the given options.
13
+ * Both interal and external space is expanded for 2D and 3D shapes.
14
+ *
13
15
  * Note: Contract is expand using a negative delta.
14
16
  * @param {Object} options - options for expand
15
17
  * @param {Number} [options.delta=1] - delta (+/-) of expansion
@@ -8,6 +8,7 @@ const offsetPath2 = require('./offsetPath2')
8
8
 
9
9
  /**
10
10
  * Create offset geometry from the given geometry using the given options.
11
+ * Offsets from internal and external space are created.
11
12
  * @param {Object} options - options for offset
12
13
  * @param {Float} [options.delta=1] - delta of offset (+ to exterior, - from interior)
13
14
  * @param {String} [options.corners='edge'] - type of corner to create after offseting; edge, chamfer, round
@@ -17,7 +17,8 @@ const extrudeRectangularGeom2 = require('./extrudeRectangularGeom2')
17
17
  * @alias module:modeling/extrusions.extrudeRectangular
18
18
  *
19
19
  * @example
20
- * let mywalls = extrudeRectangular({offset: [0,0,10]}, square())
20
+ * let mywalls = extrudeRectangular({size: 1, height: 3}, square({size: 20}))
21
+ * let mywalls = extrudeRectangular({size: 1, height: 300, twistAngle: Math.PI}, square({size: 20}))
21
22
  */
22
23
  const extrudeRectangular = (options, ...objects) => {
23
24
  const defaults = {
@@ -7,7 +7,7 @@ const geom2 = require('../geometries/geom2')
7
7
  const { isGTE, isNumberArray } = require('./commonChecks')
8
8
 
9
9
  /**
10
- * Construct an axis-aligned ellispe in two dimensional space.
10
+ * Construct an axis-aligned ellipse in two dimensional space.
11
11
  * @see https://en.wikipedia.org/wiki/Ellipse
12
12
  * @param {Object} [options] - options for construction
13
13
  * @param {Array} [options.center=[0,0]] - center of ellipse
@@ -125,7 +125,7 @@ const createTriangle = (A, B, C, a, b, c) => {
125
125
  * @alias module:modeling/primitives.triangle
126
126
  *
127
127
  * @example
128
- * let myshape = triangle({type: 'AAS', values: [values: [degToRad(62), degToRad(35), 7]})
128
+ * let myshape = triangle({type: 'AAS', values: [degToRad(62), degToRad(35), 7]})
129
129
  */
130
130
  const triangle = (options) => {
131
131
  const defaults = {
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * Insert the given element into the give array using the compareFunction.
2
3
  * @alias module:modeling/utils.insertSorted
3
4
  */
4
5
  const insertSorted = (array, element, comparefunc) => {