@jscad/modeling 3.0.1-alpha.0 → 3.0.3-alpha.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 +22 -0
- package/dist/jscad-modeling.es.js +2 -2
- package/dist/jscad-modeling.min.js +2 -2
- package/package.json +2 -2
- package/src/colors/colorize.test.js +1 -1
- package/src/geometries/geom2/index.d.ts +0 -2
- package/src/geometries/geom2/index.js +0 -2
- package/src/geometries/geom3/applyTransforms.test.js +2 -2
- package/src/geometries/geom3/clone.test.js +2 -2
- package/src/geometries/geom3/create.js +1 -9
- package/src/geometries/geom3/{fromPoints.d.ts → fromVertices.d.ts} +1 -1
- package/src/geometries/geom3/{fromPoints.js → fromVertices.js} +3 -2
- package/src/geometries/geom3/{fromPoints.test.js → fromVertices.test.js} +6 -6
- package/src/geometries/geom3/{fromPointsConvex.d.ts → fromVerticesConvex.d.ts} +1 -1
- package/src/geometries/geom3/fromVerticesConvex.js +25 -0
- package/src/geometries/geom3/{fromPointsConvex.test.js → fromVerticesConvex.test.js} +3 -3
- package/src/geometries/geom3/index.d.ts +3 -5
- package/src/geometries/geom3/index.js +4 -6
- package/src/geometries/geom3/invert.test.js +2 -2
- package/src/geometries/geom3/isA.test.js +2 -2
- package/src/geometries/geom3/toString.test.js +2 -2
- package/src/geometries/geom3/{toPoints.d.ts → toVertices.d.ts} +1 -1
- package/src/geometries/geom3/{toPoints.js → toVertices.js} +3 -2
- package/src/geometries/geom3/{toPoints.test.js → toVertices.test.js} +4 -4
- package/src/geometries/geom3/transform.test.js +2 -2
- package/src/geometries/geom3/validate.test.js +4 -4
- package/src/geometries/index.d.ts +1 -0
- package/src/geometries/index.js +1 -0
- package/src/geometries/path2/appendBezier.js +1 -1
- package/src/geometries/path2/create.js +1 -10
- package/src/geometries/path2/index.d.ts +0 -2
- package/src/geometries/path2/index.js +0 -2
- package/src/geometries/path3/applyTransforms.js +22 -0
- package/src/geometries/path3/applyTransforms.test.js +28 -0
- package/src/geometries/path3/close.d.ts +3 -0
- package/src/geometries/path3/close.js +31 -0
- package/src/geometries/path3/close.test.js +43 -0
- package/src/geometries/path3/concat.d.ts +3 -0
- package/src/geometries/path3/concat.js +36 -0
- package/src/geometries/path3/concat.test.js +35 -0
- package/src/geometries/path3/create.d.ts +4 -0
- package/src/geometries/path3/create.js +30 -0
- package/src/geometries/path3/create.test.js +8 -0
- package/src/geometries/path3/equals.d.ts +3 -0
- package/src/geometries/path3/equals.js +48 -0
- package/src/geometries/path3/equals.test.js +38 -0
- package/src/geometries/path3/fromVertices.d.ts +8 -0
- package/src/geometries/path3/fromVertices.js +45 -0
- package/src/geometries/path3/fromVertices.test.js +33 -0
- package/src/geometries/path3/index.d.ts +13 -0
- package/src/geometries/path3/index.js +21 -0
- package/src/geometries/path3/isA.d.ts +3 -0
- package/src/geometries/path3/isA.js +20 -0
- package/src/geometries/path3/isA.test.js +19 -0
- package/src/geometries/path3/reverse.d.ts +3 -0
- package/src/geometries/path3/reverse.js +19 -0
- package/src/geometries/path3/reverse.test.js +9 -0
- package/src/geometries/path3/toString.d.ts +3 -0
- package/src/geometries/path3/toString.js +24 -0
- package/src/geometries/path3/toVertices.d.ts +4 -0
- package/src/geometries/path3/toVertices.js +16 -0
- package/src/geometries/path3/toVertices.test.js +13 -0
- package/src/geometries/path3/transform.d.ts +4 -0
- package/src/geometries/path3/transform.js +21 -0
- package/src/geometries/path3/transform.test.js +50 -0
- package/src/geometries/path3/type.d.ts +10 -0
- package/src/geometries/path3/validate.d.ts +1 -0
- package/src/geometries/path3/validate.js +41 -0
- package/src/geometries/poly2/create.js +1 -6
- package/src/geometries/poly3/create.js +1 -6
- package/src/geometries/poly3/index.js +1 -1
- package/src/geometries/poly3/measureBoundingBox.js +2 -0
- package/src/geometries/poly3/measureBoundingSphere.d.ts +2 -1
- package/src/geometries/poly3/measureBoundingSphere.js +25 -8
- package/src/geometries/poly3/measureBoundingSphere.test.js +12 -8
- package/src/index.js +41 -0
- package/src/measurements/measureBoundingSphere.js +2 -6
- package/src/operations/booleans/intersectGeom3.test.js +4 -4
- package/src/operations/booleans/martinez/compareEvents.js +2 -7
- package/src/operations/booleans/martinez/connectEdges.js +30 -41
- package/src/operations/booleans/martinez/contour.js +1 -1
- package/src/operations/booleans/martinez/divideSegment.js +12 -11
- package/src/operations/booleans/martinez/fillQueue.js +24 -28
- package/src/operations/booleans/martinez/index.js +2 -1
- package/src/operations/booleans/martinez/possibleIntersection.js +41 -30
- package/src/operations/booleans/martinez/segmentIntersection.js +7 -9
- package/src/operations/booleans/martinez/splaytree.js +59 -457
- package/src/operations/booleans/martinez/subdivideSegments.js +4 -4
- package/src/operations/booleans/martinez/sweepEvent.js +3 -17
- package/src/operations/booleans/subtractGeom3.test.js +4 -4
- package/src/operations/booleans/trees/Node.js +25 -27
- package/src/operations/booleans/trees/PolygonTreeNode.js +153 -106
- package/src/operations/booleans/trees/Tree.js +9 -4
- package/src/operations/booleans/trees/splitLineSegmentByPlane.js +5 -3
- package/src/operations/booleans/trees/splitPolygonByPlane.js +39 -34
- package/src/operations/booleans/unionGeom3.test.js +5 -5
- package/src/operations/extrusions/extrudeFromSlices.test.js +6 -6
- package/src/operations/extrusions/extrudeLinear.test.js +8 -8
- package/src/operations/extrusions/extrudeRotate.test.js +12 -12
- package/src/operations/extrusions/extrudeWalls.js +3 -1
- package/src/operations/hulls/hull.test.js +5 -5
- package/src/operations/hulls/hullChain.test.js +5 -5
- package/src/operations/hulls/hullPoints2.js +20 -28
- package/src/operations/hulls/toUniquePoints.js +2 -2
- package/src/operations/modifiers/generalize.test.js +6 -6
- package/src/operations/modifiers/insertTjunctions.test.js +2 -2
- package/src/operations/modifiers/mergePolygons.js +2 -3
- package/src/operations/modifiers/reTesselateCoplanarPolygons.js +7 -7
- package/src/operations/modifiers/retessellate.test.js +10 -10
- package/src/operations/modifiers/snap.test.js +4 -4
- package/src/operations/offsets/offsetGeom3.test.js +4 -4
- package/src/operations/transforms/center.test.js +7 -7
- package/src/operations/transforms/mirror.test.js +7 -7
- package/src/operations/transforms/rotate.test.js +7 -7
- package/src/operations/transforms/scale.test.js +7 -7
- package/src/operations/transforms/transform.test.js +2 -2
- package/src/operations/transforms/translate.test.js +7 -7
- package/src/primitives/cube.test.js +4 -4
- package/src/primitives/cuboid.test.js +4 -4
- package/src/primitives/cylinder.test.js +5 -5
- package/src/primitives/cylinderElliptic.test.js +9 -9
- package/src/primitives/ellipsoid.test.js +5 -5
- package/src/primitives/geodesicSphere.test.js +4 -4
- package/src/primitives/polyhedron.test.js +2 -2
- package/src/primitives/roundedCuboid.test.js +7 -7
- package/src/primitives/roundedCylinder.test.js +9 -9
- package/src/primitives/sphere.test.js +5 -5
- package/src/primitives/torus.test.js +4 -4
- package/src/geometries/geom2/fromCompactBinary.d.ts +0 -3
- package/src/geometries/geom2/fromCompactBinary.js +0 -40
- package/src/geometries/geom2/fromToCompactBinary.test.js +0 -100
- package/src/geometries/geom2/toCompactBinary.d.ts +0 -3
- package/src/geometries/geom2/toCompactBinary.js +0 -56
- package/src/geometries/geom3/fromCompactBinary.d.ts +0 -3
- package/src/geometries/geom3/fromCompactBinary.js +0 -42
- package/src/geometries/geom3/fromPointsConvex.js +0 -25
- package/src/geometries/geom3/fromToCompactBinary.test.js +0 -139
- package/src/geometries/geom3/toCompactBinary.d.ts +0 -3
- package/src/geometries/geom3/toCompactBinary.js +0 -66
- package/src/geometries/path2/fromCompactBinary.d.ts +0 -3
- package/src/geometries/path2/fromCompactBinary.js +0 -31
- package/src/geometries/path2/fromToCompactBinary.test.js +0 -114
- package/src/geometries/path2/toCompactBinary.d.ts +0 -3
- package/src/geometries/path2/toCompactBinary.js +0 -50
|
@@ -15,36 +15,40 @@ import {
|
|
|
15
15
|
} from './edgeType.js'
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
+
* and split the segments if an intersection is detected.
|
|
18
19
|
* @param {SweepEvent} se1
|
|
19
20
|
* @param {SweepEvent} se2
|
|
20
21
|
* @param {Queue} queue
|
|
21
|
-
* @return
|
|
22
|
+
* @return
|
|
23
|
+
* 0=no intersection
|
|
24
|
+
* 1=intersect point
|
|
25
|
+
* 2=overlap, left points cooinciding
|
|
26
|
+
* 3=overlap, right points cooinciding
|
|
27
|
+
* 4=segments overlap
|
|
28
|
+
* 5=segment within segment
|
|
22
29
|
*/
|
|
23
30
|
export const possibleIntersection = (se1, se2, queue) => {
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
// if (se1.isSubject === se2.isSubject) return
|
|
31
|
+
// null = no intersection
|
|
32
|
+
// array[1] = point of intersection
|
|
33
|
+
// array[2] = line overlaps, segment of overlap, i.e. two points
|
|
28
34
|
const inter = segmentIntersection(
|
|
29
35
|
se1.point, se1.otherEvent.point,
|
|
30
36
|
se2.point, se2.otherEvent.point
|
|
31
37
|
)
|
|
32
38
|
|
|
33
39
|
const nIntersections = inter ? inter.length : 0
|
|
34
|
-
if (nIntersections === 0) return 0 // no intersection
|
|
35
40
|
|
|
36
|
-
//
|
|
41
|
+
// no intersection of segments
|
|
42
|
+
if (nIntersections === 0) return 0
|
|
43
|
+
|
|
44
|
+
// single point of intersection, check the end points
|
|
37
45
|
if ((nIntersections === 1) &&
|
|
38
46
|
(equals(se1.point, se2.point) ||
|
|
39
47
|
equals(se1.otherEvent.point, se2.otherEvent.point))) {
|
|
40
48
|
return 0
|
|
41
49
|
}
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
return 0
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// The line segments associated to se1 and se2 intersect
|
|
51
|
+
// single point of intersection, divide the segments
|
|
48
52
|
if (nIntersections === 1) {
|
|
49
53
|
// if the intersection point is not an endpoint of se1
|
|
50
54
|
if (!equals(se1.point, inter[0]) && !equals(se1.otherEvent.point, inter[0])) {
|
|
@@ -58,56 +62,63 @@ export const possibleIntersection = (se1, se2, queue) => {
|
|
|
58
62
|
return 1
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
//
|
|
62
|
-
|
|
65
|
+
// segments overlap, check for same subject/clipping
|
|
66
|
+
if (nIntersections === 2 && se1.isSubject === se2.isSubject) {
|
|
67
|
+
return 0
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// segments overlap, determine the overlap, and divide segments
|
|
71
|
+
// FIXME eliminate this stack
|
|
72
|
+
const segmentEvents = []
|
|
63
73
|
let leftCoincide = false
|
|
64
74
|
let rightCoincide = false
|
|
65
75
|
|
|
66
76
|
if (equals(se1.point, se2.point)) {
|
|
67
77
|
leftCoincide = true // linked
|
|
68
78
|
} else if (compareEvents(se1, se2) === 1) {
|
|
69
|
-
|
|
79
|
+
segmentEvents.push(se2, se1)
|
|
70
80
|
} else {
|
|
71
|
-
|
|
81
|
+
segmentEvents.push(se1, se2)
|
|
72
82
|
}
|
|
73
83
|
|
|
74
84
|
if (equals(se1.otherEvent.point, se2.otherEvent.point)) {
|
|
75
85
|
rightCoincide = true
|
|
76
86
|
} else if (compareEvents(se1.otherEvent, se2.otherEvent) === 1) {
|
|
77
|
-
|
|
87
|
+
segmentEvents.push(se2.otherEvent, se1.otherEvent)
|
|
78
88
|
} else {
|
|
79
|
-
|
|
89
|
+
segmentEvents.push(se1.otherEvent, se2.otherEvent)
|
|
80
90
|
}
|
|
81
91
|
|
|
82
|
-
if (
|
|
92
|
+
if (leftCoincide) {
|
|
83
93
|
// both line segments are equal or share the left endpoint
|
|
94
|
+
// FIXME: this setting of type should be done outside this function
|
|
84
95
|
se2.type = NON_CONTRIBUTING
|
|
85
96
|
se1.type = (se2.inOut === se1.inOut) ? SAME_TRANSITION : DIFFERENT_TRANSITION
|
|
86
97
|
|
|
87
|
-
if (
|
|
88
|
-
// honestly no idea, but changing
|
|
98
|
+
if (!rightCoincide) {
|
|
99
|
+
// honestly no idea, but changing segmentEvents selection from [2, 1]
|
|
89
100
|
// to [0, 1] fixes the overlapping self-intersecting polygons issue
|
|
90
|
-
divideSegment(
|
|
101
|
+
divideSegment(segmentEvents[1].otherEvent, segmentEvents[0].point, queue)
|
|
91
102
|
}
|
|
92
103
|
return 2
|
|
93
104
|
}
|
|
94
105
|
|
|
95
106
|
// the line segments share the right endpoint
|
|
96
107
|
if (rightCoincide) {
|
|
97
|
-
divideSegment(
|
|
108
|
+
divideSegment(segmentEvents[0], segmentEvents[1].point, queue)
|
|
98
109
|
return 3
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
// no line segment includes totally the other one
|
|
102
|
-
if (
|
|
103
|
-
divideSegment(
|
|
104
|
-
divideSegment(
|
|
105
|
-
return
|
|
113
|
+
if (segmentEvents[0] !== segmentEvents[3].otherEvent) {
|
|
114
|
+
divideSegment(segmentEvents[0], segmentEvents[1].point, queue)
|
|
115
|
+
divideSegment(segmentEvents[1], segmentEvents[2].point, queue)
|
|
116
|
+
return 4
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
// one line segment includes the other one
|
|
109
|
-
divideSegment(
|
|
110
|
-
divideSegment(
|
|
120
|
+
divideSegment(segmentEvents[0], segmentEvents[1].point, queue)
|
|
121
|
+
divideSegment(segmentEvents[3].otherEvent, segmentEvents[2].point, queue)
|
|
111
122
|
|
|
112
|
-
return
|
|
123
|
+
return 5
|
|
113
124
|
}
|
|
@@ -34,7 +34,7 @@ const crossProduct = (a, b) => (a[0] * b[1]) - (a[1] * b[0])
|
|
|
34
34
|
* intersection. If they overlap, the two end points of the overlapping segment.
|
|
35
35
|
* Otherwise, null.
|
|
36
36
|
*/
|
|
37
|
-
export const segmentIntersection = (a1, a2, b1, b2, noEndpointTouch) => {
|
|
37
|
+
export const segmentIntersection = (a1, a2, b1, b2, noEndpointTouch = false) => {
|
|
38
38
|
// The algorithm expects our lines in the form P + sd, where P is a point,
|
|
39
39
|
// s is on the interval [0, 1], and d is a vector.
|
|
40
40
|
// We are passed two points. P can be the first point of each pair. The
|
|
@@ -51,11 +51,9 @@ export const segmentIntersection = (a1, a2, b1, b2, noEndpointTouch) => {
|
|
|
51
51
|
]
|
|
52
52
|
|
|
53
53
|
// The rest is pretty much a straight port of the algorithm.
|
|
54
|
-
const
|
|
54
|
+
const v1 = [b1[0] - a1[0], b1[1] - a1[1]]
|
|
55
55
|
let kross = crossProduct(va, vb)
|
|
56
56
|
let sqrKross = kross * kross
|
|
57
|
-
const sqrLenA = dotProduct(va, va)
|
|
58
|
-
// const sqrLenB = dotProduct(vb, vb)
|
|
59
57
|
|
|
60
58
|
// Check for line intersection. This works because of the properties of the
|
|
61
59
|
// cross product -- specifically, two vectors are parallel if and only if the
|
|
@@ -66,12 +64,12 @@ export const segmentIntersection = (a1, a2, b1, b2, noEndpointTouch) => {
|
|
|
66
64
|
// If they're not parallel, then (because these are line segments) they
|
|
67
65
|
// still might not actually intersect. This code checks that the
|
|
68
66
|
// intersection point of the lines is actually on both line segments.
|
|
69
|
-
const s = crossProduct(
|
|
67
|
+
const s = crossProduct(v1, vb) / kross
|
|
70
68
|
if (s < 0 || s > 1) {
|
|
71
69
|
// not on line segment a
|
|
72
70
|
return null
|
|
73
71
|
}
|
|
74
|
-
const t = crossProduct(
|
|
72
|
+
const t = crossProduct(v1, va) / kross
|
|
75
73
|
if (t < 0 || t > 1) {
|
|
76
74
|
// not on line segment b
|
|
77
75
|
return null
|
|
@@ -93,8 +91,7 @@ export const segmentIntersection = (a1, a2, b1, b2, noEndpointTouch) => {
|
|
|
93
91
|
// the (vector) difference between the two initial points. If this is parallel
|
|
94
92
|
// with the line itself, then the two lines are the same line, and there will
|
|
95
93
|
// be overlap.
|
|
96
|
-
|
|
97
|
-
kross = crossProduct(e, va)
|
|
94
|
+
kross = crossProduct(v1, va)
|
|
98
95
|
sqrKross = kross * kross
|
|
99
96
|
|
|
100
97
|
if (sqrKross > 0 /* EPS * sqLenB * sqLenE */) {
|
|
@@ -102,7 +99,8 @@ export const segmentIntersection = (a1, a2, b1, b2, noEndpointTouch) => {
|
|
|
102
99
|
return null
|
|
103
100
|
}
|
|
104
101
|
|
|
105
|
-
const
|
|
102
|
+
const sqrLenA = dotProduct(va, va)
|
|
103
|
+
const sa = dotProduct(va, v1) / sqrLenA
|
|
106
104
|
const sb = sa + dotProduct(va, vb) / sqrLenA
|
|
107
105
|
const smin = Math.min(sa, sb)
|
|
108
106
|
const smax = Math.max(sa, sb)
|