poly-extrude 0.15.0 → 0.17.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/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/poly-extrude.js +4367 -4081
- package/dist/poly-extrude.js.map +1 -1
- package/dist/poly-extrude.min.js +2 -2
- package/dist/poly-extrude.mjs +543 -259
- package/dist/poly-extrude.mjs.map +1 -1
- package/dist/polygon.d.ts +2 -0
- package/dist/polygon.js +56 -40
- package/dist/polygon.js.map +1 -1
- package/dist/polygonpath.d.ts +11 -0
- package/dist/polygonpath.js +262 -0
- package/dist/polygonpath.js.map +1 -0
- package/dist/util.d.ts +7 -1
- package/dist/util.js +63 -0
- package/dist/util.js.map +1 -1
- package/package.json +2 -2
- package/readme.md +3 -1
- package/src/index.ts +5 -2
- package/src/polygon.ts +65 -40
- package/src/polygonpath.ts +315 -0
- package/src/util.ts +68 -1
package/dist/poly-extrude.mjs
CHANGED
@@ -1,29 +1,62 @@
|
|
1
1
|
/*!
|
2
|
-
* poly-extrude v0.
|
2
|
+
* poly-extrude v0.17.0
|
3
3
|
*/
|
4
|
-
|
4
|
+
function _defineProperties(target, props) {
|
5
|
+
for (var i = 0; i < props.length; i++) {
|
6
|
+
var descriptor = props[i];
|
7
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
8
|
+
descriptor.configurable = true;
|
9
|
+
if ("value" in descriptor) descriptor.writable = true;
|
10
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
11
|
+
}
|
12
|
+
}
|
5
13
|
|
6
|
-
|
14
|
+
function _createClass(Constructor, protoProps, staticProps) {
|
15
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
16
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
17
|
+
Object.defineProperty(Constructor, "prototype", {
|
18
|
+
writable: false
|
19
|
+
});
|
20
|
+
return Constructor;
|
21
|
+
}
|
7
22
|
|
8
|
-
|
23
|
+
function _inheritsLoose(subClass, superClass) {
|
24
|
+
subClass.prototype = Object.create(superClass.prototype);
|
25
|
+
subClass.prototype.constructor = subClass;
|
26
|
+
|
27
|
+
_setPrototypeOf(subClass, superClass);
|
28
|
+
}
|
29
|
+
|
30
|
+
function _setPrototypeOf(o, p) {
|
31
|
+
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
|
32
|
+
o.__proto__ = p;
|
33
|
+
return o;
|
34
|
+
};
|
35
|
+
return _setPrototypeOf(o, p);
|
36
|
+
}
|
9
37
|
|
10
38
|
function earcut(data, holeIndices, dim) {
|
11
|
-
dim
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
39
|
+
if (dim === void 0) {
|
40
|
+
dim = 2;
|
41
|
+
}
|
42
|
+
|
43
|
+
var hasHoles = holeIndices && holeIndices.length;
|
44
|
+
var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
|
45
|
+
var outerNode = linkedList(data, 0, outerLen, dim, true);
|
46
|
+
var triangles = [];
|
16
47
|
if (!outerNode || outerNode.next === outerNode.prev) return triangles;
|
17
|
-
var minX, minY,
|
48
|
+
var minX, minY, invSize;
|
18
49
|
if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
|
19
50
|
|
20
51
|
if (data.length > 80 * dim) {
|
21
|
-
minX =
|
22
|
-
minY =
|
52
|
+
minX = Infinity;
|
53
|
+
minY = Infinity;
|
54
|
+
var maxX = -Infinity;
|
55
|
+
var maxY = -Infinity;
|
23
56
|
|
24
57
|
for (var i = dim; i < outerLen; i += dim) {
|
25
|
-
x = data[i];
|
26
|
-
y = data[i + 1];
|
58
|
+
var x = data[i];
|
59
|
+
var y = data[i + 1];
|
27
60
|
if (x < minX) minX = x;
|
28
61
|
if (y < minY) minY = y;
|
29
62
|
if (x > maxX) maxX = x;
|
@@ -39,17 +72,16 @@ function earcut(data, holeIndices, dim) {
|
|
39
72
|
return triangles;
|
40
73
|
} // create a circular doubly linked list from polygon points in the specified winding order
|
41
74
|
|
42
|
-
|
43
75
|
function linkedList(data, start, end, dim, clockwise) {
|
44
|
-
var
|
76
|
+
var last;
|
45
77
|
|
46
78
|
if (clockwise === signedArea(data, start, end, dim) > 0) {
|
47
|
-
for (i = start; i < end; i += dim) {
|
48
|
-
last = insertNode(i, data[i], data[i + 1], last);
|
79
|
+
for (var i = start; i < end; i += dim) {
|
80
|
+
last = insertNode(i / dim | 0, data[i], data[i + 1], last);
|
49
81
|
}
|
50
82
|
} else {
|
51
|
-
for (
|
52
|
-
last = insertNode(
|
83
|
+
for (var _i = end - dim; _i >= start; _i -= dim) {
|
84
|
+
last = insertNode(_i / dim | 0, data[_i], data[_i + 1], last);
|
53
85
|
}
|
54
86
|
}
|
55
87
|
|
@@ -89,19 +121,15 @@ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
|
|
89
121
|
if (!ear) return; // interlink polygon nodes in z-order
|
90
122
|
|
91
123
|
if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
|
92
|
-
var stop = ear,
|
93
|
-
prev,
|
94
|
-
next; // iterate through ears, slicing them one by one
|
124
|
+
var stop = ear; // iterate through ears, slicing them one by one
|
95
125
|
|
96
126
|
while (ear.prev !== ear.next) {
|
97
|
-
prev = ear.prev;
|
98
|
-
next = ear.next;
|
127
|
+
var prev = ear.prev;
|
128
|
+
var next = ear.next;
|
99
129
|
|
100
130
|
if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
|
101
|
-
// cut off the triangle
|
102
|
-
|
103
|
-
triangles.push(ear.i / dim | 0);
|
104
|
-
triangles.push(next.i / dim | 0);
|
131
|
+
triangles.push(prev.i, ear.i, next.i); // cut off the triangle
|
132
|
+
|
105
133
|
removeNode(ear); // skipping the next vertex leads to less sliver triangles
|
106
134
|
|
107
135
|
ear = next.next;
|
@@ -116,7 +144,7 @@ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
|
|
116
144
|
if (!pass) {
|
117
145
|
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); // if this didn't work, try curing all small self-intersections locally
|
118
146
|
} else if (pass === 1) {
|
119
|
-
ear = cureLocalIntersections(filterPoints(ear), triangles
|
147
|
+
ear = cureLocalIntersections(filterPoints(ear), triangles);
|
120
148
|
earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); // as a last resort, try splitting the remaining polygon into two
|
121
149
|
} else if (pass === 2) {
|
122
150
|
splitEarcut(ear, triangles, dim, minX, minY, invSize);
|
@@ -140,16 +168,16 @@ function isEar(ear) {
|
|
140
168
|
cx = c.x,
|
141
169
|
ay = a.y,
|
142
170
|
by = b.y,
|
143
|
-
cy = c.y; // triangle bbox
|
171
|
+
cy = c.y; // triangle bbox
|
144
172
|
|
145
|
-
var x0 = ax
|
146
|
-
y0 = ay
|
147
|
-
x1 = ax
|
148
|
-
y1 = ay
|
173
|
+
var x0 = Math.min(ax, bx, cx),
|
174
|
+
y0 = Math.min(ay, by, cy),
|
175
|
+
x1 = Math.max(ax, bx, cx),
|
176
|
+
y1 = Math.max(ay, by, cy);
|
149
177
|
var p = c.next;
|
150
178
|
|
151
179
|
while (p !== a) {
|
152
|
-
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&
|
180
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
153
181
|
p = p.next;
|
154
182
|
}
|
155
183
|
|
@@ -167,12 +195,12 @@ function isEarHashed(ear, minX, minY, invSize) {
|
|
167
195
|
cx = c.x,
|
168
196
|
ay = a.y,
|
169
197
|
by = b.y,
|
170
|
-
cy = c.y; // triangle bbox
|
198
|
+
cy = c.y; // triangle bbox
|
171
199
|
|
172
|
-
var x0 = ax
|
173
|
-
y0 = ay
|
174
|
-
x1 = ax
|
175
|
-
y1 = ay
|
200
|
+
var x0 = Math.min(ax, bx, cx),
|
201
|
+
y0 = Math.min(ay, by, cy),
|
202
|
+
x1 = Math.max(ax, bx, cx),
|
203
|
+
y1 = Math.max(ay, by, cy); // z-order range for the current triangle bbox;
|
176
204
|
|
177
205
|
var minZ = zOrder(x0, y0, minX, minY, invSize),
|
178
206
|
maxZ = zOrder(x1, y1, minX, minY, invSize);
|
@@ -180,21 +208,21 @@ function isEarHashed(ear, minX, minY, invSize) {
|
|
180
208
|
n = ear.nextZ; // look for points inside the triangle in both directions
|
181
209
|
|
182
210
|
while (p && p.z >= minZ && n && n.z <= maxZ) {
|
183
|
-
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&
|
211
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
184
212
|
p = p.prevZ;
|
185
|
-
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&
|
213
|
+
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
|
186
214
|
n = n.nextZ;
|
187
215
|
} // look for remaining points in decreasing z-order
|
188
216
|
|
189
217
|
|
190
218
|
while (p && p.z >= minZ) {
|
191
|
-
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&
|
219
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
192
220
|
p = p.prevZ;
|
193
221
|
} // look for remaining points in increasing z-order
|
194
222
|
|
195
223
|
|
196
224
|
while (n && n.z <= maxZ) {
|
197
|
-
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&
|
225
|
+
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
|
198
226
|
n = n.nextZ;
|
199
227
|
}
|
200
228
|
|
@@ -202,7 +230,7 @@ function isEarHashed(ear, minX, minY, invSize) {
|
|
202
230
|
} // go through all polygon nodes and cure small local self-intersections
|
203
231
|
|
204
232
|
|
205
|
-
function cureLocalIntersections(start, triangles
|
233
|
+
function cureLocalIntersections(start, triangles) {
|
206
234
|
var p = start;
|
207
235
|
|
208
236
|
do {
|
@@ -210,9 +238,7 @@ function cureLocalIntersections(start, triangles, dim) {
|
|
210
238
|
b = p.next.next;
|
211
239
|
|
212
240
|
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
|
213
|
-
triangles.push(a.i
|
214
|
-
triangles.push(p.i / dim | 0);
|
215
|
-
triangles.push(b.i / dim | 0); // remove two nodes involved
|
241
|
+
triangles.push(a.i, p.i, b.i); // remove two nodes involved
|
216
242
|
|
217
243
|
removeNode(p);
|
218
244
|
removeNode(p.next);
|
@@ -255,32 +281,40 @@ function splitEarcut(start, triangles, dim, minX, minY, invSize) {
|
|
255
281
|
|
256
282
|
|
257
283
|
function eliminateHoles(data, holeIndices, outerNode, dim) {
|
258
|
-
var queue = []
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
for (i = 0, len = holeIndices.length; i < len; i++) {
|
266
|
-
start = holeIndices[i] * dim;
|
267
|
-
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
268
|
-
list = linkedList(data, start, end, dim, false);
|
284
|
+
var queue = [];
|
285
|
+
|
286
|
+
for (var i = 0, len = holeIndices.length; i < len; i++) {
|
287
|
+
var start = holeIndices[i] * dim;
|
288
|
+
var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
289
|
+
var list = linkedList(data, start, end, dim, false);
|
269
290
|
if (list === list.next) list.steiner = true;
|
270
291
|
queue.push(getLeftmost(list));
|
271
292
|
}
|
272
293
|
|
273
|
-
queue.sort(
|
294
|
+
queue.sort(compareXYSlope); // process holes from left to right
|
274
295
|
|
275
|
-
for (
|
276
|
-
outerNode = eliminateHole(queue[
|
296
|
+
for (var _i2 = 0; _i2 < queue.length; _i2++) {
|
297
|
+
outerNode = eliminateHole(queue[_i2], outerNode);
|
277
298
|
}
|
278
299
|
|
279
300
|
return outerNode;
|
280
301
|
}
|
281
302
|
|
282
|
-
function
|
283
|
-
|
303
|
+
function compareXYSlope(a, b) {
|
304
|
+
var result = a.x - b.x; // when the left-most point of 2 holes meet at a vertex, sort the holes counterclockwise so that when we find
|
305
|
+
// the bridge to the outer shell is always the point that they meet at.
|
306
|
+
|
307
|
+
if (result === 0) {
|
308
|
+
result = a.y - b.y;
|
309
|
+
|
310
|
+
if (result === 0) {
|
311
|
+
var aSlope = (a.next.y - a.y) / (a.next.x - a.x);
|
312
|
+
var bSlope = (b.next.y - b.y) / (b.next.x - b.x);
|
313
|
+
result = aSlope - bSlope;
|
314
|
+
}
|
315
|
+
}
|
316
|
+
|
317
|
+
return result;
|
284
318
|
} // find a bridge between vertices that connects hole with an outer ring and and link it
|
285
319
|
|
286
320
|
|
@@ -299,15 +333,18 @@ function eliminateHole(hole, outerNode) {
|
|
299
333
|
|
300
334
|
|
301
335
|
function findHoleBridge(hole, outerNode) {
|
302
|
-
var p = outerNode
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
336
|
+
var p = outerNode;
|
337
|
+
var hx = hole.x;
|
338
|
+
var hy = hole.y;
|
339
|
+
var qx = -Infinity;
|
340
|
+
var m; // find a segment intersected by a ray from the hole's leftmost point to the left;
|
307
341
|
// segment's endpoint with lesser x will be potential connection point
|
342
|
+
// unless they intersect at a vertex, then choose the vertex
|
343
|
+
|
344
|
+
if (equals(hole, p)) return p;
|
308
345
|
|
309
346
|
do {
|
310
|
-
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
|
347
|
+
if (equals(hole, p.next)) return p.next;else if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
|
311
348
|
var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
|
312
349
|
|
313
350
|
if (x <= hx && x > qx) {
|
@@ -316,7 +353,6 @@ function findHoleBridge(hole, outerNode) {
|
|
316
353
|
if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint
|
317
354
|
}
|
318
355
|
}
|
319
|
-
|
320
356
|
p = p.next;
|
321
357
|
} while (p !== outerNode);
|
322
358
|
|
@@ -324,16 +360,15 @@ function findHoleBridge(hole, outerNode) {
|
|
324
360
|
// if there are no points found, we have a valid connection;
|
325
361
|
// otherwise choose the point of the minimum angle with the ray as connection point
|
326
362
|
|
327
|
-
var stop = m
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
tan;
|
363
|
+
var stop = m;
|
364
|
+
var mx = m.x;
|
365
|
+
var my = m.y;
|
366
|
+
var tanMin = Infinity;
|
332
367
|
p = m;
|
333
368
|
|
334
369
|
do {
|
335
370
|
if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
|
336
|
-
tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
|
371
|
+
var tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
|
337
372
|
|
338
373
|
if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
|
339
374
|
m = p;
|
@@ -371,34 +406,28 @@ function indexCurve(start, minX, minY, invSize) {
|
|
371
406
|
|
372
407
|
|
373
408
|
function sortLinked(list) {
|
374
|
-
var
|
375
|
-
|
376
|
-
q,
|
377
|
-
e,
|
378
|
-
tail,
|
379
|
-
numMerges,
|
380
|
-
pSize,
|
381
|
-
qSize,
|
382
|
-
inSize = 1;
|
409
|
+
var numMerges;
|
410
|
+
var inSize = 1;
|
383
411
|
|
384
412
|
do {
|
385
|
-
p = list;
|
413
|
+
var p = list;
|
414
|
+
var e = void 0;
|
386
415
|
list = null;
|
387
|
-
tail = null;
|
416
|
+
var tail = null;
|
388
417
|
numMerges = 0;
|
389
418
|
|
390
419
|
while (p) {
|
391
420
|
numMerges++;
|
392
|
-
q = p;
|
393
|
-
pSize = 0;
|
421
|
+
var q = p;
|
422
|
+
var pSize = 0;
|
394
423
|
|
395
|
-
for (i = 0; i < inSize; i++) {
|
424
|
+
for (var i = 0; i < inSize; i++) {
|
396
425
|
pSize++;
|
397
426
|
q = q.nextZ;
|
398
427
|
if (!q) break;
|
399
428
|
}
|
400
429
|
|
401
|
-
qSize = inSize;
|
430
|
+
var qSize = inSize;
|
402
431
|
|
403
432
|
while (pSize > 0 || qSize > 0 && q) {
|
404
433
|
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
|
@@ -458,6 +487,11 @@ function getLeftmost(start) {
|
|
458
487
|
|
459
488
|
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
|
460
489
|
return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
|
490
|
+
} // check if a point lies within a convex triangle but false if its equal to the first point of the triangle
|
491
|
+
|
492
|
+
|
493
|
+
function pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, px, py) {
|
494
|
+
return !(ax === px && ay === py) && pointInTriangle(ax, ay, bx, by, cx, cy, px, py);
|
461
495
|
} // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
|
462
496
|
|
463
497
|
|
@@ -525,10 +559,10 @@ function locallyInside(a, b) {
|
|
525
559
|
|
526
560
|
|
527
561
|
function middleInside(a, b) {
|
528
|
-
var p = a
|
529
|
-
|
530
|
-
|
531
|
-
|
562
|
+
var p = a;
|
563
|
+
var inside = false;
|
564
|
+
var px = (a.x + b.x) / 2;
|
565
|
+
var py = (a.y + b.y) / 2;
|
532
566
|
|
533
567
|
do {
|
534
568
|
if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) inside = !inside;
|
@@ -541,8 +575,8 @@ function middleInside(a, b) {
|
|
541
575
|
|
542
576
|
|
543
577
|
function splitPolygon(a, b) {
|
544
|
-
var a2 =
|
545
|
-
b2 =
|
578
|
+
var a2 = createNode(a.i, a.x, a.y),
|
579
|
+
b2 = createNode(b.i, b.x, b.y),
|
546
580
|
an = a.next,
|
547
581
|
bp = b.prev;
|
548
582
|
a.next = b;
|
@@ -558,7 +592,7 @@ function splitPolygon(a, b) {
|
|
558
592
|
|
559
593
|
|
560
594
|
function insertNode(i, x, y, last) {
|
561
|
-
var p =
|
595
|
+
var p = createNode(i, x, y);
|
562
596
|
|
563
597
|
if (!last) {
|
564
598
|
p.prev = p;
|
@@ -580,50 +614,25 @@ function removeNode(p) {
|
|
580
614
|
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
|
581
615
|
}
|
582
616
|
|
583
|
-
function
|
584
|
-
|
585
|
-
|
617
|
+
function createNode(i, x, y) {
|
618
|
+
return {
|
619
|
+
i: i,
|
620
|
+
// vertex index in coordinates array
|
621
|
+
x: x,
|
622
|
+
y: y,
|
623
|
+
// vertex coordinates
|
624
|
+
prev: null,
|
625
|
+
// previous and next vertex nodes in a polygon ring
|
626
|
+
next: null,
|
627
|
+
z: 0,
|
628
|
+
// z-order curve value
|
629
|
+
prevZ: null,
|
630
|
+
// previous and next nodes in z-order
|
631
|
+
nextZ: null,
|
632
|
+
steiner: false // indicates whether this is a steiner point
|
586
633
|
|
587
|
-
|
588
|
-
this.y = y; // previous and next vertex nodes in a polygon ring
|
589
|
-
|
590
|
-
this.prev = null;
|
591
|
-
this.next = null; // z-order curve value
|
592
|
-
|
593
|
-
this.z = 0; // previous and next nodes in z-order
|
594
|
-
|
595
|
-
this.prevZ = null;
|
596
|
-
this.nextZ = null; // indicates whether this is a steiner point
|
597
|
-
|
598
|
-
this.steiner = false;
|
634
|
+
};
|
599
635
|
} // return a percentage difference between the polygon area and its triangulation area;
|
600
|
-
// used to verify correctness of triangulation
|
601
|
-
|
602
|
-
|
603
|
-
earcut.deviation = function (data, holeIndices, dim, triangles) {
|
604
|
-
var hasHoles = holeIndices && holeIndices.length;
|
605
|
-
var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
|
606
|
-
var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
|
607
|
-
|
608
|
-
if (hasHoles) {
|
609
|
-
for (var i = 0, len = holeIndices.length; i < len; i++) {
|
610
|
-
var start = holeIndices[i] * dim;
|
611
|
-
var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
612
|
-
polygonArea -= Math.abs(signedArea(data, start, end, dim));
|
613
|
-
}
|
614
|
-
}
|
615
|
-
|
616
|
-
var trianglesArea = 0;
|
617
|
-
|
618
|
-
for (i = 0; i < triangles.length; i += 3) {
|
619
|
-
var a = triangles[i] * dim;
|
620
|
-
var b = triangles[i + 1] * dim;
|
621
|
-
var c = triangles[i + 2] * dim;
|
622
|
-
trianglesArea += Math.abs((data[a] - data[c]) * (data[b + 1] - data[a + 1]) - (data[a] - data[b]) * (data[c + 1] - data[a + 1]));
|
623
|
-
}
|
624
|
-
|
625
|
-
return polygonArea === 0 && trianglesArea === 0 ? 0 : Math.abs((trianglesArea - polygonArea) / polygonArea);
|
626
|
-
};
|
627
636
|
|
628
637
|
function signedArea(data, start, end, dim) {
|
629
638
|
var sum = 0;
|
@@ -636,68 +645,6 @@ function signedArea(data, start, end, dim) {
|
|
636
645
|
return sum;
|
637
646
|
} // turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
|
638
647
|
|
639
|
-
|
640
|
-
earcut.flatten = function (data) {
|
641
|
-
var dim = data[0][0].length,
|
642
|
-
result = {
|
643
|
-
vertices: [],
|
644
|
-
holes: [],
|
645
|
-
dimensions: dim
|
646
|
-
},
|
647
|
-
holeIndex = 0;
|
648
|
-
|
649
|
-
for (var i = 0; i < data.length; i++) {
|
650
|
-
for (var j = 0; j < data[i].length; j++) {
|
651
|
-
for (var d = 0; d < dim; d++) {
|
652
|
-
result.vertices.push(data[i][j][d]);
|
653
|
-
}
|
654
|
-
}
|
655
|
-
|
656
|
-
if (i > 0) {
|
657
|
-
holeIndex += data[i - 1].length;
|
658
|
-
result.holes.push(holeIndex);
|
659
|
-
}
|
660
|
-
}
|
661
|
-
|
662
|
-
return result;
|
663
|
-
};
|
664
|
-
|
665
|
-
var earcut$1 = earcut$2.exports;
|
666
|
-
|
667
|
-
function _defineProperties(target, props) {
|
668
|
-
for (var i = 0; i < props.length; i++) {
|
669
|
-
var descriptor = props[i];
|
670
|
-
descriptor.enumerable = descriptor.enumerable || false;
|
671
|
-
descriptor.configurable = true;
|
672
|
-
if ("value" in descriptor) descriptor.writable = true;
|
673
|
-
Object.defineProperty(target, descriptor.key, descriptor);
|
674
|
-
}
|
675
|
-
}
|
676
|
-
|
677
|
-
function _createClass(Constructor, protoProps, staticProps) {
|
678
|
-
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
679
|
-
if (staticProps) _defineProperties(Constructor, staticProps);
|
680
|
-
Object.defineProperty(Constructor, "prototype", {
|
681
|
-
writable: false
|
682
|
-
});
|
683
|
-
return Constructor;
|
684
|
-
}
|
685
|
-
|
686
|
-
function _inheritsLoose(subClass, superClass) {
|
687
|
-
subClass.prototype = Object.create(superClass.prototype);
|
688
|
-
subClass.prototype.constructor = subClass;
|
689
|
-
|
690
|
-
_setPrototypeOf(subClass, superClass);
|
691
|
-
}
|
692
|
-
|
693
|
-
function _setPrototypeOf(o, p) {
|
694
|
-
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
|
695
|
-
o.__proto__ = p;
|
696
|
-
return o;
|
697
|
-
};
|
698
|
-
return _setPrototypeOf(o, p);
|
699
|
-
}
|
700
|
-
|
701
648
|
// code copy from https://github.com/mrdoob/three.js/blob/dev/src/math/Quaternion.js
|
702
649
|
// import { clamp } from './MathUtils.js';
|
703
650
|
var Quaternion = /*#__PURE__*/function () {
|
@@ -1746,6 +1693,12 @@ var Vector3 = /*#__PURE__*/function () {
|
|
1746
1693
|
return Vector3;
|
1747
1694
|
}();
|
1748
1695
|
|
1696
|
+
function mergeArray(array1, array2) {
|
1697
|
+
let index = array1.length - 1;
|
1698
|
+
for (let i = 0, len = array2.length; i < len; i++) {
|
1699
|
+
array1[++index] = array2[i];
|
1700
|
+
}
|
1701
|
+
}
|
1749
1702
|
/**
|
1750
1703
|
* https://github.com/Turfjs/turf/blob/master/packages/turf-boolean-clockwise/index.ts
|
1751
1704
|
* @param {*} ring
|
@@ -1765,6 +1718,63 @@ function isClockwise(ring) {
|
|
1765
1718
|
}
|
1766
1719
|
return sum > 0;
|
1767
1720
|
}
|
1721
|
+
function validateRing(ring) {
|
1722
|
+
if (!isClosedRing(ring)) {
|
1723
|
+
ring.push(ring[0]);
|
1724
|
+
}
|
1725
|
+
}
|
1726
|
+
function isClosedRing(ring) {
|
1727
|
+
const len = ring.length;
|
1728
|
+
const [x1, y1] = ring[0], [x2, y2] = ring[len - 1];
|
1729
|
+
return (x1 === x2 && y1 === y2);
|
1730
|
+
}
|
1731
|
+
function calPolygonPointsCount(polygon) {
|
1732
|
+
let count = 0;
|
1733
|
+
let i = 0;
|
1734
|
+
const len = polygon.length;
|
1735
|
+
while (i < len) {
|
1736
|
+
count += (polygon[i].length);
|
1737
|
+
i++;
|
1738
|
+
}
|
1739
|
+
return count;
|
1740
|
+
}
|
1741
|
+
function getPolygonsBBOX(polygons, bbox) {
|
1742
|
+
bbox = bbox || [Infinity, Infinity, -Infinity, -Infinity];
|
1743
|
+
for (let i = 0, len = polygons.length; i < len; i++) {
|
1744
|
+
const p = polygons[i];
|
1745
|
+
if (Array.isArray(p[0][0])) {
|
1746
|
+
getPolygonsBBOX(p, bbox);
|
1747
|
+
}
|
1748
|
+
else {
|
1749
|
+
for (let j = 0, len1 = p.length; j < len1; j++) {
|
1750
|
+
const c = p[j];
|
1751
|
+
const [x, y] = c;
|
1752
|
+
bbox[0] = Math.min(bbox[0], x);
|
1753
|
+
bbox[1] = Math.min(bbox[1], y);
|
1754
|
+
bbox[2] = Math.max(bbox[2], x);
|
1755
|
+
bbox[3] = Math.max(bbox[3], y);
|
1756
|
+
}
|
1757
|
+
}
|
1758
|
+
}
|
1759
|
+
return bbox;
|
1760
|
+
}
|
1761
|
+
function validatePolygon(polygon) {
|
1762
|
+
for (let i = 0, len = polygon.length; i < len; i++) {
|
1763
|
+
const ring = polygon[i];
|
1764
|
+
validateRing(ring);
|
1765
|
+
if (i === 0) {
|
1766
|
+
if (!isClockwise(ring)) {
|
1767
|
+
polygon[i] = ring.reverse();
|
1768
|
+
}
|
1769
|
+
}
|
1770
|
+
else if (isClockwise(ring)) {
|
1771
|
+
polygon[i] = ring.reverse();
|
1772
|
+
}
|
1773
|
+
if (isClosedRing(ring)) {
|
1774
|
+
ring.splice(ring.length - 1, 1);
|
1775
|
+
}
|
1776
|
+
}
|
1777
|
+
}
|
1768
1778
|
function v3Sub(out, v1, v2) {
|
1769
1779
|
out[0] = v1[0] - v2[0];
|
1770
1780
|
out[1] = v1[1] - v2[1];
|
@@ -1963,27 +1973,13 @@ function calLineDistance(line) {
|
|
1963
1973
|
}
|
1964
1974
|
|
1965
1975
|
function extrudePolygons(polygons, options) {
|
1966
|
-
options = Object.assign({}, { depth: 2 }, options);
|
1976
|
+
options = Object.assign({}, { depth: 2, top: true }, options);
|
1967
1977
|
const results = polygons.map(polygon => {
|
1968
|
-
|
1969
|
-
const ring = polygon[i];
|
1970
|
-
validateRing(ring);
|
1971
|
-
if (i === 0) {
|
1972
|
-
if (!isClockwise(ring)) {
|
1973
|
-
polygon[i] = ring.reverse();
|
1974
|
-
}
|
1975
|
-
}
|
1976
|
-
else if (isClockwise(ring)) {
|
1977
|
-
polygon[i] = ring.reverse();
|
1978
|
-
}
|
1979
|
-
if (isClosedRing(ring)) {
|
1980
|
-
ring.splice(ring.length - 1, 1);
|
1981
|
-
}
|
1982
|
-
}
|
1978
|
+
validatePolygon(polygon);
|
1983
1979
|
const result = flatVertices(polygon, options);
|
1984
1980
|
result.polygon = polygon;
|
1985
|
-
const triangles = earcut
|
1986
|
-
generateTopAndBottom$1(result, triangles);
|
1981
|
+
const triangles = earcut(result.flatVertices, result.holes, 2);
|
1982
|
+
generateTopAndBottom$1(result, triangles, options);
|
1987
1983
|
generateSides$1(result, options);
|
1988
1984
|
result.position = new Float32Array(result.points);
|
1989
1985
|
result.indices = new Uint32Array(result.indices);
|
@@ -1995,18 +1991,24 @@ function extrudePolygons(polygons, options) {
|
|
1995
1991
|
result.polygons = polygons;
|
1996
1992
|
return result;
|
1997
1993
|
}
|
1998
|
-
function generateTopAndBottom$1(result, triangles) {
|
1994
|
+
function generateTopAndBottom$1(result, triangles, options) {
|
1999
1995
|
const indices = [];
|
2000
1996
|
const { count } = result;
|
1997
|
+
const top = options.top;
|
2001
1998
|
for (let i = 0, len = triangles.length; i < len; i += 3) {
|
2002
1999
|
// top
|
2003
2000
|
const a = triangles[i], b = triangles[i + 1], c = triangles[i + 2];
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2001
|
+
if (top) {
|
2002
|
+
indices[i] = a;
|
2003
|
+
indices[i + 1] = b;
|
2004
|
+
indices[i + 2] = c;
|
2005
|
+
}
|
2007
2006
|
// bottom
|
2008
|
-
|
2007
|
+
let idx = len + i;
|
2009
2008
|
const a1 = count + a, b1 = count + b, c1 = count + c;
|
2009
|
+
if (!top) {
|
2010
|
+
idx = i;
|
2011
|
+
}
|
2010
2012
|
indices[idx] = a1;
|
2011
2013
|
indices[idx + 1] = b1;
|
2012
2014
|
indices[idx + 2] = c1;
|
@@ -2058,16 +2060,6 @@ function generateSides$1(result, options) {
|
|
2058
2060
|
}
|
2059
2061
|
}
|
2060
2062
|
}
|
2061
|
-
function calPolygonPointsCount(polygon) {
|
2062
|
-
let count = 0;
|
2063
|
-
let i = 0;
|
2064
|
-
const len = polygon.length;
|
2065
|
-
while (i < len) {
|
2066
|
-
count += (polygon[i].length);
|
2067
|
-
i++;
|
2068
|
-
}
|
2069
|
-
return count;
|
2070
|
-
}
|
2071
2063
|
function flatVertices(polygon, options) {
|
2072
2064
|
const count = calPolygonPointsCount(polygon);
|
2073
2065
|
const len = polygon.length;
|
@@ -2112,15 +2104,49 @@ function flatVertices(polygon, options) {
|
|
2112
2104
|
uv
|
2113
2105
|
};
|
2114
2106
|
}
|
2115
|
-
function
|
2116
|
-
|
2117
|
-
|
2107
|
+
function simplePolygon(polygon, options = {}) {
|
2108
|
+
const flatVertices = [], holes = [];
|
2109
|
+
let pIndex = -1, aIndex = -1, uvIndex = -1;
|
2110
|
+
const points = [], uv = [];
|
2111
|
+
for (let i = 0, len = polygon.length; i < len; i++) {
|
2112
|
+
const ring = polygon[i];
|
2113
|
+
if (i > 0) {
|
2114
|
+
holes.push(flatVertices.length / 2);
|
2115
|
+
}
|
2116
|
+
for (let j = 0, len1 = ring.length; j < len1; j++) {
|
2117
|
+
const c = ring[j];
|
2118
|
+
flatVertices[++pIndex] = c[0];
|
2119
|
+
flatVertices[++pIndex] = c[1];
|
2120
|
+
points[++aIndex] = c[0];
|
2121
|
+
points[++aIndex] = c[1];
|
2122
|
+
points[++aIndex] = c[2] || 0;
|
2123
|
+
uv[++uvIndex] = c[0];
|
2124
|
+
uv[++uvIndex] = c[1];
|
2125
|
+
}
|
2118
2126
|
}
|
2127
|
+
const triangles = earcut(flatVertices, holes, 2);
|
2128
|
+
const normal = generateNormal(triangles, points);
|
2129
|
+
return {
|
2130
|
+
normal,
|
2131
|
+
uv,
|
2132
|
+
points,
|
2133
|
+
indices: triangles
|
2134
|
+
};
|
2119
2135
|
}
|
2120
|
-
function
|
2121
|
-
const
|
2122
|
-
|
2123
|
-
|
2136
|
+
function polygons(polygons, options = {}) {
|
2137
|
+
const results = polygons.map(polygon => {
|
2138
|
+
validatePolygon(polygon);
|
2139
|
+
const result = simplePolygon(polygon, options);
|
2140
|
+
result.polygon = polygon;
|
2141
|
+
result.position = new Float32Array(result.points);
|
2142
|
+
result.indices = new Uint32Array(result.indices);
|
2143
|
+
result.uv = new Float32Array(result.uv);
|
2144
|
+
result.normal = new Float32Array(result.normal);
|
2145
|
+
return result;
|
2146
|
+
});
|
2147
|
+
const result = merge(results);
|
2148
|
+
result.polygons = polygons;
|
2149
|
+
return result;
|
2124
2150
|
}
|
2125
2151
|
|
2126
2152
|
function checkOptions(options) {
|
@@ -2416,7 +2442,7 @@ function expandLine(line, options) {
|
|
2416
2442
|
TEMPV1.y = p0[1] - p1[1];
|
2417
2443
|
TEMPV2.x = p2[0] - p1[0];
|
2418
2444
|
TEMPV2.y = p2[1] - p1[1];
|
2419
|
-
const vAngle = getAngle(TEMPV1, TEMPV2);
|
2445
|
+
const vAngle = getAngle$1(TEMPV1, TEMPV2);
|
2420
2446
|
rAngle = angle - vAngle / 2;
|
2421
2447
|
}
|
2422
2448
|
const rRad = degToRad(rAngle);
|
@@ -2453,7 +2479,7 @@ function expandLine(line, options) {
|
|
2453
2479
|
}
|
2454
2480
|
return { offsetPoints: points, leftPoints, rightPoints, line };
|
2455
2481
|
}
|
2456
|
-
const getAngle = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
|
2482
|
+
const getAngle$1 = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
|
2457
2483
|
const dot = x1 * x2 + y1 * y2;
|
2458
2484
|
const det = x1 * y2 - y1 * x2;
|
2459
2485
|
const angle = Math.atan2(det, dot) / Math.PI * 180;
|
@@ -3930,7 +3956,7 @@ var PathPointList = /*#__PURE__*/function () {
|
|
3930
3956
|
return PathPointList;
|
3931
3957
|
}();
|
3932
3958
|
|
3933
|
-
const UP$
|
3959
|
+
const UP$2 = new Vector3(0, 0, 1);
|
3934
3960
|
const right = new Vector3();
|
3935
3961
|
const left = new Vector3();
|
3936
3962
|
// for sharp corners
|
@@ -3944,7 +3970,7 @@ function expandPaths(lines, options) {
|
|
3944
3970
|
const points = line2Vectors(line);
|
3945
3971
|
const pathPointList = new PathPointList();
|
3946
3972
|
//@ts-ignore
|
3947
|
-
pathPointList.set(points, options.cornerRadius, options.cornerSplit, UP$
|
3973
|
+
pathPointList.set(points, options.cornerRadius, options.cornerSplit, UP$2);
|
3948
3974
|
const params = generatePathVertexData(pathPointList, options);
|
3949
3975
|
const result = {
|
3950
3976
|
position: new Float32Array(params.position),
|
@@ -4253,15 +4279,15 @@ function generatePathVertexData(pathPointList, options) {
|
|
4253
4279
|
};
|
4254
4280
|
}
|
4255
4281
|
|
4256
|
-
const UP = new Vector3(0, 0, 1);
|
4257
|
-
const normalDir = new Vector3();
|
4282
|
+
const UP$1 = new Vector3(0, 0, 1);
|
4283
|
+
const normalDir$1 = new Vector3();
|
4258
4284
|
function expandTubes(lines, options) {
|
4259
4285
|
options = Object.assign({}, { radius: 1, cornerSplit: 0, radialSegments: 8, startRad: -Math.PI / 4 }, options);
|
4260
4286
|
const results = lines.map(line => {
|
4261
4287
|
const points = line2Vectors(line);
|
4262
4288
|
const pathPointList = new PathPointList();
|
4263
4289
|
//@ts-ignore
|
4264
|
-
pathPointList.set(points, 0, options.cornerSplit, UP);
|
4290
|
+
pathPointList.set(points, 0, options.cornerSplit, UP$1);
|
4265
4291
|
const result = generateTubeVertexData(pathPointList, options);
|
4266
4292
|
result.line = line;
|
4267
4293
|
result.position = new Float32Array(result.points);
|
@@ -4308,14 +4334,14 @@ function generateTubeVertexData(pathPointList, options) {
|
|
4308
4334
|
if (r === radialSegments) {
|
4309
4335
|
r = 0;
|
4310
4336
|
}
|
4311
|
-
normalDir.copy(pathPoint.up).applyAxisAngle(pathPoint.dir, startRad + Math.PI * 2 * r / radialSegments).normalize();
|
4337
|
+
normalDir$1.copy(pathPoint.up).applyAxisAngle(pathPoint.dir, startRad + Math.PI * 2 * r / radialSegments).normalize();
|
4312
4338
|
const scale = radius * pathPoint.widthScale;
|
4313
|
-
points[++pIndex] = pathPoint.pos.x + normalDir.x * scale;
|
4314
|
-
points[++pIndex] = pathPoint.pos.y + normalDir.y * scale;
|
4315
|
-
points[++pIndex] = pathPoint.pos.z + normalDir.z * scale;
|
4316
|
-
normal[++nIndex] = normalDir.x;
|
4317
|
-
normal[++nIndex] = normalDir.y;
|
4318
|
-
normal[++nIndex] = normalDir.z;
|
4339
|
+
points[++pIndex] = pathPoint.pos.x + normalDir$1.x * scale;
|
4340
|
+
points[++pIndex] = pathPoint.pos.y + normalDir$1.y * scale;
|
4341
|
+
points[++pIndex] = pathPoint.pos.z + normalDir$1.z * scale;
|
4342
|
+
normal[++nIndex] = normalDir$1.x;
|
4343
|
+
normal[++nIndex] = normalDir$1.y;
|
4344
|
+
normal[++nIndex] = normalDir$1.z;
|
4319
4345
|
uv[++uIndex] = uvDist;
|
4320
4346
|
uv[++uIndex] = i / radialSegments;
|
4321
4347
|
// uvs.push(uvDist, r / radialSegments);
|
@@ -4430,5 +4456,263 @@ function plane(width, height, devideW, devideH) {
|
|
4430
4456
|
};
|
4431
4457
|
}
|
4432
4458
|
|
4433
|
-
|
4459
|
+
const UP = new Vector3(0, 0, 1);
|
4460
|
+
const normalDir = new Vector3();
|
4461
|
+
function extrudePolygonsOnPath(polygons, options) {
|
4462
|
+
options = Object.assign({}, { openEnd: false, openEndUV: true }, options);
|
4463
|
+
const { extrudePath, openEnd } = options;
|
4464
|
+
if (!extrudePath || !Array.isArray(extrudePath) || extrudePath.length < 2) {
|
4465
|
+
console.error('extrudePath is error:', extrudePath);
|
4466
|
+
return null;
|
4467
|
+
}
|
4468
|
+
const bbox = getPolygonsBBOX(polygons);
|
4469
|
+
const [minx, miny, maxx, maxy] = bbox;
|
4470
|
+
const center = [(minx + maxx) / 2, (miny + maxy) / 2];
|
4471
|
+
const points = line2Vectors(extrudePath);
|
4472
|
+
const pathPointList = new PathPointList();
|
4473
|
+
//@ts-ignore
|
4474
|
+
pathPointList.set(points, 0, options.cornerSplit, UP);
|
4475
|
+
const results = polygons.map(polygon => {
|
4476
|
+
for (let i = 0, len = polygon.length; i < len; i++) {
|
4477
|
+
const ring = polygon[i];
|
4478
|
+
validateRing(ring);
|
4479
|
+
if (i === 0) {
|
4480
|
+
if (isClockwise(ring)) {
|
4481
|
+
polygon[i] = ring.reverse();
|
4482
|
+
}
|
4483
|
+
}
|
4484
|
+
else if (!isClockwise(ring)) {
|
4485
|
+
polygon[i] = ring.reverse();
|
4486
|
+
}
|
4487
|
+
}
|
4488
|
+
const result = generatePolygonOnPathVertexData(pathPointList, polygon, center);
|
4489
|
+
if (!openEnd) {
|
4490
|
+
generateStartAndEnd(result, polygon, options);
|
4491
|
+
}
|
4492
|
+
result.polygon = polygon;
|
4493
|
+
result.position = new Float32Array(result.points);
|
4494
|
+
result.indices = new Uint32Array(result.indices);
|
4495
|
+
result.uv = new Float32Array(result.uv);
|
4496
|
+
result.normal = new Float32Array(result.normal);
|
4497
|
+
return result;
|
4498
|
+
});
|
4499
|
+
const result = merge(results);
|
4500
|
+
result.polygons = polygons;
|
4501
|
+
return result;
|
4502
|
+
}
|
4503
|
+
function getAngle(c1, c2) {
|
4504
|
+
const [x1, y1] = c1;
|
4505
|
+
const [x2, y2] = c2;
|
4506
|
+
const dy = y2 - y1;
|
4507
|
+
const dx = x2 - x1;
|
4508
|
+
return Math.atan2(dy, dx);
|
4509
|
+
}
|
4510
|
+
function transformPolygon(polygon, center) {
|
4511
|
+
const [cx, cy] = center;
|
4512
|
+
const list = [];
|
4513
|
+
polygon.forEach((ring, rIndex) => {
|
4514
|
+
const data = [];
|
4515
|
+
let totalDistance = 0;
|
4516
|
+
let tempPoint;
|
4517
|
+
for (let i = 0, len = ring.length; i < len; i++) {
|
4518
|
+
const p = ring[i];
|
4519
|
+
const x1 = p[0], y1 = p[1];
|
4520
|
+
const offsetx = x1 - cx, offsety = y1 - cy;
|
4521
|
+
let distance = 0;
|
4522
|
+
if (i > 0) {
|
4523
|
+
const x2 = tempPoint[0], y2 = tempPoint[1];
|
4524
|
+
const dx = x2 - x1, dy = y2 - y1;
|
4525
|
+
distance = Math.sqrt(dx * dx + dy * dy) + totalDistance;
|
4526
|
+
totalDistance = distance;
|
4527
|
+
}
|
4528
|
+
data[i] = {
|
4529
|
+
// dx,
|
4530
|
+
// dy,
|
4531
|
+
// dz: 0,
|
4532
|
+
distance,
|
4533
|
+
radius: Math.sqrt(offsetx * offsetx + offsety * offsety),
|
4534
|
+
angle: getAngle(center, p)
|
4535
|
+
};
|
4536
|
+
tempPoint = p;
|
4537
|
+
}
|
4538
|
+
list[rIndex] = {
|
4539
|
+
ring: data,
|
4540
|
+
ringLen: totalDistance
|
4541
|
+
};
|
4542
|
+
});
|
4543
|
+
return list;
|
4544
|
+
}
|
4545
|
+
const TEMP_VECTOR3 = new Vector3(0, 0, 0);
|
4546
|
+
// Vertex Data Generate Functions
|
4547
|
+
// code copy from https://github.com/shawn0326/three.path/blob/master/src/PathGeometry.js
|
4548
|
+
function generatePolygonOnPathVertexData(pathPointList, polygon, center) {
|
4549
|
+
const tpolygon = transformPolygon(polygon, center);
|
4550
|
+
// let count = 0;
|
4551
|
+
// modify data
|
4552
|
+
const points = [];
|
4553
|
+
const normal = [];
|
4554
|
+
const uv = [];
|
4555
|
+
// const uv2 = [];
|
4556
|
+
const indices = [];
|
4557
|
+
let verticesCount = 0;
|
4558
|
+
let pIndex = -1;
|
4559
|
+
let nIndex = -1;
|
4560
|
+
let uIndex = -1;
|
4561
|
+
let iIndex = -1;
|
4562
|
+
const startPoints = [], endPoints = [];
|
4563
|
+
function addVertices(pathPoint, ring, ringLen, first, end) {
|
4564
|
+
const uvDist = pathPoint.dist / ringLen;
|
4565
|
+
const radialSegments = ring.length;
|
4566
|
+
// const startRad = ring[0].angle;
|
4567
|
+
for (let i = 0; i < radialSegments; i++) {
|
4568
|
+
const item = ring[i];
|
4569
|
+
if (!item) {
|
4570
|
+
continue;
|
4571
|
+
}
|
4572
|
+
const isLast = i === radialSegments - 1;
|
4573
|
+
const angle = item.angle;
|
4574
|
+
const radius = item.radius;
|
4575
|
+
const distance = item.distance;
|
4576
|
+
normalDir.copy(pathPoint.up).applyAxisAngle(pathPoint.dir, angle).normalize();
|
4577
|
+
const v = TEMP_VECTOR3.copy(pathPoint.up);
|
4578
|
+
v.applyAxisAngle(pathPoint.dir, angle);
|
4579
|
+
v.x *= radius;
|
4580
|
+
v.y *= radius;
|
4581
|
+
v.z *= radius;
|
4582
|
+
points[++pIndex] = pathPoint.pos.x + v.x;
|
4583
|
+
points[++pIndex] = pathPoint.pos.y + v.y;
|
4584
|
+
points[++pIndex] = pathPoint.pos.z + v.z;
|
4585
|
+
// if (i === 0 || i === radialSegments - 1) {
|
4586
|
+
// console.log(i, radialSegments, v.x, v.y, v.z);
|
4587
|
+
// }
|
4588
|
+
normal[++nIndex] = normalDir.x;
|
4589
|
+
normal[++nIndex] = normalDir.y;
|
4590
|
+
normal[++nIndex] = normalDir.z;
|
4591
|
+
uv[++uIndex] = uvDist;
|
4592
|
+
uv[++uIndex] = distance / ringLen;
|
4593
|
+
verticesCount++;
|
4594
|
+
if (first && !isLast) {
|
4595
|
+
let index = startPoints.length - 1;
|
4596
|
+
startPoints[++index] = pathPoint.pos.x + v.x;
|
4597
|
+
startPoints[++index] = pathPoint.pos.y + v.y;
|
4598
|
+
startPoints[++index] = pathPoint.pos.z + v.z;
|
4599
|
+
}
|
4600
|
+
if (end && !isLast) {
|
4601
|
+
let index = endPoints.length - 1;
|
4602
|
+
endPoints[++index] = pathPoint.pos.x + v.x;
|
4603
|
+
endPoints[++index] = pathPoint.pos.y + v.y;
|
4604
|
+
endPoints[++index] = pathPoint.pos.z + v.z;
|
4605
|
+
}
|
4606
|
+
}
|
4607
|
+
if (!first) {
|
4608
|
+
const begin1 = verticesCount - (radialSegments) * 2;
|
4609
|
+
const begin2 = verticesCount - (radialSegments);
|
4610
|
+
for (let i = 0; i < radialSegments; i++) {
|
4611
|
+
indices[++iIndex] = begin2 + i;
|
4612
|
+
indices[++iIndex] = begin1 + i;
|
4613
|
+
indices[++iIndex] = begin1 + i + 1;
|
4614
|
+
indices[++iIndex] = begin2 + i;
|
4615
|
+
indices[++iIndex] = begin1 + i + 1;
|
4616
|
+
indices[++iIndex] = begin2 + i + 1;
|
4617
|
+
}
|
4618
|
+
}
|
4619
|
+
}
|
4620
|
+
const polygonLen = tpolygon[0].ringLen;
|
4621
|
+
tpolygon.forEach(item => {
|
4622
|
+
for (let i = 0; i < pathPointList.count; i++) {
|
4623
|
+
const pathPoint = pathPointList.array[i];
|
4624
|
+
const { ring, ringLen } = item;
|
4625
|
+
addVertices(pathPoint, ring, ringLen, i === 0, i === pathPointList.count - 1);
|
4626
|
+
}
|
4627
|
+
});
|
4628
|
+
return {
|
4629
|
+
points,
|
4630
|
+
normal,
|
4631
|
+
uv,
|
4632
|
+
// uv2,
|
4633
|
+
indices,
|
4634
|
+
startPoints,
|
4635
|
+
endPoints,
|
4636
|
+
polygonLen
|
4637
|
+
// count
|
4638
|
+
};
|
4639
|
+
}
|
4640
|
+
function generateStartAndEnd(result, polygon, options) {
|
4641
|
+
const { openEndUV } = options;
|
4642
|
+
for (let i = 0, len = polygon.length; i < len; i++) {
|
4643
|
+
const ring = polygon[i];
|
4644
|
+
if (isClosedRing(ring)) {
|
4645
|
+
ring.splice(ring.length - 1, 1);
|
4646
|
+
}
|
4647
|
+
}
|
4648
|
+
const pointCount = calPolygonPointsCount(polygon);
|
4649
|
+
const flatVertices = [], holes = [];
|
4650
|
+
let pIndex = -1;
|
4651
|
+
for (let i = 0, len = polygon.length; i < len; i++) {
|
4652
|
+
const ring = polygon[i];
|
4653
|
+
if (i > 0) {
|
4654
|
+
holes.push(flatVertices.length / 2);
|
4655
|
+
}
|
4656
|
+
for (let j = 0, len1 = ring.length; j < len1; j++) {
|
4657
|
+
const c = ring[j];
|
4658
|
+
flatVertices[++pIndex] = c[0];
|
4659
|
+
flatVertices[++pIndex] = c[1];
|
4660
|
+
}
|
4661
|
+
}
|
4662
|
+
const triangles = earcut(flatVertices, holes, 2);
|
4663
|
+
const { points, normal, uv, indices, startPoints, endPoints, polygonLen } = result;
|
4664
|
+
pIndex = 0;
|
4665
|
+
let uIndex = 0;
|
4666
|
+
const aPoints1 = [], auv1 = [], aPoints2 = [], auv2 = [];
|
4667
|
+
for (let i = 0; i < pointCount; i++) {
|
4668
|
+
const idx = i * 3;
|
4669
|
+
const x = startPoints[idx];
|
4670
|
+
const y = startPoints[idx + 1];
|
4671
|
+
const z = startPoints[idx + 2];
|
4672
|
+
aPoints1[pIndex] = x;
|
4673
|
+
aPoints1[pIndex + 1] = y;
|
4674
|
+
aPoints1[pIndex + 2] = z;
|
4675
|
+
if (openEndUV) {
|
4676
|
+
auv1[uIndex] = y / polygonLen;
|
4677
|
+
auv1[uIndex + 1] = z / polygonLen;
|
4678
|
+
}
|
4679
|
+
else {
|
4680
|
+
auv1[uIndex] = 0;
|
4681
|
+
auv1[uIndex + 1] = 0;
|
4682
|
+
}
|
4683
|
+
const x1 = endPoints[idx];
|
4684
|
+
const y1 = endPoints[idx + 1];
|
4685
|
+
const z1 = endPoints[idx + 2];
|
4686
|
+
aPoints2[pIndex] = x1;
|
4687
|
+
aPoints2[pIndex + 1] = y1;
|
4688
|
+
aPoints2[pIndex + 2] = z1;
|
4689
|
+
if (openEndUV) {
|
4690
|
+
auv2[uIndex] = y1 / polygonLen;
|
4691
|
+
auv2[uIndex + 1] = z1 / polygonLen;
|
4692
|
+
}
|
4693
|
+
else {
|
4694
|
+
auv2[uIndex] = 0;
|
4695
|
+
auv2[uIndex + 1] = 0;
|
4696
|
+
}
|
4697
|
+
pIndex += 3;
|
4698
|
+
uIndex += 2;
|
4699
|
+
}
|
4700
|
+
const indexOffset = points.length / 3;
|
4701
|
+
const indexs = [];
|
4702
|
+
for (let i = 0, len = triangles.length; i < len; i++) {
|
4703
|
+
indexs[i] = triangles[i] + indexOffset;
|
4704
|
+
indexs[i + len] = triangles[i] + indexOffset + pointCount;
|
4705
|
+
}
|
4706
|
+
const anormal1 = generateNormal(triangles, aPoints1);
|
4707
|
+
const anormal2 = generateNormal(triangles, aPoints2);
|
4708
|
+
mergeArray(points, aPoints1);
|
4709
|
+
mergeArray(points, aPoints2);
|
4710
|
+
mergeArray(uv, auv1);
|
4711
|
+
mergeArray(uv, auv2);
|
4712
|
+
mergeArray(normal, anormal1);
|
4713
|
+
mergeArray(normal, anormal2);
|
4714
|
+
mergeArray(indices, indexs);
|
4715
|
+
}
|
4716
|
+
|
4717
|
+
export { cylinder, expandLine, expandPaths, expandTubes, extrudePolygons, extrudePolygonsOnPath, extrudePolylines, extrudeSlopes, isClockwise, leftOnLine, merge, plane, polygons };
|
4434
4718
|
//# sourceMappingURL=poly-extrude.mjs.map
|