poly-extrude 0.16.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 CHANGED
@@ -1,8 +1,9 @@
1
- import { extrudePolygons } from './polygon';
1
+ import { extrudePolygons, polygons } from './polygon';
2
2
  import { extrudePolylines, expandLine, leftOnLine, extrudeSlopes } from './polyline';
3
3
  import { cylinder } from './cylinder';
4
4
  import { expandPaths } from './path';
5
5
  import { expandTubes } from './tube';
6
6
  import { plane } from './plane';
7
+ import { extrudePolygonsOnPath } from './polygonpath';
7
8
  import { isClockwise, merge } from './util';
8
- export { isClockwise, merge, extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane };
9
+ export { isClockwise, merge, extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane, extrudePolygonsOnPath, polygons };
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
- import { extrudePolygons } from './polygon';
1
+ import { extrudePolygons, polygons } from './polygon';
2
2
  import { extrudePolylines, expandLine, leftOnLine, extrudeSlopes } from './polyline';
3
3
  import { cylinder } from './cylinder';
4
4
  import { expandPaths } from './path';
5
5
  import { expandTubes } from './tube';
6
6
  import { plane } from './plane';
7
+ import { extrudePolygonsOnPath } from './polygonpath';
7
8
  import { isClockwise, merge } from './util';
8
- export { isClockwise, merge, extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane };
9
+ export { isClockwise, merge, extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane, extrudePolygonsOnPath, polygons };
9
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EACH,WAAW,EAAE,KAAK,EAClB,eAAe,EAAE,gBAAgB,EACjC,aAAa,EAAE,UAAU,EAAE,UAAU,EACrC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAC5C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EACH,WAAW,EAAE,KAAK,EAClB,eAAe,EAAE,gBAAgB,EACjC,aAAa,EAAE,UAAU,EAAE,UAAU,EACrC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EACzC,qBAAqB,EACrB,QAAQ,EACX,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * poly-extrude v0.16.0
2
+ * poly-extrude v0.17.0
3
3
  */
4
4
  (function (global, factory) {
5
5
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
@@ -1699,6 +1699,12 @@
1699
1699
  return Vector3;
1700
1700
  }();
1701
1701
 
1702
+ function mergeArray(array1, array2) {
1703
+ let index = array1.length - 1;
1704
+ for (let i = 0, len = array2.length; i < len; i++) {
1705
+ array1[++index] = array2[i];
1706
+ }
1707
+ }
1702
1708
  /**
1703
1709
  * https://github.com/Turfjs/turf/blob/master/packages/turf-boolean-clockwise/index.ts
1704
1710
  * @param {*} ring
@@ -1718,6 +1724,63 @@
1718
1724
  }
1719
1725
  return sum > 0;
1720
1726
  }
1727
+ function validateRing(ring) {
1728
+ if (!isClosedRing(ring)) {
1729
+ ring.push(ring[0]);
1730
+ }
1731
+ }
1732
+ function isClosedRing(ring) {
1733
+ const len = ring.length;
1734
+ const [x1, y1] = ring[0], [x2, y2] = ring[len - 1];
1735
+ return (x1 === x2 && y1 === y2);
1736
+ }
1737
+ function calPolygonPointsCount(polygon) {
1738
+ let count = 0;
1739
+ let i = 0;
1740
+ const len = polygon.length;
1741
+ while (i < len) {
1742
+ count += (polygon[i].length);
1743
+ i++;
1744
+ }
1745
+ return count;
1746
+ }
1747
+ function getPolygonsBBOX(polygons, bbox) {
1748
+ bbox = bbox || [Infinity, Infinity, -Infinity, -Infinity];
1749
+ for (let i = 0, len = polygons.length; i < len; i++) {
1750
+ const p = polygons[i];
1751
+ if (Array.isArray(p[0][0])) {
1752
+ getPolygonsBBOX(p, bbox);
1753
+ }
1754
+ else {
1755
+ for (let j = 0, len1 = p.length; j < len1; j++) {
1756
+ const c = p[j];
1757
+ const [x, y] = c;
1758
+ bbox[0] = Math.min(bbox[0], x);
1759
+ bbox[1] = Math.min(bbox[1], y);
1760
+ bbox[2] = Math.max(bbox[2], x);
1761
+ bbox[3] = Math.max(bbox[3], y);
1762
+ }
1763
+ }
1764
+ }
1765
+ return bbox;
1766
+ }
1767
+ function validatePolygon(polygon) {
1768
+ for (let i = 0, len = polygon.length; i < len; i++) {
1769
+ const ring = polygon[i];
1770
+ validateRing(ring);
1771
+ if (i === 0) {
1772
+ if (!isClockwise(ring)) {
1773
+ polygon[i] = ring.reverse();
1774
+ }
1775
+ }
1776
+ else if (isClockwise(ring)) {
1777
+ polygon[i] = ring.reverse();
1778
+ }
1779
+ if (isClosedRing(ring)) {
1780
+ ring.splice(ring.length - 1, 1);
1781
+ }
1782
+ }
1783
+ }
1721
1784
  function v3Sub(out, v1, v2) {
1722
1785
  out[0] = v1[0] - v2[0];
1723
1786
  out[1] = v1[1] - v2[1];
@@ -1918,21 +1981,7 @@
1918
1981
  function extrudePolygons(polygons, options) {
1919
1982
  options = Object.assign({}, { depth: 2, top: true }, options);
1920
1983
  const results = polygons.map(polygon => {
1921
- for (let i = 0, len = polygon.length; i < len; i++) {
1922
- const ring = polygon[i];
1923
- validateRing(ring);
1924
- if (i === 0) {
1925
- if (!isClockwise(ring)) {
1926
- polygon[i] = ring.reverse();
1927
- }
1928
- }
1929
- else if (isClockwise(ring)) {
1930
- polygon[i] = ring.reverse();
1931
- }
1932
- if (isClosedRing(ring)) {
1933
- ring.splice(ring.length - 1, 1);
1934
- }
1935
- }
1984
+ validatePolygon(polygon);
1936
1985
  const result = flatVertices(polygon, options);
1937
1986
  result.polygon = polygon;
1938
1987
  const triangles = earcut(result.flatVertices, result.holes, 2);
@@ -2017,16 +2066,6 @@
2017
2066
  }
2018
2067
  }
2019
2068
  }
2020
- function calPolygonPointsCount(polygon) {
2021
- let count = 0;
2022
- let i = 0;
2023
- const len = polygon.length;
2024
- while (i < len) {
2025
- count += (polygon[i].length);
2026
- i++;
2027
- }
2028
- return count;
2029
- }
2030
2069
  function flatVertices(polygon, options) {
2031
2070
  const count = calPolygonPointsCount(polygon);
2032
2071
  const len = polygon.length;
@@ -2071,15 +2110,49 @@
2071
2110
  uv
2072
2111
  };
2073
2112
  }
2074
- function validateRing(ring) {
2075
- if (!isClosedRing(ring)) {
2076
- ring.push(ring[0]);
2113
+ function simplePolygon(polygon, options = {}) {
2114
+ const flatVertices = [], holes = [];
2115
+ let pIndex = -1, aIndex = -1, uvIndex = -1;
2116
+ const points = [], uv = [];
2117
+ for (let i = 0, len = polygon.length; i < len; i++) {
2118
+ const ring = polygon[i];
2119
+ if (i > 0) {
2120
+ holes.push(flatVertices.length / 2);
2121
+ }
2122
+ for (let j = 0, len1 = ring.length; j < len1; j++) {
2123
+ const c = ring[j];
2124
+ flatVertices[++pIndex] = c[0];
2125
+ flatVertices[++pIndex] = c[1];
2126
+ points[++aIndex] = c[0];
2127
+ points[++aIndex] = c[1];
2128
+ points[++aIndex] = c[2] || 0;
2129
+ uv[++uvIndex] = c[0];
2130
+ uv[++uvIndex] = c[1];
2131
+ }
2077
2132
  }
2133
+ const triangles = earcut(flatVertices, holes, 2);
2134
+ const normal = generateNormal(triangles, points);
2135
+ return {
2136
+ normal,
2137
+ uv,
2138
+ points,
2139
+ indices: triangles
2140
+ };
2078
2141
  }
2079
- function isClosedRing(ring) {
2080
- const len = ring.length;
2081
- const [x1, y1] = ring[0], [x2, y2] = ring[len - 1];
2082
- return (x1 === x2 && y1 === y2);
2142
+ function polygons(polygons, options = {}) {
2143
+ const results = polygons.map(polygon => {
2144
+ validatePolygon(polygon);
2145
+ const result = simplePolygon(polygon, options);
2146
+ result.polygon = polygon;
2147
+ result.position = new Float32Array(result.points);
2148
+ result.indices = new Uint32Array(result.indices);
2149
+ result.uv = new Float32Array(result.uv);
2150
+ result.normal = new Float32Array(result.normal);
2151
+ return result;
2152
+ });
2153
+ const result = merge(results);
2154
+ result.polygons = polygons;
2155
+ return result;
2083
2156
  }
2084
2157
 
2085
2158
  function checkOptions(options) {
@@ -2375,7 +2448,7 @@
2375
2448
  TEMPV1.y = p0[1] - p1[1];
2376
2449
  TEMPV2.x = p2[0] - p1[0];
2377
2450
  TEMPV2.y = p2[1] - p1[1];
2378
- const vAngle = getAngle(TEMPV1, TEMPV2);
2451
+ const vAngle = getAngle$1(TEMPV1, TEMPV2);
2379
2452
  rAngle = angle - vAngle / 2;
2380
2453
  }
2381
2454
  const rRad = degToRad(rAngle);
@@ -2412,7 +2485,7 @@
2412
2485
  }
2413
2486
  return { offsetPoints: points, leftPoints, rightPoints, line };
2414
2487
  }
2415
- const getAngle = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
2488
+ const getAngle$1 = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
2416
2489
  const dot = x1 * x2 + y1 * y2;
2417
2490
  const det = x1 * y2 - y1 * x2;
2418
2491
  const angle = Math.atan2(det, dot) / Math.PI * 180;
@@ -3889,7 +3962,7 @@
3889
3962
  return PathPointList;
3890
3963
  }();
3891
3964
 
3892
- const UP$1 = new Vector3(0, 0, 1);
3965
+ const UP$2 = new Vector3(0, 0, 1);
3893
3966
  const right = new Vector3();
3894
3967
  const left = new Vector3();
3895
3968
  // for sharp corners
@@ -3903,7 +3976,7 @@
3903
3976
  const points = line2Vectors(line);
3904
3977
  const pathPointList = new PathPointList();
3905
3978
  //@ts-ignore
3906
- pathPointList.set(points, options.cornerRadius, options.cornerSplit, UP$1);
3979
+ pathPointList.set(points, options.cornerRadius, options.cornerSplit, UP$2);
3907
3980
  const params = generatePathVertexData(pathPointList, options);
3908
3981
  const result = {
3909
3982
  position: new Float32Array(params.position),
@@ -4212,15 +4285,15 @@
4212
4285
  };
4213
4286
  }
4214
4287
 
4215
- const UP = new Vector3(0, 0, 1);
4216
- const normalDir = new Vector3();
4288
+ const UP$1 = new Vector3(0, 0, 1);
4289
+ const normalDir$1 = new Vector3();
4217
4290
  function expandTubes(lines, options) {
4218
4291
  options = Object.assign({}, { radius: 1, cornerSplit: 0, radialSegments: 8, startRad: -Math.PI / 4 }, options);
4219
4292
  const results = lines.map(line => {
4220
4293
  const points = line2Vectors(line);
4221
4294
  const pathPointList = new PathPointList();
4222
4295
  //@ts-ignore
4223
- pathPointList.set(points, 0, options.cornerSplit, UP);
4296
+ pathPointList.set(points, 0, options.cornerSplit, UP$1);
4224
4297
  const result = generateTubeVertexData(pathPointList, options);
4225
4298
  result.line = line;
4226
4299
  result.position = new Float32Array(result.points);
@@ -4267,14 +4340,14 @@
4267
4340
  if (r === radialSegments) {
4268
4341
  r = 0;
4269
4342
  }
4270
- normalDir.copy(pathPoint.up).applyAxisAngle(pathPoint.dir, startRad + Math.PI * 2 * r / radialSegments).normalize();
4343
+ normalDir$1.copy(pathPoint.up).applyAxisAngle(pathPoint.dir, startRad + Math.PI * 2 * r / radialSegments).normalize();
4271
4344
  const scale = radius * pathPoint.widthScale;
4272
- points[++pIndex] = pathPoint.pos.x + normalDir.x * scale;
4273
- points[++pIndex] = pathPoint.pos.y + normalDir.y * scale;
4274
- points[++pIndex] = pathPoint.pos.z + normalDir.z * scale;
4275
- normal[++nIndex] = normalDir.x;
4276
- normal[++nIndex] = normalDir.y;
4277
- normal[++nIndex] = normalDir.z;
4345
+ points[++pIndex] = pathPoint.pos.x + normalDir$1.x * scale;
4346
+ points[++pIndex] = pathPoint.pos.y + normalDir$1.y * scale;
4347
+ points[++pIndex] = pathPoint.pos.z + normalDir$1.z * scale;
4348
+ normal[++nIndex] = normalDir$1.x;
4349
+ normal[++nIndex] = normalDir$1.y;
4350
+ normal[++nIndex] = normalDir$1.z;
4278
4351
  uv[++uIndex] = uvDist;
4279
4352
  uv[++uIndex] = i / radialSegments;
4280
4353
  // uvs.push(uvDist, r / radialSegments);
@@ -4389,17 +4462,277 @@
4389
4462
  };
4390
4463
  }
4391
4464
 
4465
+ const UP = new Vector3(0, 0, 1);
4466
+ const normalDir = new Vector3();
4467
+ function extrudePolygonsOnPath(polygons, options) {
4468
+ options = Object.assign({}, { openEnd: false, openEndUV: true }, options);
4469
+ const { extrudePath, openEnd } = options;
4470
+ if (!extrudePath || !Array.isArray(extrudePath) || extrudePath.length < 2) {
4471
+ console.error('extrudePath is error:', extrudePath);
4472
+ return null;
4473
+ }
4474
+ const bbox = getPolygonsBBOX(polygons);
4475
+ const [minx, miny, maxx, maxy] = bbox;
4476
+ const center = [(minx + maxx) / 2, (miny + maxy) / 2];
4477
+ const points = line2Vectors(extrudePath);
4478
+ const pathPointList = new PathPointList();
4479
+ //@ts-ignore
4480
+ pathPointList.set(points, 0, options.cornerSplit, UP);
4481
+ const results = polygons.map(polygon => {
4482
+ for (let i = 0, len = polygon.length; i < len; i++) {
4483
+ const ring = polygon[i];
4484
+ validateRing(ring);
4485
+ if (i === 0) {
4486
+ if (isClockwise(ring)) {
4487
+ polygon[i] = ring.reverse();
4488
+ }
4489
+ }
4490
+ else if (!isClockwise(ring)) {
4491
+ polygon[i] = ring.reverse();
4492
+ }
4493
+ }
4494
+ const result = generatePolygonOnPathVertexData(pathPointList, polygon, center);
4495
+ if (!openEnd) {
4496
+ generateStartAndEnd(result, polygon, options);
4497
+ }
4498
+ result.polygon = polygon;
4499
+ result.position = new Float32Array(result.points);
4500
+ result.indices = new Uint32Array(result.indices);
4501
+ result.uv = new Float32Array(result.uv);
4502
+ result.normal = new Float32Array(result.normal);
4503
+ return result;
4504
+ });
4505
+ const result = merge(results);
4506
+ result.polygons = polygons;
4507
+ return result;
4508
+ }
4509
+ function getAngle(c1, c2) {
4510
+ const [x1, y1] = c1;
4511
+ const [x2, y2] = c2;
4512
+ const dy = y2 - y1;
4513
+ const dx = x2 - x1;
4514
+ return Math.atan2(dy, dx);
4515
+ }
4516
+ function transformPolygon(polygon, center) {
4517
+ const [cx, cy] = center;
4518
+ const list = [];
4519
+ polygon.forEach((ring, rIndex) => {
4520
+ const data = [];
4521
+ let totalDistance = 0;
4522
+ let tempPoint;
4523
+ for (let i = 0, len = ring.length; i < len; i++) {
4524
+ const p = ring[i];
4525
+ const x1 = p[0], y1 = p[1];
4526
+ const offsetx = x1 - cx, offsety = y1 - cy;
4527
+ let distance = 0;
4528
+ if (i > 0) {
4529
+ const x2 = tempPoint[0], y2 = tempPoint[1];
4530
+ const dx = x2 - x1, dy = y2 - y1;
4531
+ distance = Math.sqrt(dx * dx + dy * dy) + totalDistance;
4532
+ totalDistance = distance;
4533
+ }
4534
+ data[i] = {
4535
+ // dx,
4536
+ // dy,
4537
+ // dz: 0,
4538
+ distance,
4539
+ radius: Math.sqrt(offsetx * offsetx + offsety * offsety),
4540
+ angle: getAngle(center, p)
4541
+ };
4542
+ tempPoint = p;
4543
+ }
4544
+ list[rIndex] = {
4545
+ ring: data,
4546
+ ringLen: totalDistance
4547
+ };
4548
+ });
4549
+ return list;
4550
+ }
4551
+ const TEMP_VECTOR3 = new Vector3(0, 0, 0);
4552
+ // Vertex Data Generate Functions
4553
+ // code copy from https://github.com/shawn0326/three.path/blob/master/src/PathGeometry.js
4554
+ function generatePolygonOnPathVertexData(pathPointList, polygon, center) {
4555
+ const tpolygon = transformPolygon(polygon, center);
4556
+ // let count = 0;
4557
+ // modify data
4558
+ const points = [];
4559
+ const normal = [];
4560
+ const uv = [];
4561
+ // const uv2 = [];
4562
+ const indices = [];
4563
+ let verticesCount = 0;
4564
+ let pIndex = -1;
4565
+ let nIndex = -1;
4566
+ let uIndex = -1;
4567
+ let iIndex = -1;
4568
+ const startPoints = [], endPoints = [];
4569
+ function addVertices(pathPoint, ring, ringLen, first, end) {
4570
+ const uvDist = pathPoint.dist / ringLen;
4571
+ const radialSegments = ring.length;
4572
+ // const startRad = ring[0].angle;
4573
+ for (let i = 0; i < radialSegments; i++) {
4574
+ const item = ring[i];
4575
+ if (!item) {
4576
+ continue;
4577
+ }
4578
+ const isLast = i === radialSegments - 1;
4579
+ const angle = item.angle;
4580
+ const radius = item.radius;
4581
+ const distance = item.distance;
4582
+ normalDir.copy(pathPoint.up).applyAxisAngle(pathPoint.dir, angle).normalize();
4583
+ const v = TEMP_VECTOR3.copy(pathPoint.up);
4584
+ v.applyAxisAngle(pathPoint.dir, angle);
4585
+ v.x *= radius;
4586
+ v.y *= radius;
4587
+ v.z *= radius;
4588
+ points[++pIndex] = pathPoint.pos.x + v.x;
4589
+ points[++pIndex] = pathPoint.pos.y + v.y;
4590
+ points[++pIndex] = pathPoint.pos.z + v.z;
4591
+ // if (i === 0 || i === radialSegments - 1) {
4592
+ // console.log(i, radialSegments, v.x, v.y, v.z);
4593
+ // }
4594
+ normal[++nIndex] = normalDir.x;
4595
+ normal[++nIndex] = normalDir.y;
4596
+ normal[++nIndex] = normalDir.z;
4597
+ uv[++uIndex] = uvDist;
4598
+ uv[++uIndex] = distance / ringLen;
4599
+ verticesCount++;
4600
+ if (first && !isLast) {
4601
+ let index = startPoints.length - 1;
4602
+ startPoints[++index] = pathPoint.pos.x + v.x;
4603
+ startPoints[++index] = pathPoint.pos.y + v.y;
4604
+ startPoints[++index] = pathPoint.pos.z + v.z;
4605
+ }
4606
+ if (end && !isLast) {
4607
+ let index = endPoints.length - 1;
4608
+ endPoints[++index] = pathPoint.pos.x + v.x;
4609
+ endPoints[++index] = pathPoint.pos.y + v.y;
4610
+ endPoints[++index] = pathPoint.pos.z + v.z;
4611
+ }
4612
+ }
4613
+ if (!first) {
4614
+ const begin1 = verticesCount - (radialSegments) * 2;
4615
+ const begin2 = verticesCount - (radialSegments);
4616
+ for (let i = 0; i < radialSegments; i++) {
4617
+ indices[++iIndex] = begin2 + i;
4618
+ indices[++iIndex] = begin1 + i;
4619
+ indices[++iIndex] = begin1 + i + 1;
4620
+ indices[++iIndex] = begin2 + i;
4621
+ indices[++iIndex] = begin1 + i + 1;
4622
+ indices[++iIndex] = begin2 + i + 1;
4623
+ }
4624
+ }
4625
+ }
4626
+ const polygonLen = tpolygon[0].ringLen;
4627
+ tpolygon.forEach(item => {
4628
+ for (let i = 0; i < pathPointList.count; i++) {
4629
+ const pathPoint = pathPointList.array[i];
4630
+ const { ring, ringLen } = item;
4631
+ addVertices(pathPoint, ring, ringLen, i === 0, i === pathPointList.count - 1);
4632
+ }
4633
+ });
4634
+ return {
4635
+ points,
4636
+ normal,
4637
+ uv,
4638
+ // uv2,
4639
+ indices,
4640
+ startPoints,
4641
+ endPoints,
4642
+ polygonLen
4643
+ // count
4644
+ };
4645
+ }
4646
+ function generateStartAndEnd(result, polygon, options) {
4647
+ const { openEndUV } = options;
4648
+ for (let i = 0, len = polygon.length; i < len; i++) {
4649
+ const ring = polygon[i];
4650
+ if (isClosedRing(ring)) {
4651
+ ring.splice(ring.length - 1, 1);
4652
+ }
4653
+ }
4654
+ const pointCount = calPolygonPointsCount(polygon);
4655
+ const flatVertices = [], holes = [];
4656
+ let pIndex = -1;
4657
+ for (let i = 0, len = polygon.length; i < len; i++) {
4658
+ const ring = polygon[i];
4659
+ if (i > 0) {
4660
+ holes.push(flatVertices.length / 2);
4661
+ }
4662
+ for (let j = 0, len1 = ring.length; j < len1; j++) {
4663
+ const c = ring[j];
4664
+ flatVertices[++pIndex] = c[0];
4665
+ flatVertices[++pIndex] = c[1];
4666
+ }
4667
+ }
4668
+ const triangles = earcut(flatVertices, holes, 2);
4669
+ const { points, normal, uv, indices, startPoints, endPoints, polygonLen } = result;
4670
+ pIndex = 0;
4671
+ let uIndex = 0;
4672
+ const aPoints1 = [], auv1 = [], aPoints2 = [], auv2 = [];
4673
+ for (let i = 0; i < pointCount; i++) {
4674
+ const idx = i * 3;
4675
+ const x = startPoints[idx];
4676
+ const y = startPoints[idx + 1];
4677
+ const z = startPoints[idx + 2];
4678
+ aPoints1[pIndex] = x;
4679
+ aPoints1[pIndex + 1] = y;
4680
+ aPoints1[pIndex + 2] = z;
4681
+ if (openEndUV) {
4682
+ auv1[uIndex] = y / polygonLen;
4683
+ auv1[uIndex + 1] = z / polygonLen;
4684
+ }
4685
+ else {
4686
+ auv1[uIndex] = 0;
4687
+ auv1[uIndex + 1] = 0;
4688
+ }
4689
+ const x1 = endPoints[idx];
4690
+ const y1 = endPoints[idx + 1];
4691
+ const z1 = endPoints[idx + 2];
4692
+ aPoints2[pIndex] = x1;
4693
+ aPoints2[pIndex + 1] = y1;
4694
+ aPoints2[pIndex + 2] = z1;
4695
+ if (openEndUV) {
4696
+ auv2[uIndex] = y1 / polygonLen;
4697
+ auv2[uIndex + 1] = z1 / polygonLen;
4698
+ }
4699
+ else {
4700
+ auv2[uIndex] = 0;
4701
+ auv2[uIndex + 1] = 0;
4702
+ }
4703
+ pIndex += 3;
4704
+ uIndex += 2;
4705
+ }
4706
+ const indexOffset = points.length / 3;
4707
+ const indexs = [];
4708
+ for (let i = 0, len = triangles.length; i < len; i++) {
4709
+ indexs[i] = triangles[i] + indexOffset;
4710
+ indexs[i + len] = triangles[i] + indexOffset + pointCount;
4711
+ }
4712
+ const anormal1 = generateNormal(triangles, aPoints1);
4713
+ const anormal2 = generateNormal(triangles, aPoints2);
4714
+ mergeArray(points, aPoints1);
4715
+ mergeArray(points, aPoints2);
4716
+ mergeArray(uv, auv1);
4717
+ mergeArray(uv, auv2);
4718
+ mergeArray(normal, anormal1);
4719
+ mergeArray(normal, anormal2);
4720
+ mergeArray(indices, indexs);
4721
+ }
4722
+
4392
4723
  exports.cylinder = cylinder;
4393
4724
  exports.expandLine = expandLine;
4394
4725
  exports.expandPaths = expandPaths;
4395
4726
  exports.expandTubes = expandTubes;
4396
4727
  exports.extrudePolygons = extrudePolygons;
4728
+ exports.extrudePolygonsOnPath = extrudePolygonsOnPath;
4397
4729
  exports.extrudePolylines = extrudePolylines;
4398
4730
  exports.extrudeSlopes = extrudeSlopes;
4399
4731
  exports.isClockwise = isClockwise;
4400
4732
  exports.leftOnLine = leftOnLine;
4401
4733
  exports.merge = merge;
4402
4734
  exports.plane = plane;
4735
+ exports.polygons = polygons;
4403
4736
 
4404
4737
  Object.defineProperty(exports, '__esModule', { value: true });
4405
4738