@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 +11 -0
- package/dist/jscad-modeling.min.js +2 -2
- package/package.json +2 -2
- package/src/curves/bezier/create.js +3 -8
- package/src/curves/index.js +1 -1
- package/src/geometries/geom3/create.js +1 -1
- package/src/maths/line3/create.js +2 -1
- package/src/maths/mat4/isOnlyTransformScale.js +5 -4
- package/src/measurements/measureBoundingBox.js +38 -128
- package/src/operations/expansions/expand.js +2 -0
- package/src/operations/expansions/offset.js +1 -0
- package/src/operations/extrusions/extrudeRectangular.js +2 -1
- package/src/primitives/ellipse.js +1 -1
- package/src/primitives/triangle.js +1 -1
- package/src/utils/insertSorted.js +1 -0
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"),
|
|
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/
|
|
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.
|
|
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": "
|
|
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
|
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
|
|
@@ -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
|
/**
|
|
@@ -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
|
-
*
|
|
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
|
|
4
|
-
*
|
|
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.
|
|
16
|
-
* @return {Array[]} the min and max bounds for the geometry
|
|
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
|
|
19
|
-
let boundingBox = cache.get(
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
|
49
|
+
const measureBoundingBoxOfGeom2 = (geometry) => {
|
|
45
50
|
let boundingBox = cache.get(geometry)
|
|
46
51
|
if (boundingBox) return boundingBox
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
const points = geom2.toPoints(geometry)
|
|
54
|
+
|
|
55
|
+
let minpoint
|
|
56
|
+
if (points.length === 0) {
|
|
57
|
+
minpoint = vec2.create()
|
|
51
58
|
} else {
|
|
52
|
-
|
|
53
|
-
boundingBox = measureBoundingBoxOfPath2Points(path2.toPoints(geometry))
|
|
59
|
+
minpoint = vec2.clone(points[0])
|
|
54
60
|
}
|
|
61
|
+
let maxpoint = vec2.clone(minpoint)
|
|
55
62
|
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
68
|
+
minpoint = [minpoint[0], minpoint[1], 0]
|
|
69
|
+
maxpoint = [maxpoint[0], maxpoint[1], 0]
|
|
71
70
|
|
|
72
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
|
82
|
+
const measureBoundingBoxOfGeom3 = (geometry) => {
|
|
109
83
|
let boundingBox = cache.get(geometry)
|
|
110
84
|
if (boundingBox) return boundingBox
|
|
111
85
|
|
|
112
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
102
|
+
minpoint = [minpoint[0], minpoint[1], minpoint[2]]
|
|
103
|
+
maxpoint = [maxpoint[0], maxpoint[1], maxpoint[2]]
|
|
147
104
|
|
|
148
|
-
|
|
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({
|
|
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
|
|
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: [
|
|
128
|
+
* let myshape = triangle({type: 'AAS', values: [degToRad(62), degToRad(35), 7]})
|
|
129
129
|
*/
|
|
130
130
|
const triangle = (options) => {
|
|
131
131
|
const defaults = {
|