tess-extrude 0.1.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.
@@ -0,0 +1,1726 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const THREE = require("three");
4
+ const SVGLoader_js = require("three/examples/jsm/loaders/SVGLoader.js");
5
+ function _interopNamespaceDefault(e) {
6
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
7
+ if (e) {
8
+ for (const k in e) {
9
+ if (k !== "default") {
10
+ const d = Object.getOwnPropertyDescriptor(e, k);
11
+ Object.defineProperty(n, k, d.get ? d : {
12
+ enumerable: true,
13
+ get: () => e[k]
14
+ });
15
+ }
16
+ }
17
+ }
18
+ n.default = e;
19
+ return Object.freeze(n);
20
+ }
21
+ const THREE__namespace = /* @__PURE__ */ _interopNamespaceDefault(THREE);
22
+ function validatePoints(points) {
23
+ if (!Array.isArray(points) || points.length < 3) return null;
24
+ for (const p of points) {
25
+ if (typeof p.x !== "number" || typeof p.y !== "number" || !isFinite(p.x) || !isFinite(p.y)) {
26
+ return null;
27
+ }
28
+ }
29
+ return points;
30
+ }
31
+ function fromSVG(data) {
32
+ let svgString;
33
+ if (data.startsWith("data:")) {
34
+ const commaIdx = data.indexOf(",");
35
+ svgString = atob(commaIdx >= 0 ? data.slice(commaIdx + 1) : data);
36
+ } else {
37
+ svgString = atob(data);
38
+ }
39
+ const loader = new SVGLoader_js.SVGLoader();
40
+ const svgData = loader.parse(svgString);
41
+ const contours = [];
42
+ for (const path of svgData.paths) {
43
+ const shapes = SVGLoader_js.SVGLoader.createShapes(path);
44
+ for (const shape of shapes) {
45
+ const pts = shape.getPoints();
46
+ if (pts.length >= 3) {
47
+ contours.push(pts.map((p) => ({ x: p.x, y: p.y })));
48
+ }
49
+ }
50
+ }
51
+ return contours;
52
+ }
53
+ function deduplicatePoints(points, eps = 0.5) {
54
+ if (points.length === 0) return [];
55
+ const epsSq = eps * eps;
56
+ const result = [points[0]];
57
+ for (let i = 1; i < points.length; i++) {
58
+ const prev = result[result.length - 1];
59
+ const cur = points[i];
60
+ const dx = cur.x - prev.x;
61
+ const dy = cur.y - prev.y;
62
+ if (dx * dx + dy * dy > epsSq) {
63
+ result.push(cur);
64
+ }
65
+ }
66
+ if (result.length > 1) {
67
+ const first = result[0];
68
+ const last = result[result.length - 1];
69
+ const dx = last.x - first.x;
70
+ const dy = last.y - first.y;
71
+ if (dx * dx + dy * dy <= epsSq) {
72
+ result.pop();
73
+ }
74
+ }
75
+ return result;
76
+ }
77
+ function ensureCCW(points) {
78
+ let area = 0;
79
+ for (let i = 0; i < points.length; i++) {
80
+ const j = (i + 1) % points.length;
81
+ area += points[i].x * points[j].y;
82
+ area -= points[j].x * points[i].y;
83
+ }
84
+ if (area < 0) {
85
+ return [...points].reverse();
86
+ }
87
+ return points;
88
+ }
89
+ function centerPoints(points) {
90
+ let cx = 0;
91
+ let cy = 0;
92
+ for (const p of points) {
93
+ cx += p.x;
94
+ cy += p.y;
95
+ }
96
+ cx /= points.length;
97
+ cy /= points.length;
98
+ return points.map((p) => ({ x: p.x - cx, y: p.y - cy }));
99
+ }
100
+ function subdivideBoundary(points, subdivisions) {
101
+ if (subdivisions <= 1) return [...points];
102
+ const n = points.length;
103
+ const result = new Array(n * subdivisions);
104
+ for (let i = 0; i < n; i++) {
105
+ const a = points[i];
106
+ const b = points[(i + 1) % n];
107
+ for (let s = 0; s < subdivisions; s++) {
108
+ const t = s / subdivisions;
109
+ result[i * subdivisions + s] = {
110
+ x: a.x + (b.x - a.x) * t,
111
+ y: a.y + (b.y - a.y) * t
112
+ };
113
+ }
114
+ }
115
+ return result;
116
+ }
117
+ var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
118
+ var poly2tri = {};
119
+ const version = "1.5.0";
120
+ const require$$0 = {
121
+ version
122
+ };
123
+ function toStringBase(p) {
124
+ return "(" + p.x + ";" + p.y + ")";
125
+ }
126
+ function toString(p) {
127
+ var s = p.toString();
128
+ return s === "[object Object]" ? toStringBase(p) : s;
129
+ }
130
+ function compare(a, b) {
131
+ if (a.y === b.y) {
132
+ return a.x - b.x;
133
+ } else {
134
+ return a.y - b.y;
135
+ }
136
+ }
137
+ function equals(a, b) {
138
+ return a.x === b.x && a.y === b.y;
139
+ }
140
+ var xy$3 = {
141
+ toString,
142
+ toStringBase,
143
+ compare,
144
+ equals
145
+ };
146
+ var xy$2 = xy$3;
147
+ var PointError$2 = function(message, points) {
148
+ this.name = "PointError";
149
+ this.points = points = points || [];
150
+ this.message = message || "Invalid Points!";
151
+ for (var i = 0; i < points.length; i++) {
152
+ this.message += " " + xy$2.toString(points[i]);
153
+ }
154
+ };
155
+ PointError$2.prototype = new Error();
156
+ PointError$2.prototype.constructor = PointError$2;
157
+ var pointerror = PointError$2;
158
+ var xy$1 = xy$3;
159
+ var Point$1 = function(x, y) {
160
+ this.x = +x || 0;
161
+ this.y = +y || 0;
162
+ this._p2t_edge_list = null;
163
+ };
164
+ Point$1.prototype.toString = function() {
165
+ return xy$1.toStringBase(this);
166
+ };
167
+ Point$1.prototype.toJSON = function() {
168
+ return { x: this.x, y: this.y };
169
+ };
170
+ Point$1.prototype.clone = function() {
171
+ return new Point$1(this.x, this.y);
172
+ };
173
+ Point$1.prototype.set_zero = function() {
174
+ this.x = 0;
175
+ this.y = 0;
176
+ return this;
177
+ };
178
+ Point$1.prototype.set = function(x, y) {
179
+ this.x = +x || 0;
180
+ this.y = +y || 0;
181
+ return this;
182
+ };
183
+ Point$1.prototype.negate = function() {
184
+ this.x = -this.x;
185
+ this.y = -this.y;
186
+ return this;
187
+ };
188
+ Point$1.prototype.add = function(n) {
189
+ this.x += n.x;
190
+ this.y += n.y;
191
+ return this;
192
+ };
193
+ Point$1.prototype.sub = function(n) {
194
+ this.x -= n.x;
195
+ this.y -= n.y;
196
+ return this;
197
+ };
198
+ Point$1.prototype.mul = function(s) {
199
+ this.x *= s;
200
+ this.y *= s;
201
+ return this;
202
+ };
203
+ Point$1.prototype.length = function() {
204
+ return Math.sqrt(this.x * this.x + this.y * this.y);
205
+ };
206
+ Point$1.prototype.normalize = function() {
207
+ var len = this.length();
208
+ this.x /= len;
209
+ this.y /= len;
210
+ return len;
211
+ };
212
+ Point$1.prototype.equals = function(p) {
213
+ return this.x === p.x && this.y === p.y;
214
+ };
215
+ Point$1.negate = function(p) {
216
+ return new Point$1(-p.x, -p.y);
217
+ };
218
+ Point$1.add = function(a, b) {
219
+ return new Point$1(a.x + b.x, a.y + b.y);
220
+ };
221
+ Point$1.sub = function(a, b) {
222
+ return new Point$1(a.x - b.x, a.y - b.y);
223
+ };
224
+ Point$1.mul = function(s, p) {
225
+ return new Point$1(s * p.x, s * p.y);
226
+ };
227
+ Point$1.cross = function(a, b) {
228
+ if (typeof a === "number") {
229
+ if (typeof b === "number") {
230
+ return a * b;
231
+ } else {
232
+ return new Point$1(-a * b.y, a * b.x);
233
+ }
234
+ } else {
235
+ if (typeof b === "number") {
236
+ return new Point$1(b * a.y, -b * a.x);
237
+ } else {
238
+ return a.x * b.y - a.y * b.x;
239
+ }
240
+ }
241
+ };
242
+ Point$1.toString = xy$1.toString;
243
+ Point$1.compare = xy$1.compare;
244
+ Point$1.cmp = xy$1.compare;
245
+ Point$1.equals = xy$1.equals;
246
+ Point$1.dot = function(a, b) {
247
+ return a.x * b.x + a.y * b.y;
248
+ };
249
+ var point = Point$1;
250
+ var xy = xy$3;
251
+ var Triangle$2 = function(a, b, c) {
252
+ this.points_ = [a, b, c];
253
+ this.neighbors_ = [null, null, null];
254
+ this.interior_ = false;
255
+ this.constrained_edge = [false, false, false];
256
+ this.delaunay_edge = [false, false, false];
257
+ };
258
+ var p2s = xy.toString;
259
+ Triangle$2.prototype.toString = function() {
260
+ return "[" + p2s(this.points_[0]) + p2s(this.points_[1]) + p2s(this.points_[2]) + "]";
261
+ };
262
+ Triangle$2.prototype.getPoint = function(index) {
263
+ return this.points_[index];
264
+ };
265
+ Triangle$2.prototype.GetPoint = Triangle$2.prototype.getPoint;
266
+ Triangle$2.prototype.getPoints = function() {
267
+ return this.points_;
268
+ };
269
+ Triangle$2.prototype.getNeighbor = function(index) {
270
+ return this.neighbors_[index];
271
+ };
272
+ Triangle$2.prototype.containsPoint = function(point2) {
273
+ var points = this.points_;
274
+ return point2 === points[0] || point2 === points[1] || point2 === points[2];
275
+ };
276
+ Triangle$2.prototype.containsEdge = function(edge) {
277
+ return this.containsPoint(edge.p) && this.containsPoint(edge.q);
278
+ };
279
+ Triangle$2.prototype.containsPoints = function(p1, p2) {
280
+ return this.containsPoint(p1) && this.containsPoint(p2);
281
+ };
282
+ Triangle$2.prototype.isInterior = function() {
283
+ return this.interior_;
284
+ };
285
+ Triangle$2.prototype.setInterior = function(interior) {
286
+ this.interior_ = interior;
287
+ return this;
288
+ };
289
+ Triangle$2.prototype.markNeighborPointers = function(p1, p2, t) {
290
+ var points = this.points_;
291
+ if (p1 === points[2] && p2 === points[1] || p1 === points[1] && p2 === points[2]) {
292
+ this.neighbors_[0] = t;
293
+ } else if (p1 === points[0] && p2 === points[2] || p1 === points[2] && p2 === points[0]) {
294
+ this.neighbors_[1] = t;
295
+ } else if (p1 === points[0] && p2 === points[1] || p1 === points[1] && p2 === points[0]) {
296
+ this.neighbors_[2] = t;
297
+ } else {
298
+ throw new Error("poly2tri Invalid Triangle.markNeighborPointers() call");
299
+ }
300
+ };
301
+ Triangle$2.prototype.markNeighbor = function(t) {
302
+ var points = this.points_;
303
+ if (t.containsPoints(points[1], points[2])) {
304
+ this.neighbors_[0] = t;
305
+ t.markNeighborPointers(points[1], points[2], this);
306
+ } else if (t.containsPoints(points[0], points[2])) {
307
+ this.neighbors_[1] = t;
308
+ t.markNeighborPointers(points[0], points[2], this);
309
+ } else if (t.containsPoints(points[0], points[1])) {
310
+ this.neighbors_[2] = t;
311
+ t.markNeighborPointers(points[0], points[1], this);
312
+ }
313
+ };
314
+ Triangle$2.prototype.clearNeighbors = function() {
315
+ this.neighbors_[0] = null;
316
+ this.neighbors_[1] = null;
317
+ this.neighbors_[2] = null;
318
+ };
319
+ Triangle$2.prototype.clearDelaunayEdges = function() {
320
+ this.delaunay_edge[0] = false;
321
+ this.delaunay_edge[1] = false;
322
+ this.delaunay_edge[2] = false;
323
+ };
324
+ Triangle$2.prototype.pointCW = function(p) {
325
+ var points = this.points_;
326
+ if (p === points[0]) {
327
+ return points[2];
328
+ } else if (p === points[1]) {
329
+ return points[0];
330
+ } else if (p === points[2]) {
331
+ return points[1];
332
+ } else {
333
+ return null;
334
+ }
335
+ };
336
+ Triangle$2.prototype.pointCCW = function(p) {
337
+ var points = this.points_;
338
+ if (p === points[0]) {
339
+ return points[1];
340
+ } else if (p === points[1]) {
341
+ return points[2];
342
+ } else if (p === points[2]) {
343
+ return points[0];
344
+ } else {
345
+ return null;
346
+ }
347
+ };
348
+ Triangle$2.prototype.neighborCW = function(p) {
349
+ if (p === this.points_[0]) {
350
+ return this.neighbors_[1];
351
+ } else if (p === this.points_[1]) {
352
+ return this.neighbors_[2];
353
+ } else {
354
+ return this.neighbors_[0];
355
+ }
356
+ };
357
+ Triangle$2.prototype.neighborCCW = function(p) {
358
+ if (p === this.points_[0]) {
359
+ return this.neighbors_[2];
360
+ } else if (p === this.points_[1]) {
361
+ return this.neighbors_[0];
362
+ } else {
363
+ return this.neighbors_[1];
364
+ }
365
+ };
366
+ Triangle$2.prototype.getConstrainedEdgeCW = function(p) {
367
+ if (p === this.points_[0]) {
368
+ return this.constrained_edge[1];
369
+ } else if (p === this.points_[1]) {
370
+ return this.constrained_edge[2];
371
+ } else {
372
+ return this.constrained_edge[0];
373
+ }
374
+ };
375
+ Triangle$2.prototype.getConstrainedEdgeCCW = function(p) {
376
+ if (p === this.points_[0]) {
377
+ return this.constrained_edge[2];
378
+ } else if (p === this.points_[1]) {
379
+ return this.constrained_edge[0];
380
+ } else {
381
+ return this.constrained_edge[1];
382
+ }
383
+ };
384
+ Triangle$2.prototype.getConstrainedEdgeAcross = function(p) {
385
+ if (p === this.points_[0]) {
386
+ return this.constrained_edge[0];
387
+ } else if (p === this.points_[1]) {
388
+ return this.constrained_edge[1];
389
+ } else {
390
+ return this.constrained_edge[2];
391
+ }
392
+ };
393
+ Triangle$2.prototype.setConstrainedEdgeCW = function(p, ce) {
394
+ if (p === this.points_[0]) {
395
+ this.constrained_edge[1] = ce;
396
+ } else if (p === this.points_[1]) {
397
+ this.constrained_edge[2] = ce;
398
+ } else {
399
+ this.constrained_edge[0] = ce;
400
+ }
401
+ };
402
+ Triangle$2.prototype.setConstrainedEdgeCCW = function(p, ce) {
403
+ if (p === this.points_[0]) {
404
+ this.constrained_edge[2] = ce;
405
+ } else if (p === this.points_[1]) {
406
+ this.constrained_edge[0] = ce;
407
+ } else {
408
+ this.constrained_edge[1] = ce;
409
+ }
410
+ };
411
+ Triangle$2.prototype.getDelaunayEdgeCW = function(p) {
412
+ if (p === this.points_[0]) {
413
+ return this.delaunay_edge[1];
414
+ } else if (p === this.points_[1]) {
415
+ return this.delaunay_edge[2];
416
+ } else {
417
+ return this.delaunay_edge[0];
418
+ }
419
+ };
420
+ Triangle$2.prototype.getDelaunayEdgeCCW = function(p) {
421
+ if (p === this.points_[0]) {
422
+ return this.delaunay_edge[2];
423
+ } else if (p === this.points_[1]) {
424
+ return this.delaunay_edge[0];
425
+ } else {
426
+ return this.delaunay_edge[1];
427
+ }
428
+ };
429
+ Triangle$2.prototype.setDelaunayEdgeCW = function(p, e) {
430
+ if (p === this.points_[0]) {
431
+ this.delaunay_edge[1] = e;
432
+ } else if (p === this.points_[1]) {
433
+ this.delaunay_edge[2] = e;
434
+ } else {
435
+ this.delaunay_edge[0] = e;
436
+ }
437
+ };
438
+ Triangle$2.prototype.setDelaunayEdgeCCW = function(p, e) {
439
+ if (p === this.points_[0]) {
440
+ this.delaunay_edge[2] = e;
441
+ } else if (p === this.points_[1]) {
442
+ this.delaunay_edge[0] = e;
443
+ } else {
444
+ this.delaunay_edge[1] = e;
445
+ }
446
+ };
447
+ Triangle$2.prototype.neighborAcross = function(p) {
448
+ if (p === this.points_[0]) {
449
+ return this.neighbors_[0];
450
+ } else if (p === this.points_[1]) {
451
+ return this.neighbors_[1];
452
+ } else {
453
+ return this.neighbors_[2];
454
+ }
455
+ };
456
+ Triangle$2.prototype.oppositePoint = function(t, p) {
457
+ var cw = t.pointCW(p);
458
+ return this.pointCW(cw);
459
+ };
460
+ Triangle$2.prototype.legalize = function(opoint, npoint) {
461
+ var points = this.points_;
462
+ if (opoint === points[0]) {
463
+ points[1] = points[0];
464
+ points[0] = points[2];
465
+ points[2] = npoint;
466
+ } else if (opoint === points[1]) {
467
+ points[2] = points[1];
468
+ points[1] = points[0];
469
+ points[0] = npoint;
470
+ } else if (opoint === points[2]) {
471
+ points[0] = points[2];
472
+ points[2] = points[1];
473
+ points[1] = npoint;
474
+ } else {
475
+ throw new Error("poly2tri Invalid Triangle.legalize() call");
476
+ }
477
+ };
478
+ Triangle$2.prototype.index = function(p) {
479
+ var points = this.points_;
480
+ if (p === points[0]) {
481
+ return 0;
482
+ } else if (p === points[1]) {
483
+ return 1;
484
+ } else if (p === points[2]) {
485
+ return 2;
486
+ } else {
487
+ throw new Error("poly2tri Invalid Triangle.index() call");
488
+ }
489
+ };
490
+ Triangle$2.prototype.edgeIndex = function(p1, p2) {
491
+ var points = this.points_;
492
+ if (p1 === points[0]) {
493
+ if (p2 === points[1]) {
494
+ return 2;
495
+ } else if (p2 === points[2]) {
496
+ return 1;
497
+ }
498
+ } else if (p1 === points[1]) {
499
+ if (p2 === points[2]) {
500
+ return 0;
501
+ } else if (p2 === points[0]) {
502
+ return 2;
503
+ }
504
+ } else if (p1 === points[2]) {
505
+ if (p2 === points[0]) {
506
+ return 1;
507
+ } else if (p2 === points[1]) {
508
+ return 0;
509
+ }
510
+ }
511
+ return -1;
512
+ };
513
+ Triangle$2.prototype.markConstrainedEdgeByIndex = function(index) {
514
+ this.constrained_edge[index] = true;
515
+ };
516
+ Triangle$2.prototype.markConstrainedEdgeByEdge = function(edge) {
517
+ this.markConstrainedEdgeByPoints(edge.p, edge.q);
518
+ };
519
+ Triangle$2.prototype.markConstrainedEdgeByPoints = function(p, q) {
520
+ var points = this.points_;
521
+ if (q === points[0] && p === points[1] || q === points[1] && p === points[0]) {
522
+ this.constrained_edge[2] = true;
523
+ } else if (q === points[0] && p === points[2] || q === points[2] && p === points[0]) {
524
+ this.constrained_edge[1] = true;
525
+ } else if (q === points[1] && p === points[2] || q === points[2] && p === points[1]) {
526
+ this.constrained_edge[0] = true;
527
+ }
528
+ };
529
+ var triangle = Triangle$2;
530
+ var sweep$1 = {};
531
+ function assert$1(condition, message) {
532
+ if (!condition) {
533
+ throw new Error(message || "Assert Failed");
534
+ }
535
+ }
536
+ var assert_1 = assert$1;
537
+ var advancingfront = { exports: {} };
538
+ var Node$2 = function(p, t) {
539
+ this.point = p;
540
+ this.triangle = t || null;
541
+ this.next = null;
542
+ this.prev = null;
543
+ this.value = p.x;
544
+ };
545
+ var AdvancingFront$1 = function(head, tail) {
546
+ this.head_ = head;
547
+ this.tail_ = tail;
548
+ this.search_node_ = head;
549
+ };
550
+ AdvancingFront$1.prototype.head = function() {
551
+ return this.head_;
552
+ };
553
+ AdvancingFront$1.prototype.setHead = function(node) {
554
+ this.head_ = node;
555
+ };
556
+ AdvancingFront$1.prototype.tail = function() {
557
+ return this.tail_;
558
+ };
559
+ AdvancingFront$1.prototype.setTail = function(node) {
560
+ this.tail_ = node;
561
+ };
562
+ AdvancingFront$1.prototype.search = function() {
563
+ return this.search_node_;
564
+ };
565
+ AdvancingFront$1.prototype.setSearch = function(node) {
566
+ this.search_node_ = node;
567
+ };
568
+ AdvancingFront$1.prototype.findSearchNode = function() {
569
+ return this.search_node_;
570
+ };
571
+ AdvancingFront$1.prototype.locateNode = function(x) {
572
+ var node = this.search_node_;
573
+ if (x < node.value) {
574
+ while (node = node.prev) {
575
+ if (x >= node.value) {
576
+ this.search_node_ = node;
577
+ return node;
578
+ }
579
+ }
580
+ } else {
581
+ while (node = node.next) {
582
+ if (x < node.value) {
583
+ this.search_node_ = node.prev;
584
+ return node.prev;
585
+ }
586
+ }
587
+ }
588
+ return null;
589
+ };
590
+ AdvancingFront$1.prototype.locatePoint = function(point2) {
591
+ var px = point2.x;
592
+ var node = this.findSearchNode(px);
593
+ var nx = node.point.x;
594
+ if (px === nx) {
595
+ if (point2 !== node.point) {
596
+ if (point2 === node.prev.point) {
597
+ node = node.prev;
598
+ } else if (point2 === node.next.point) {
599
+ node = node.next;
600
+ } else {
601
+ throw new Error("poly2tri Invalid AdvancingFront.locatePoint() call");
602
+ }
603
+ }
604
+ } else if (px < nx) {
605
+ while (node = node.prev) {
606
+ if (point2 === node.point) {
607
+ break;
608
+ }
609
+ }
610
+ } else {
611
+ while (node = node.next) {
612
+ if (point2 === node.point) {
613
+ break;
614
+ }
615
+ }
616
+ }
617
+ if (node) {
618
+ this.search_node_ = node;
619
+ }
620
+ return node;
621
+ };
622
+ advancingfront.exports = AdvancingFront$1;
623
+ advancingfront.exports.Node = Node$2;
624
+ var advancingfrontExports = advancingfront.exports;
625
+ var utils$1 = {};
626
+ var EPSILON$1 = 1e-12;
627
+ utils$1.EPSILON = EPSILON$1;
628
+ var Orientation$1 = {
629
+ "CW": 1,
630
+ "CCW": -1,
631
+ "COLLINEAR": 0
632
+ };
633
+ utils$1.Orientation = Orientation$1;
634
+ function orient2d$1(pa, pb, pc) {
635
+ var detleft = (pa.x - pc.x) * (pb.y - pc.y);
636
+ var detright = (pa.y - pc.y) * (pb.x - pc.x);
637
+ var val = detleft - detright;
638
+ if (val > -EPSILON$1 && val < EPSILON$1) {
639
+ return Orientation$1.COLLINEAR;
640
+ } else if (val > 0) {
641
+ return Orientation$1.CCW;
642
+ } else {
643
+ return Orientation$1.CW;
644
+ }
645
+ }
646
+ utils$1.orient2d = orient2d$1;
647
+ function inScanArea$1(pa, pb, pc, pd) {
648
+ var oadb = (pa.x - pb.x) * (pd.y - pb.y) - (pd.x - pb.x) * (pa.y - pb.y);
649
+ if (oadb >= -EPSILON$1) {
650
+ return false;
651
+ }
652
+ var oadc = (pa.x - pc.x) * (pd.y - pc.y) - (pd.x - pc.x) * (pa.y - pc.y);
653
+ if (oadc <= EPSILON$1) {
654
+ return false;
655
+ }
656
+ return true;
657
+ }
658
+ utils$1.inScanArea = inScanArea$1;
659
+ function isAngleObtuse$1(pa, pb, pc) {
660
+ var ax = pb.x - pa.x;
661
+ var ay = pb.y - pa.y;
662
+ var bx = pc.x - pa.x;
663
+ var by = pc.y - pa.y;
664
+ return ax * bx + ay * by < 0;
665
+ }
666
+ utils$1.isAngleObtuse = isAngleObtuse$1;
667
+ var assert = assert_1;
668
+ var PointError$1 = pointerror;
669
+ var Triangle$1 = triangle;
670
+ var Node$1 = advancingfrontExports.Node;
671
+ var utils = utils$1;
672
+ var EPSILON = utils.EPSILON;
673
+ var Orientation = utils.Orientation;
674
+ var orient2d = utils.orient2d;
675
+ var inScanArea = utils.inScanArea;
676
+ var isAngleObtuse = utils.isAngleObtuse;
677
+ function triangulate(tcx) {
678
+ tcx.initTriangulation();
679
+ tcx.createAdvancingFront();
680
+ sweepPoints(tcx);
681
+ finalizationPolygon(tcx);
682
+ }
683
+ function sweepPoints(tcx) {
684
+ var i, len = tcx.pointCount();
685
+ for (i = 1; i < len; ++i) {
686
+ var point2 = tcx.getPoint(i);
687
+ var node = pointEvent(tcx, point2);
688
+ var edges = point2._p2t_edge_list;
689
+ for (var j = 0; edges && j < edges.length; ++j) {
690
+ edgeEventByEdge(tcx, edges[j], node);
691
+ }
692
+ }
693
+ }
694
+ function finalizationPolygon(tcx) {
695
+ var t = tcx.front().head().next.triangle;
696
+ var p = tcx.front().head().next.point;
697
+ while (!t.getConstrainedEdgeCW(p)) {
698
+ t = t.neighborCCW(p);
699
+ }
700
+ tcx.meshClean(t);
701
+ }
702
+ function pointEvent(tcx, point2) {
703
+ var node = tcx.locateNode(point2);
704
+ var new_node = newFrontTriangle(tcx, point2, node);
705
+ if (point2.x <= node.point.x + EPSILON) {
706
+ fill(tcx, node);
707
+ }
708
+ fillAdvancingFront(tcx, new_node);
709
+ return new_node;
710
+ }
711
+ function edgeEventByEdge(tcx, edge, node) {
712
+ tcx.edge_event.constrained_edge = edge;
713
+ tcx.edge_event.right = edge.p.x > edge.q.x;
714
+ if (isEdgeSideOfTriangle(node.triangle, edge.p, edge.q)) {
715
+ return;
716
+ }
717
+ fillEdgeEvent(tcx, edge, node);
718
+ edgeEventByPoints(tcx, edge.p, edge.q, node.triangle, edge.q);
719
+ }
720
+ function edgeEventByPoints(tcx, ep, eq, triangle2, point2) {
721
+ if (isEdgeSideOfTriangle(triangle2, ep, eq)) {
722
+ return;
723
+ }
724
+ var p1 = triangle2.pointCCW(point2);
725
+ var o1 = orient2d(eq, p1, ep);
726
+ if (o1 === Orientation.COLLINEAR) {
727
+ throw new PointError$1("poly2tri EdgeEvent: Collinear not supported!", [eq, p1, ep]);
728
+ }
729
+ var p2 = triangle2.pointCW(point2);
730
+ var o2 = orient2d(eq, p2, ep);
731
+ if (o2 === Orientation.COLLINEAR) {
732
+ throw new PointError$1("poly2tri EdgeEvent: Collinear not supported!", [eq, p2, ep]);
733
+ }
734
+ if (o1 === o2) {
735
+ if (o1 === Orientation.CW) {
736
+ triangle2 = triangle2.neighborCCW(point2);
737
+ } else {
738
+ triangle2 = triangle2.neighborCW(point2);
739
+ }
740
+ edgeEventByPoints(tcx, ep, eq, triangle2, point2);
741
+ } else {
742
+ flipEdgeEvent(tcx, ep, eq, triangle2, point2);
743
+ }
744
+ }
745
+ function isEdgeSideOfTriangle(triangle2, ep, eq) {
746
+ var index = triangle2.edgeIndex(ep, eq);
747
+ if (index !== -1) {
748
+ triangle2.markConstrainedEdgeByIndex(index);
749
+ var t = triangle2.getNeighbor(index);
750
+ if (t) {
751
+ t.markConstrainedEdgeByPoints(ep, eq);
752
+ }
753
+ return true;
754
+ }
755
+ return false;
756
+ }
757
+ function newFrontTriangle(tcx, point2, node) {
758
+ var triangle2 = new Triangle$1(point2, node.point, node.next.point);
759
+ triangle2.markNeighbor(node.triangle);
760
+ tcx.addToMap(triangle2);
761
+ var new_node = new Node$1(point2);
762
+ new_node.next = node.next;
763
+ new_node.prev = node;
764
+ node.next.prev = new_node;
765
+ node.next = new_node;
766
+ if (!legalize(tcx, triangle2)) {
767
+ tcx.mapTriangleToNodes(triangle2);
768
+ }
769
+ return new_node;
770
+ }
771
+ function fill(tcx, node) {
772
+ var triangle2 = new Triangle$1(node.prev.point, node.point, node.next.point);
773
+ triangle2.markNeighbor(node.prev.triangle);
774
+ triangle2.markNeighbor(node.triangle);
775
+ tcx.addToMap(triangle2);
776
+ node.prev.next = node.next;
777
+ node.next.prev = node.prev;
778
+ if (!legalize(tcx, triangle2)) {
779
+ tcx.mapTriangleToNodes(triangle2);
780
+ }
781
+ }
782
+ function fillAdvancingFront(tcx, n) {
783
+ var node = n.next;
784
+ while (node.next) {
785
+ if (isAngleObtuse(node.point, node.next.point, node.prev.point)) {
786
+ break;
787
+ }
788
+ fill(tcx, node);
789
+ node = node.next;
790
+ }
791
+ node = n.prev;
792
+ while (node.prev) {
793
+ if (isAngleObtuse(node.point, node.next.point, node.prev.point)) {
794
+ break;
795
+ }
796
+ fill(tcx, node);
797
+ node = node.prev;
798
+ }
799
+ if (n.next && n.next.next) {
800
+ if (isBasinAngleRight(n)) {
801
+ fillBasin(tcx, n);
802
+ }
803
+ }
804
+ }
805
+ function isBasinAngleRight(node) {
806
+ var ax = node.point.x - node.next.next.point.x;
807
+ var ay = node.point.y - node.next.next.point.y;
808
+ assert(ay >= 0, "unordered y");
809
+ return ax >= 0 || Math.abs(ax) < ay;
810
+ }
811
+ function legalize(tcx, t) {
812
+ for (var i = 0; i < 3; ++i) {
813
+ if (t.delaunay_edge[i]) {
814
+ continue;
815
+ }
816
+ var ot = t.getNeighbor(i);
817
+ if (ot) {
818
+ var p = t.getPoint(i);
819
+ var op = ot.oppositePoint(t, p);
820
+ var oi = ot.index(op);
821
+ if (ot.constrained_edge[oi] || ot.delaunay_edge[oi]) {
822
+ t.constrained_edge[i] = ot.constrained_edge[oi];
823
+ continue;
824
+ }
825
+ var inside = inCircle(p, t.pointCCW(p), t.pointCW(p), op);
826
+ if (inside) {
827
+ t.delaunay_edge[i] = true;
828
+ ot.delaunay_edge[oi] = true;
829
+ rotateTrianglePair(t, p, ot, op);
830
+ var not_legalized = !legalize(tcx, t);
831
+ if (not_legalized) {
832
+ tcx.mapTriangleToNodes(t);
833
+ }
834
+ not_legalized = !legalize(tcx, ot);
835
+ if (not_legalized) {
836
+ tcx.mapTriangleToNodes(ot);
837
+ }
838
+ t.delaunay_edge[i] = false;
839
+ ot.delaunay_edge[oi] = false;
840
+ return true;
841
+ }
842
+ }
843
+ }
844
+ return false;
845
+ }
846
+ function inCircle(pa, pb, pc, pd) {
847
+ var adx = pa.x - pd.x;
848
+ var ady = pa.y - pd.y;
849
+ var bdx = pb.x - pd.x;
850
+ var bdy = pb.y - pd.y;
851
+ var adxbdy = adx * bdy;
852
+ var bdxady = bdx * ady;
853
+ var oabd = adxbdy - bdxady;
854
+ if (oabd <= 0) {
855
+ return false;
856
+ }
857
+ var cdx = pc.x - pd.x;
858
+ var cdy = pc.y - pd.y;
859
+ var cdxady = cdx * ady;
860
+ var adxcdy = adx * cdy;
861
+ var ocad = cdxady - adxcdy;
862
+ if (ocad <= 0) {
863
+ return false;
864
+ }
865
+ var bdxcdy = bdx * cdy;
866
+ var cdxbdy = cdx * bdy;
867
+ var alift = adx * adx + ady * ady;
868
+ var blift = bdx * bdx + bdy * bdy;
869
+ var clift = cdx * cdx + cdy * cdy;
870
+ var det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
871
+ return det > 0;
872
+ }
873
+ function rotateTrianglePair(t, p, ot, op) {
874
+ var n1, n2, n3, n4;
875
+ n1 = t.neighborCCW(p);
876
+ n2 = t.neighborCW(p);
877
+ n3 = ot.neighborCCW(op);
878
+ n4 = ot.neighborCW(op);
879
+ var ce1, ce2, ce3, ce4;
880
+ ce1 = t.getConstrainedEdgeCCW(p);
881
+ ce2 = t.getConstrainedEdgeCW(p);
882
+ ce3 = ot.getConstrainedEdgeCCW(op);
883
+ ce4 = ot.getConstrainedEdgeCW(op);
884
+ var de1, de2, de3, de4;
885
+ de1 = t.getDelaunayEdgeCCW(p);
886
+ de2 = t.getDelaunayEdgeCW(p);
887
+ de3 = ot.getDelaunayEdgeCCW(op);
888
+ de4 = ot.getDelaunayEdgeCW(op);
889
+ t.legalize(p, op);
890
+ ot.legalize(op, p);
891
+ ot.setDelaunayEdgeCCW(p, de1);
892
+ t.setDelaunayEdgeCW(p, de2);
893
+ t.setDelaunayEdgeCCW(op, de3);
894
+ ot.setDelaunayEdgeCW(op, de4);
895
+ ot.setConstrainedEdgeCCW(p, ce1);
896
+ t.setConstrainedEdgeCW(p, ce2);
897
+ t.setConstrainedEdgeCCW(op, ce3);
898
+ ot.setConstrainedEdgeCW(op, ce4);
899
+ t.clearNeighbors();
900
+ ot.clearNeighbors();
901
+ if (n1) {
902
+ ot.markNeighbor(n1);
903
+ }
904
+ if (n2) {
905
+ t.markNeighbor(n2);
906
+ }
907
+ if (n3) {
908
+ t.markNeighbor(n3);
909
+ }
910
+ if (n4) {
911
+ ot.markNeighbor(n4);
912
+ }
913
+ t.markNeighbor(ot);
914
+ }
915
+ function fillBasin(tcx, node) {
916
+ if (orient2d(node.point, node.next.point, node.next.next.point) === Orientation.CCW) {
917
+ tcx.basin.left_node = node.next.next;
918
+ } else {
919
+ tcx.basin.left_node = node.next;
920
+ }
921
+ tcx.basin.bottom_node = tcx.basin.left_node;
922
+ while (tcx.basin.bottom_node.next && tcx.basin.bottom_node.point.y >= tcx.basin.bottom_node.next.point.y) {
923
+ tcx.basin.bottom_node = tcx.basin.bottom_node.next;
924
+ }
925
+ if (tcx.basin.bottom_node === tcx.basin.left_node) {
926
+ return;
927
+ }
928
+ tcx.basin.right_node = tcx.basin.bottom_node;
929
+ while (tcx.basin.right_node.next && tcx.basin.right_node.point.y < tcx.basin.right_node.next.point.y) {
930
+ tcx.basin.right_node = tcx.basin.right_node.next;
931
+ }
932
+ if (tcx.basin.right_node === tcx.basin.bottom_node) {
933
+ return;
934
+ }
935
+ tcx.basin.width = tcx.basin.right_node.point.x - tcx.basin.left_node.point.x;
936
+ tcx.basin.left_highest = tcx.basin.left_node.point.y > tcx.basin.right_node.point.y;
937
+ fillBasinReq(tcx, tcx.basin.bottom_node);
938
+ }
939
+ function fillBasinReq(tcx, node) {
940
+ if (isShallow(tcx, node)) {
941
+ return;
942
+ }
943
+ fill(tcx, node);
944
+ var o;
945
+ if (node.prev === tcx.basin.left_node && node.next === tcx.basin.right_node) {
946
+ return;
947
+ } else if (node.prev === tcx.basin.left_node) {
948
+ o = orient2d(node.point, node.next.point, node.next.next.point);
949
+ if (o === Orientation.CW) {
950
+ return;
951
+ }
952
+ node = node.next;
953
+ } else if (node.next === tcx.basin.right_node) {
954
+ o = orient2d(node.point, node.prev.point, node.prev.prev.point);
955
+ if (o === Orientation.CCW) {
956
+ return;
957
+ }
958
+ node = node.prev;
959
+ } else {
960
+ if (node.prev.point.y < node.next.point.y) {
961
+ node = node.prev;
962
+ } else {
963
+ node = node.next;
964
+ }
965
+ }
966
+ fillBasinReq(tcx, node);
967
+ }
968
+ function isShallow(tcx, node) {
969
+ var height;
970
+ if (tcx.basin.left_highest) {
971
+ height = tcx.basin.left_node.point.y - node.point.y;
972
+ } else {
973
+ height = tcx.basin.right_node.point.y - node.point.y;
974
+ }
975
+ if (tcx.basin.width > height) {
976
+ return true;
977
+ }
978
+ return false;
979
+ }
980
+ function fillEdgeEvent(tcx, edge, node) {
981
+ if (tcx.edge_event.right) {
982
+ fillRightAboveEdgeEvent(tcx, edge, node);
983
+ } else {
984
+ fillLeftAboveEdgeEvent(tcx, edge, node);
985
+ }
986
+ }
987
+ function fillRightAboveEdgeEvent(tcx, edge, node) {
988
+ while (node.next.point.x < edge.p.x) {
989
+ if (orient2d(edge.q, node.next.point, edge.p) === Orientation.CCW) {
990
+ fillRightBelowEdgeEvent(tcx, edge, node);
991
+ } else {
992
+ node = node.next;
993
+ }
994
+ }
995
+ }
996
+ function fillRightBelowEdgeEvent(tcx, edge, node) {
997
+ if (node.point.x < edge.p.x) {
998
+ if (orient2d(node.point, node.next.point, node.next.next.point) === Orientation.CCW) {
999
+ fillRightConcaveEdgeEvent(tcx, edge, node);
1000
+ } else {
1001
+ fillRightConvexEdgeEvent(tcx, edge, node);
1002
+ fillRightBelowEdgeEvent(tcx, edge, node);
1003
+ }
1004
+ }
1005
+ }
1006
+ function fillRightConcaveEdgeEvent(tcx, edge, node) {
1007
+ fill(tcx, node.next);
1008
+ if (node.next.point !== edge.p) {
1009
+ if (orient2d(edge.q, node.next.point, edge.p) === Orientation.CCW) {
1010
+ if (orient2d(node.point, node.next.point, node.next.next.point) === Orientation.CCW) {
1011
+ fillRightConcaveEdgeEvent(tcx, edge, node);
1012
+ }
1013
+ }
1014
+ }
1015
+ }
1016
+ function fillRightConvexEdgeEvent(tcx, edge, node) {
1017
+ if (orient2d(node.next.point, node.next.next.point, node.next.next.next.point) === Orientation.CCW) {
1018
+ fillRightConcaveEdgeEvent(tcx, edge, node.next);
1019
+ } else {
1020
+ if (orient2d(edge.q, node.next.next.point, edge.p) === Orientation.CCW) {
1021
+ fillRightConvexEdgeEvent(tcx, edge, node.next);
1022
+ }
1023
+ }
1024
+ }
1025
+ function fillLeftAboveEdgeEvent(tcx, edge, node) {
1026
+ while (node.prev.point.x > edge.p.x) {
1027
+ if (orient2d(edge.q, node.prev.point, edge.p) === Orientation.CW) {
1028
+ fillLeftBelowEdgeEvent(tcx, edge, node);
1029
+ } else {
1030
+ node = node.prev;
1031
+ }
1032
+ }
1033
+ }
1034
+ function fillLeftBelowEdgeEvent(tcx, edge, node) {
1035
+ if (node.point.x > edge.p.x) {
1036
+ if (orient2d(node.point, node.prev.point, node.prev.prev.point) === Orientation.CW) {
1037
+ fillLeftConcaveEdgeEvent(tcx, edge, node);
1038
+ } else {
1039
+ fillLeftConvexEdgeEvent(tcx, edge, node);
1040
+ fillLeftBelowEdgeEvent(tcx, edge, node);
1041
+ }
1042
+ }
1043
+ }
1044
+ function fillLeftConvexEdgeEvent(tcx, edge, node) {
1045
+ if (orient2d(node.prev.point, node.prev.prev.point, node.prev.prev.prev.point) === Orientation.CW) {
1046
+ fillLeftConcaveEdgeEvent(tcx, edge, node.prev);
1047
+ } else {
1048
+ if (orient2d(edge.q, node.prev.prev.point, edge.p) === Orientation.CW) {
1049
+ fillLeftConvexEdgeEvent(tcx, edge, node.prev);
1050
+ }
1051
+ }
1052
+ }
1053
+ function fillLeftConcaveEdgeEvent(tcx, edge, node) {
1054
+ fill(tcx, node.prev);
1055
+ if (node.prev.point !== edge.p) {
1056
+ if (orient2d(edge.q, node.prev.point, edge.p) === Orientation.CW) {
1057
+ if (orient2d(node.point, node.prev.point, node.prev.prev.point) === Orientation.CW) {
1058
+ fillLeftConcaveEdgeEvent(tcx, edge, node);
1059
+ }
1060
+ }
1061
+ }
1062
+ }
1063
+ function flipEdgeEvent(tcx, ep, eq, t, p) {
1064
+ var ot = t.neighborAcross(p);
1065
+ assert(ot, "FLIP failed due to missing triangle!");
1066
+ var op = ot.oppositePoint(t, p);
1067
+ if (t.getConstrainedEdgeAcross(p)) {
1068
+ var index = t.index(p);
1069
+ throw new PointError$1(
1070
+ "poly2tri Intersecting Constraints",
1071
+ [p, op, t.getPoint((index + 1) % 3), t.getPoint((index + 2) % 3)]
1072
+ );
1073
+ }
1074
+ if (inScanArea(p, t.pointCCW(p), t.pointCW(p), op)) {
1075
+ rotateTrianglePair(t, p, ot, op);
1076
+ tcx.mapTriangleToNodes(t);
1077
+ tcx.mapTriangleToNodes(ot);
1078
+ if (p === eq && op === ep) {
1079
+ if (eq === tcx.edge_event.constrained_edge.q && ep === tcx.edge_event.constrained_edge.p) {
1080
+ t.markConstrainedEdgeByPoints(ep, eq);
1081
+ ot.markConstrainedEdgeByPoints(ep, eq);
1082
+ legalize(tcx, t);
1083
+ legalize(tcx, ot);
1084
+ }
1085
+ } else {
1086
+ var o = orient2d(eq, op, ep);
1087
+ t = nextFlipTriangle(tcx, o, t, ot, p, op);
1088
+ flipEdgeEvent(tcx, ep, eq, t, p);
1089
+ }
1090
+ } else {
1091
+ var newP = nextFlipPoint(ep, eq, ot, op);
1092
+ flipScanEdgeEvent(tcx, ep, eq, t, ot, newP);
1093
+ edgeEventByPoints(tcx, ep, eq, t, p);
1094
+ }
1095
+ }
1096
+ function nextFlipTriangle(tcx, o, t, ot, p, op) {
1097
+ var edge_index;
1098
+ if (o === Orientation.CCW) {
1099
+ edge_index = ot.edgeIndex(p, op);
1100
+ ot.delaunay_edge[edge_index] = true;
1101
+ legalize(tcx, ot);
1102
+ ot.clearDelaunayEdges();
1103
+ return t;
1104
+ }
1105
+ edge_index = t.edgeIndex(p, op);
1106
+ t.delaunay_edge[edge_index] = true;
1107
+ legalize(tcx, t);
1108
+ t.clearDelaunayEdges();
1109
+ return ot;
1110
+ }
1111
+ function nextFlipPoint(ep, eq, ot, op) {
1112
+ var o2d = orient2d(eq, op, ep);
1113
+ if (o2d === Orientation.CW) {
1114
+ return ot.pointCCW(op);
1115
+ } else if (o2d === Orientation.CCW) {
1116
+ return ot.pointCW(op);
1117
+ } else {
1118
+ throw new PointError$1("poly2tri [Unsupported] nextFlipPoint: opposing point on constrained edge!", [eq, op, ep]);
1119
+ }
1120
+ }
1121
+ function flipScanEdgeEvent(tcx, ep, eq, flip_triangle, t, p) {
1122
+ var ot = t.neighborAcross(p);
1123
+ assert(ot, "FLIP failed due to missing triangle");
1124
+ var op = ot.oppositePoint(t, p);
1125
+ if (inScanArea(eq, flip_triangle.pointCCW(eq), flip_triangle.pointCW(eq), op)) {
1126
+ flipEdgeEvent(tcx, eq, op, ot, op);
1127
+ } else {
1128
+ var newP = nextFlipPoint(ep, eq, ot, op);
1129
+ flipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP);
1130
+ }
1131
+ }
1132
+ sweep$1.triangulate = triangulate;
1133
+ var PointError = pointerror;
1134
+ var Point = point;
1135
+ var Triangle = triangle;
1136
+ var sweep = sweep$1;
1137
+ var AdvancingFront = advancingfrontExports;
1138
+ var Node = AdvancingFront.Node;
1139
+ var kAlpha = 0.3;
1140
+ var Edge = function(p1, p2) {
1141
+ this.p = p1;
1142
+ this.q = p2;
1143
+ if (p1.y > p2.y) {
1144
+ this.q = p1;
1145
+ this.p = p2;
1146
+ } else if (p1.y === p2.y) {
1147
+ if (p1.x > p2.x) {
1148
+ this.q = p1;
1149
+ this.p = p2;
1150
+ } else if (p1.x === p2.x) {
1151
+ throw new PointError("poly2tri Invalid Edge constructor: repeated points!", [p1]);
1152
+ }
1153
+ }
1154
+ if (!this.q._p2t_edge_list) {
1155
+ this.q._p2t_edge_list = [];
1156
+ }
1157
+ this.q._p2t_edge_list.push(this);
1158
+ };
1159
+ var Basin = function() {
1160
+ this.left_node = null;
1161
+ this.bottom_node = null;
1162
+ this.right_node = null;
1163
+ this.width = 0;
1164
+ this.left_highest = false;
1165
+ };
1166
+ Basin.prototype.clear = function() {
1167
+ this.left_node = null;
1168
+ this.bottom_node = null;
1169
+ this.right_node = null;
1170
+ this.width = 0;
1171
+ this.left_highest = false;
1172
+ };
1173
+ var EdgeEvent = function() {
1174
+ this.constrained_edge = null;
1175
+ this.right = false;
1176
+ };
1177
+ var SweepContext = function(contour, options) {
1178
+ options = options || {};
1179
+ this.triangles_ = [];
1180
+ this.map_ = [];
1181
+ this.points_ = options.cloneArrays ? contour.slice(0) : contour;
1182
+ this.edge_list = [];
1183
+ this.pmin_ = this.pmax_ = null;
1184
+ this.front_ = null;
1185
+ this.head_ = null;
1186
+ this.tail_ = null;
1187
+ this.af_head_ = null;
1188
+ this.af_middle_ = null;
1189
+ this.af_tail_ = null;
1190
+ this.basin = new Basin();
1191
+ this.edge_event = new EdgeEvent();
1192
+ this.initEdges(this.points_);
1193
+ };
1194
+ SweepContext.prototype.addHole = function(polyline) {
1195
+ this.initEdges(polyline);
1196
+ var i, len = polyline.length;
1197
+ for (i = 0; i < len; i++) {
1198
+ this.points_.push(polyline[i]);
1199
+ }
1200
+ return this;
1201
+ };
1202
+ SweepContext.prototype.AddHole = SweepContext.prototype.addHole;
1203
+ SweepContext.prototype.addHoles = function(holes) {
1204
+ var i, len = holes.length;
1205
+ for (i = 0; i < len; i++) {
1206
+ this.initEdges(holes[i]);
1207
+ }
1208
+ this.points_ = this.points_.concat.apply(this.points_, holes);
1209
+ return this;
1210
+ };
1211
+ SweepContext.prototype.addPoint = function(point2) {
1212
+ this.points_.push(point2);
1213
+ return this;
1214
+ };
1215
+ SweepContext.prototype.AddPoint = SweepContext.prototype.addPoint;
1216
+ SweepContext.prototype.addPoints = function(points) {
1217
+ this.points_ = this.points_.concat(points);
1218
+ return this;
1219
+ };
1220
+ SweepContext.prototype.triangulate = function() {
1221
+ sweep.triangulate(this);
1222
+ return this;
1223
+ };
1224
+ SweepContext.prototype.getBoundingBox = function() {
1225
+ return { min: this.pmin_, max: this.pmax_ };
1226
+ };
1227
+ SweepContext.prototype.getTriangles = function() {
1228
+ return this.triangles_;
1229
+ };
1230
+ SweepContext.prototype.GetTriangles = SweepContext.prototype.getTriangles;
1231
+ SweepContext.prototype.front = function() {
1232
+ return this.front_;
1233
+ };
1234
+ SweepContext.prototype.pointCount = function() {
1235
+ return this.points_.length;
1236
+ };
1237
+ SweepContext.prototype.head = function() {
1238
+ return this.head_;
1239
+ };
1240
+ SweepContext.prototype.setHead = function(p1) {
1241
+ this.head_ = p1;
1242
+ };
1243
+ SweepContext.prototype.tail = function() {
1244
+ return this.tail_;
1245
+ };
1246
+ SweepContext.prototype.setTail = function(p1) {
1247
+ this.tail_ = p1;
1248
+ };
1249
+ SweepContext.prototype.getMap = function() {
1250
+ return this.map_;
1251
+ };
1252
+ SweepContext.prototype.initTriangulation = function() {
1253
+ var xmax = this.points_[0].x;
1254
+ var xmin = this.points_[0].x;
1255
+ var ymax = this.points_[0].y;
1256
+ var ymin = this.points_[0].y;
1257
+ var i, len = this.points_.length;
1258
+ for (i = 1; i < len; i++) {
1259
+ var p = this.points_[i];
1260
+ p.x > xmax && (xmax = p.x);
1261
+ p.x < xmin && (xmin = p.x);
1262
+ p.y > ymax && (ymax = p.y);
1263
+ p.y < ymin && (ymin = p.y);
1264
+ }
1265
+ this.pmin_ = new Point(xmin, ymin);
1266
+ this.pmax_ = new Point(xmax, ymax);
1267
+ var dx = kAlpha * (xmax - xmin);
1268
+ var dy = kAlpha * (ymax - ymin);
1269
+ this.head_ = new Point(xmax + dx, ymin - dy);
1270
+ this.tail_ = new Point(xmin - dx, ymin - dy);
1271
+ this.points_.sort(Point.compare);
1272
+ };
1273
+ SweepContext.prototype.initEdges = function(polyline) {
1274
+ var i, len = polyline.length;
1275
+ for (i = 0; i < len; ++i) {
1276
+ this.edge_list.push(new Edge(polyline[i], polyline[(i + 1) % len]));
1277
+ }
1278
+ };
1279
+ SweepContext.prototype.getPoint = function(index) {
1280
+ return this.points_[index];
1281
+ };
1282
+ SweepContext.prototype.addToMap = function(triangle2) {
1283
+ this.map_.push(triangle2);
1284
+ };
1285
+ SweepContext.prototype.locateNode = function(point2) {
1286
+ return this.front_.locateNode(point2.x);
1287
+ };
1288
+ SweepContext.prototype.createAdvancingFront = function() {
1289
+ var head;
1290
+ var middle;
1291
+ var tail;
1292
+ var triangle2 = new Triangle(this.points_[0], this.tail_, this.head_);
1293
+ this.map_.push(triangle2);
1294
+ head = new Node(triangle2.getPoint(1), triangle2);
1295
+ middle = new Node(triangle2.getPoint(0), triangle2);
1296
+ tail = new Node(triangle2.getPoint(2));
1297
+ this.front_ = new AdvancingFront(head, tail);
1298
+ head.next = middle;
1299
+ middle.next = tail;
1300
+ middle.prev = head;
1301
+ tail.prev = middle;
1302
+ };
1303
+ SweepContext.prototype.removeNode = function(node) {
1304
+ };
1305
+ SweepContext.prototype.mapTriangleToNodes = function(t) {
1306
+ for (var i = 0; i < 3; ++i) {
1307
+ if (!t.getNeighbor(i)) {
1308
+ var n = this.front_.locatePoint(t.pointCW(t.getPoint(i)));
1309
+ if (n) {
1310
+ n.triangle = t;
1311
+ }
1312
+ }
1313
+ }
1314
+ };
1315
+ SweepContext.prototype.removeFromMap = function(triangle2) {
1316
+ var i, map = this.map_, len = map.length;
1317
+ for (i = 0; i < len; i++) {
1318
+ if (map[i] === triangle2) {
1319
+ map.splice(i, 1);
1320
+ break;
1321
+ }
1322
+ }
1323
+ };
1324
+ SweepContext.prototype.meshClean = function(triangle2) {
1325
+ var triangles = [triangle2], t, i;
1326
+ while (t = triangles.pop()) {
1327
+ if (!t.isInterior()) {
1328
+ t.setInterior(true);
1329
+ this.triangles_.push(t);
1330
+ for (i = 0; i < 3; i++) {
1331
+ if (!t.constrained_edge[i]) {
1332
+ triangles.push(t.getNeighbor(i));
1333
+ }
1334
+ }
1335
+ }
1336
+ }
1337
+ };
1338
+ var sweepcontext = SweepContext;
1339
+ (function(exports$1) {
1340
+ var previousPoly2tri = commonjsGlobal.poly2tri;
1341
+ exports$1.noConflict = function() {
1342
+ commonjsGlobal.poly2tri = previousPoly2tri;
1343
+ return exports$1;
1344
+ };
1345
+ exports$1.VERSION = require$$0.version;
1346
+ exports$1.PointError = pointerror;
1347
+ exports$1.Point = point;
1348
+ exports$1.Triangle = triangle;
1349
+ exports$1.SweepContext = sweepcontext;
1350
+ var sweep2 = sweep$1;
1351
+ exports$1.triangulate = sweep2.triangulate;
1352
+ exports$1.sweep = { Triangulate: sweep2.triangulate };
1353
+ })(poly2tri);
1354
+ function pointInPolygon(px, py, polygon) {
1355
+ let inside = false;
1356
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
1357
+ const xi = polygon[i].x;
1358
+ const yi = polygon[i].y;
1359
+ const xj = polygon[j].x;
1360
+ const yj = polygon[j].y;
1361
+ if (yi > py !== yj > py && px < (xj - xi) * (py - yi) / (yj - yi) + xi) {
1362
+ inside = !inside;
1363
+ }
1364
+ }
1365
+ return inside;
1366
+ }
1367
+ function distToSegment(px, py, a, b) {
1368
+ const dx = b.x - a.x;
1369
+ const dy = b.y - a.y;
1370
+ const lenSq = dx * dx + dy * dy;
1371
+ if (lenSq === 0) return Math.hypot(px - a.x, py - a.y);
1372
+ const t = Math.max(0, Math.min(1, ((px - a.x) * dx + (py - a.y) * dy) / lenSq));
1373
+ return Math.hypot(px - (a.x + t * dx), py - (a.y + t * dy));
1374
+ }
1375
+ function generateSteinerPoints(polygon, density, bounds, rand) {
1376
+ const { minX, minY, maxX, maxY } = bounds;
1377
+ const maxDim = Math.max(maxX - minX, maxY - minY);
1378
+ const spacing = maxDim / (density + 1);
1379
+ const margin = spacing * 0.5;
1380
+ const steiners = [];
1381
+ for (let x = minX + margin; x < maxX - margin * 0.5; x += spacing) {
1382
+ for (let y = minY + margin; y < maxY - margin * 0.5; y += spacing) {
1383
+ if (!pointInPolygon(x, y, polygon)) continue;
1384
+ let tooClose = false;
1385
+ for (let i = 0; i < polygon.length; i++) {
1386
+ const j = (i + 1) % polygon.length;
1387
+ if (distToSegment(x, y, polygon[i], polygon[j]) < spacing * 0.15) {
1388
+ tooClose = true;
1389
+ break;
1390
+ }
1391
+ }
1392
+ if (!tooClose) {
1393
+ const jx = (rand() - 0.5) * spacing * 0.05;
1394
+ const jy = (rand() - 0.5) * spacing * 0.05;
1395
+ steiners.push({ x: x + jx, y: y + jy });
1396
+ }
1397
+ }
1398
+ }
1399
+ return steiners;
1400
+ }
1401
+ function mulberry32(seed) {
1402
+ let s = seed | 0;
1403
+ return function() {
1404
+ s = s + 1831565813 | 0;
1405
+ let t = Math.imul(s ^ s >>> 15, 1 | s);
1406
+ t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
1407
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
1408
+ };
1409
+ }
1410
+ function triangulateCap(boundaryPoints, density, bounds) {
1411
+ const seed = Math.round(
1412
+ Math.abs(bounds.maxX - bounds.minX) * 1e3 + Math.abs(bounds.maxY - bounds.minY) * 1e3
1413
+ );
1414
+ const rand = mulberry32(seed);
1415
+ const attempt = (withSteiners) => {
1416
+ try {
1417
+ const contour = boundaryPoints.map((p) => new poly2tri.Point(p.x, p.y));
1418
+ const swctx = new poly2tri.SweepContext(contour);
1419
+ if (withSteiners && density > 1) {
1420
+ const steiners = generateSteinerPoints(boundaryPoints, density, bounds, rand);
1421
+ for (const s of steiners) {
1422
+ swctx.addPoint(new poly2tri.Point(s.x, s.y));
1423
+ }
1424
+ }
1425
+ swctx.triangulate();
1426
+ const tris2 = swctx.getTriangles();
1427
+ return tris2;
1428
+ } catch {
1429
+ return null;
1430
+ }
1431
+ };
1432
+ let tris = attempt(true);
1433
+ if (tris === null) {
1434
+ console.warn("poly2tri: triangulation failed, retrying without Steiner points");
1435
+ tris = attempt(false);
1436
+ if (tris === null) {
1437
+ console.error("poly2tri: triangulation failed completely");
1438
+ }
1439
+ }
1440
+ return tris;
1441
+ }
1442
+ function writeCap(positions, normals, indices, vertOffset, idxOffset, capTriangles, z, normalZ, reverseWinding) {
1443
+ const vertMap = /* @__PURE__ */ new Map();
1444
+ let localVert = 0;
1445
+ let ii = idxOffset;
1446
+ for (const tri of capTriangles) {
1447
+ const pts = tri.getPoints();
1448
+ const vi0 = getOrAdd(pts[0], z, normalZ, positions, normals, vertOffset, vertMap, () => localVert++);
1449
+ const vi1 = getOrAdd(pts[1], z, normalZ, positions, normals, vertOffset, vertMap, () => localVert++);
1450
+ const vi2 = getOrAdd(pts[2], z, normalZ, positions, normals, vertOffset, vertMap, () => localVert++);
1451
+ if (reverseWinding) {
1452
+ indices[ii++] = vi0;
1453
+ indices[ii++] = vi2;
1454
+ indices[ii++] = vi1;
1455
+ } else {
1456
+ indices[ii++] = vi0;
1457
+ indices[ii++] = vi1;
1458
+ indices[ii++] = vi2;
1459
+ }
1460
+ }
1461
+ return localVert;
1462
+ }
1463
+ function getOrAdd(pt, z, normalZ, positions, normals, vertOffset, map, nextIdx) {
1464
+ let idx = map.get(pt);
1465
+ if (idx !== void 0) return idx;
1466
+ idx = vertOffset + nextIdx();
1467
+ const base = idx * 3;
1468
+ positions[base] = pt.x;
1469
+ positions[base + 1] = pt.y;
1470
+ positions[base + 2] = z;
1471
+ normals[base] = 0;
1472
+ normals[base + 1] = 0;
1473
+ normals[base + 2] = normalZ;
1474
+ map.set(pt, idx);
1475
+ return idx;
1476
+ }
1477
+ function writeSides(positions, normals, indices, vertOffset, idxOffset, boundaryPoints, frontZ, backZ, depthSegs) {
1478
+ const n = boundaryPoints.length;
1479
+ let vi = vertOffset;
1480
+ let ii = idxOffset;
1481
+ for (let i = 0; i < n; i++) {
1482
+ const a = boundaryPoints[i];
1483
+ const b = boundaryPoints[(i + 1) % n];
1484
+ const edgeDx = b.x - a.x;
1485
+ const edgeDy = b.y - a.y;
1486
+ const edgeLen = Math.hypot(edgeDx, edgeDy);
1487
+ const nx = edgeLen > 0 ? edgeDy / edgeLen : 0;
1488
+ const ny = edgeLen > 0 ? -edgeDx / edgeLen : 0;
1489
+ for (let j = 0; j < depthSegs; j++) {
1490
+ const z0 = frontZ + (backZ - frontZ) * (j / depthSegs);
1491
+ const z1 = frontZ + (backZ - frontZ) * ((j + 1) / depthSegs);
1492
+ const v0 = vi++;
1493
+ positions[v0 * 3] = a.x;
1494
+ positions[v0 * 3 + 1] = a.y;
1495
+ positions[v0 * 3 + 2] = z0;
1496
+ normals[v0 * 3] = nx;
1497
+ normals[v0 * 3 + 1] = ny;
1498
+ normals[v0 * 3 + 2] = 0;
1499
+ const v1 = vi++;
1500
+ positions[v1 * 3] = b.x;
1501
+ positions[v1 * 3 + 1] = b.y;
1502
+ positions[v1 * 3 + 2] = z0;
1503
+ normals[v1 * 3] = nx;
1504
+ normals[v1 * 3 + 1] = ny;
1505
+ normals[v1 * 3 + 2] = 0;
1506
+ const v2 = vi++;
1507
+ positions[v2 * 3] = b.x;
1508
+ positions[v2 * 3 + 1] = b.y;
1509
+ positions[v2 * 3 + 2] = z1;
1510
+ normals[v2 * 3] = nx;
1511
+ normals[v2 * 3 + 1] = ny;
1512
+ normals[v2 * 3 + 2] = 0;
1513
+ const v3 = vi++;
1514
+ positions[v3 * 3] = a.x;
1515
+ positions[v3 * 3 + 1] = a.y;
1516
+ positions[v3 * 3 + 2] = z1;
1517
+ normals[v3 * 3] = nx;
1518
+ normals[v3 * 3 + 1] = ny;
1519
+ normals[v3 * 3 + 2] = 0;
1520
+ indices[ii++] = v0;
1521
+ indices[ii++] = v1;
1522
+ indices[ii++] = v2;
1523
+ indices[ii++] = v0;
1524
+ indices[ii++] = v2;
1525
+ indices[ii++] = v3;
1526
+ }
1527
+ }
1528
+ }
1529
+ function computeBounds(points) {
1530
+ let minX = Infinity;
1531
+ let minY = Infinity;
1532
+ let maxX = -Infinity;
1533
+ let maxY = -Infinity;
1534
+ for (const p of points) {
1535
+ if (p.x < minX) minX = p.x;
1536
+ if (p.y < minY) minY = p.y;
1537
+ if (p.x > maxX) maxX = p.x;
1538
+ if (p.y > maxY) maxY = p.y;
1539
+ }
1540
+ return { minX, minY, maxX, maxY };
1541
+ }
1542
+ function buildGeometry(subdividedPts, capTriangles, depth, depthSegs) {
1543
+ const nCapTris = capTriangles.length;
1544
+ const nBoundary = subdividedPts.length;
1545
+ const uniqueCapPoints = /* @__PURE__ */ new Set();
1546
+ for (const tri of capTriangles) {
1547
+ const pts = tri.getPoints();
1548
+ uniqueCapPoints.add(pts[0]);
1549
+ uniqueCapPoints.add(pts[1]);
1550
+ uniqueCapPoints.add(pts[2]);
1551
+ }
1552
+ const nUniqueCapVerts = uniqueCapPoints.size;
1553
+ uniqueCapPoints.clear();
1554
+ const nSideVerts = nBoundary * depthSegs * 4;
1555
+ const totalVerts = nUniqueCapVerts * 2 + nSideVerts;
1556
+ const totalIndices = nCapTris * 6 + nBoundary * depthSegs * 6;
1557
+ const positions = new Float32Array(totalVerts * 3);
1558
+ const normals = new Float32Array(totalVerts * 3);
1559
+ const indices = totalVerts <= 65535 ? new Uint16Array(totalIndices) : new Uint32Array(totalIndices);
1560
+ const frontZ = -depth / 2;
1561
+ const backZ = depth / 2;
1562
+ const frontVertsWritten = writeCap(
1563
+ positions,
1564
+ normals,
1565
+ indices,
1566
+ 0,
1567
+ 0,
1568
+ capTriangles,
1569
+ frontZ,
1570
+ -1,
1571
+ true
1572
+ );
1573
+ writeCap(
1574
+ positions,
1575
+ normals,
1576
+ indices,
1577
+ frontVertsWritten,
1578
+ nCapTris * 3,
1579
+ capTriangles,
1580
+ backZ,
1581
+ 1,
1582
+ false
1583
+ );
1584
+ writeSides(
1585
+ positions,
1586
+ normals,
1587
+ indices,
1588
+ nUniqueCapVerts * 2,
1589
+ nCapTris * 6,
1590
+ subdividedPts,
1591
+ frontZ,
1592
+ backZ,
1593
+ depthSegs
1594
+ );
1595
+ const geo = new THREE__namespace.BufferGeometry();
1596
+ geo.setAttribute("position", new THREE__namespace.BufferAttribute(positions, 3));
1597
+ geo.setAttribute("normal", new THREE__namespace.BufferAttribute(normals, 3));
1598
+ geo.setIndex(new THREE__namespace.BufferAttribute(indices, 1));
1599
+ return geo;
1600
+ }
1601
+ const DEFAULTS = {
1602
+ depth: 20,
1603
+ depthSegments: 4,
1604
+ capDensity: 5,
1605
+ edgeSubdivisions: 2
1606
+ };
1607
+ function buildExtrudedGeometry(rawPoints, opts) {
1608
+ const { depth, depthSegments, capDensity, edgeSubdivisions } = opts;
1609
+ let pts = deduplicatePoints(rawPoints, 0.5);
1610
+ if (pts.length < 3) return null;
1611
+ pts = ensureCCW(pts);
1612
+ pts = centerPoints(pts);
1613
+ const subdividedPts = subdivideBoundary(pts, edgeSubdivisions);
1614
+ const bounds = computeBounds(subdividedPts);
1615
+ const capTriangles = triangulateCap(subdividedPts, capDensity, bounds);
1616
+ if (!capTriangles || capTriangles.length === 0) return null;
1617
+ return buildGeometry(subdividedPts, capTriangles, depth, depthSegments);
1618
+ }
1619
+ function extrude(input, options) {
1620
+ const opts = { ...DEFAULTS, ...options };
1621
+ if (input.type === "points") {
1622
+ const pts = validatePoints(input.points);
1623
+ if (!pts) return null;
1624
+ return buildExtrudedGeometry(pts, opts);
1625
+ }
1626
+ let contours;
1627
+ try {
1628
+ contours = fromSVG(input.data);
1629
+ } catch (e) {
1630
+ console.error("tess-extrude: SVG parsing failed", e);
1631
+ return null;
1632
+ }
1633
+ if (contours.length === 0) return null;
1634
+ const geometries = [];
1635
+ for (const contour of contours) {
1636
+ const geo = buildExtrudedGeometry(contour, opts);
1637
+ if (geo) geometries.push(geo);
1638
+ }
1639
+ if (geometries.length === 0) return null;
1640
+ if (geometries.length === 1) return geometries[0];
1641
+ return mergeGeometries(geometries);
1642
+ }
1643
+ function mergeGeometries(geos) {
1644
+ let totalVerts = 0;
1645
+ let totalIndices = 0;
1646
+ for (const g of geos) {
1647
+ const pos = g.getAttribute("position");
1648
+ totalVerts += pos.count;
1649
+ const idx = g.index;
1650
+ if (idx) totalIndices += idx.count;
1651
+ }
1652
+ const positions = new Float32Array(totalVerts * 3);
1653
+ const normals = new Float32Array(totalVerts * 3);
1654
+ const indices = totalVerts <= 65535 ? new Uint16Array(totalIndices) : new Uint32Array(totalIndices);
1655
+ let vOff = 0;
1656
+ let iOff = 0;
1657
+ for (const g of geos) {
1658
+ const pos = g.getAttribute("position").array;
1659
+ const nor = g.getAttribute("normal").array;
1660
+ const idx = g.index;
1661
+ positions.set(pos, vOff * 3);
1662
+ normals.set(nor, vOff * 3);
1663
+ if (idx) {
1664
+ const idxArr = idx.array;
1665
+ for (let i = 0; i < idxArr.length; i++) {
1666
+ indices[iOff + i] = idxArr[i] + vOff;
1667
+ }
1668
+ iOff += idxArr.length;
1669
+ }
1670
+ vOff += pos.length / 3;
1671
+ g.dispose();
1672
+ }
1673
+ const merged = new THREE__namespace.BufferGeometry();
1674
+ merged.setAttribute("position", new THREE__namespace.BufferAttribute(positions, 3));
1675
+ merged.setAttribute("normal", new THREE__namespace.BufferAttribute(normals, 3));
1676
+ merged.setIndex(new THREE__namespace.BufferAttribute(indices, 1));
1677
+ return merged;
1678
+ }
1679
+ function perpendicularDist(p, a, b) {
1680
+ const dx = b.x - a.x;
1681
+ const dy = b.y - a.y;
1682
+ const lenSq = dx * dx + dy * dy;
1683
+ if (lenSq === 0) return Math.hypot(p.x - a.x, p.y - a.y);
1684
+ const t = Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / lenSq));
1685
+ return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy));
1686
+ }
1687
+ function simplifyPath(points, tolerance) {
1688
+ if (points.length <= 2) return points.slice();
1689
+ const keep = new Uint8Array(points.length);
1690
+ keep[0] = 1;
1691
+ keep[points.length - 1] = 1;
1692
+ const stack = [[0, points.length - 1]];
1693
+ while (stack.length > 0) {
1694
+ const range = stack.pop();
1695
+ const start = range[0];
1696
+ const end = range[1];
1697
+ if (end - start <= 1) continue;
1698
+ const first = points[start];
1699
+ const last = points[end];
1700
+ let maxDist = 0;
1701
+ let maxIdx = start;
1702
+ for (let i = start + 1; i < end; i++) {
1703
+ const d = perpendicularDist(points[i], first, last);
1704
+ if (d > maxDist) {
1705
+ maxDist = d;
1706
+ maxIdx = i;
1707
+ }
1708
+ }
1709
+ if (maxDist > tolerance) {
1710
+ keep[maxIdx] = 1;
1711
+ stack.push([start, maxIdx]);
1712
+ stack.push([maxIdx, end]);
1713
+ }
1714
+ }
1715
+ const result = [];
1716
+ for (let i = 0; i < points.length; i++) {
1717
+ if (keep[i]) result.push(points[i]);
1718
+ }
1719
+ return result;
1720
+ }
1721
+ exports.deduplicatePoints = deduplicatePoints;
1722
+ exports.ensureCCW = ensureCCW;
1723
+ exports.extrude = extrude;
1724
+ exports.simplifyPath = simplifyPath;
1725
+ exports.subdivideBoundary = subdivideBoundary;
1726
+ //# sourceMappingURL=tess-extrude.cjs.js.map