poly-extrude 0.16.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * poly-extrude v0.16.0
2
+ * poly-extrude v0.17.1
3
3
  */
4
4
  function _defineProperties(target, props) {
5
5
  for (var i = 0; i < props.length; i++) {
@@ -1693,6 +1693,12 @@ var Vector3 = /*#__PURE__*/function () {
1693
1693
  return Vector3;
1694
1694
  }();
1695
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
+ }
1696
1702
  /**
1697
1703
  * https://github.com/Turfjs/turf/blob/master/packages/turf-boolean-clockwise/index.ts
1698
1704
  * @param {*} ring
@@ -1712,6 +1718,63 @@ function isClockwise(ring) {
1712
1718
  }
1713
1719
  return sum > 0;
1714
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
+ }
1715
1778
  function v3Sub(out, v1, v2) {
1716
1779
  out[0] = v1[0] - v2[0];
1717
1780
  out[1] = v1[1] - v2[1];
@@ -1912,21 +1975,7 @@ function calLineDistance(line) {
1912
1975
  function extrudePolygons(polygons, options) {
1913
1976
  options = Object.assign({}, { depth: 2, top: true }, options);
1914
1977
  const results = polygons.map(polygon => {
1915
- for (let i = 0, len = polygon.length; i < len; i++) {
1916
- const ring = polygon[i];
1917
- validateRing(ring);
1918
- if (i === 0) {
1919
- if (!isClockwise(ring)) {
1920
- polygon[i] = ring.reverse();
1921
- }
1922
- }
1923
- else if (isClockwise(ring)) {
1924
- polygon[i] = ring.reverse();
1925
- }
1926
- if (isClosedRing(ring)) {
1927
- ring.splice(ring.length - 1, 1);
1928
- }
1929
- }
1978
+ validatePolygon(polygon);
1930
1979
  const result = flatVertices(polygon, options);
1931
1980
  result.polygon = polygon;
1932
1981
  const triangles = earcut(result.flatVertices, result.holes, 2);
@@ -2011,16 +2060,6 @@ function generateSides$1(result, options) {
2011
2060
  }
2012
2061
  }
2013
2062
  }
2014
- function calPolygonPointsCount(polygon) {
2015
- let count = 0;
2016
- let i = 0;
2017
- const len = polygon.length;
2018
- while (i < len) {
2019
- count += (polygon[i].length);
2020
- i++;
2021
- }
2022
- return count;
2023
- }
2024
2063
  function flatVertices(polygon, options) {
2025
2064
  const count = calPolygonPointsCount(polygon);
2026
2065
  const len = polygon.length;
@@ -2065,15 +2104,49 @@ function flatVertices(polygon, options) {
2065
2104
  uv
2066
2105
  };
2067
2106
  }
2068
- function validateRing(ring) {
2069
- if (!isClosedRing(ring)) {
2070
- ring.push(ring[0]);
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
+ }
2071
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
+ };
2072
2135
  }
2073
- function isClosedRing(ring) {
2074
- const len = ring.length;
2075
- const [x1, y1] = ring[0], [x2, y2] = ring[len - 1];
2076
- return (x1 === x2 && y1 === y2);
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;
2077
2150
  }
2078
2151
 
2079
2152
  function checkOptions(options) {
@@ -2369,7 +2442,7 @@ function expandLine(line, options) {
2369
2442
  TEMPV1.y = p0[1] - p1[1];
2370
2443
  TEMPV2.x = p2[0] - p1[0];
2371
2444
  TEMPV2.y = p2[1] - p1[1];
2372
- const vAngle = getAngle(TEMPV1, TEMPV2);
2445
+ const vAngle = getAngle$1(TEMPV1, TEMPV2);
2373
2446
  rAngle = angle - vAngle / 2;
2374
2447
  }
2375
2448
  const rRad = degToRad(rAngle);
@@ -2406,7 +2479,7 @@ function expandLine(line, options) {
2406
2479
  }
2407
2480
  return { offsetPoints: points, leftPoints, rightPoints, line };
2408
2481
  }
2409
- const getAngle = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
2482
+ const getAngle$1 = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
2410
2483
  const dot = x1 * x2 + y1 * y2;
2411
2484
  const det = x1 * y2 - y1 * x2;
2412
2485
  const angle = Math.atan2(det, dot) / Math.PI * 180;
@@ -3883,7 +3956,7 @@ var PathPointList = /*#__PURE__*/function () {
3883
3956
  return PathPointList;
3884
3957
  }();
3885
3958
 
3886
- const UP$1 = new Vector3(0, 0, 1);
3959
+ const UP$2 = new Vector3(0, 0, 1);
3887
3960
  const right = new Vector3();
3888
3961
  const left = new Vector3();
3889
3962
  // for sharp corners
@@ -3897,7 +3970,7 @@ function expandPaths(lines, options) {
3897
3970
  const points = line2Vectors(line);
3898
3971
  const pathPointList = new PathPointList();
3899
3972
  //@ts-ignore
3900
- pathPointList.set(points, options.cornerRadius, options.cornerSplit, UP$1);
3973
+ pathPointList.set(points, options.cornerRadius, options.cornerSplit, UP$2);
3901
3974
  const params = generatePathVertexData(pathPointList, options);
3902
3975
  const result = {
3903
3976
  position: new Float32Array(params.position),
@@ -4206,15 +4279,15 @@ function generatePathVertexData(pathPointList, options) {
4206
4279
  };
4207
4280
  }
4208
4281
 
4209
- const UP = new Vector3(0, 0, 1);
4210
- const normalDir = new Vector3();
4282
+ const UP$1 = new Vector3(0, 0, 1);
4283
+ const normalDir$1 = new Vector3();
4211
4284
  function expandTubes(lines, options) {
4212
4285
  options = Object.assign({}, { radius: 1, cornerSplit: 0, radialSegments: 8, startRad: -Math.PI / 4 }, options);
4213
4286
  const results = lines.map(line => {
4214
4287
  const points = line2Vectors(line);
4215
4288
  const pathPointList = new PathPointList();
4216
4289
  //@ts-ignore
4217
- pathPointList.set(points, 0, options.cornerSplit, UP);
4290
+ pathPointList.set(points, 0, options.cornerSplit, UP$1);
4218
4291
  const result = generateTubeVertexData(pathPointList, options);
4219
4292
  result.line = line;
4220
4293
  result.position = new Float32Array(result.points);
@@ -4261,14 +4334,14 @@ function generateTubeVertexData(pathPointList, options) {
4261
4334
  if (r === radialSegments) {
4262
4335
  r = 0;
4263
4336
  }
4264
- 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();
4265
4338
  const scale = radius * pathPoint.widthScale;
4266
- points[++pIndex] = pathPoint.pos.x + normalDir.x * scale;
4267
- points[++pIndex] = pathPoint.pos.y + normalDir.y * scale;
4268
- points[++pIndex] = pathPoint.pos.z + normalDir.z * scale;
4269
- normal[++nIndex] = normalDir.x;
4270
- normal[++nIndex] = normalDir.y;
4271
- 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;
4272
4345
  uv[++uIndex] = uvDist;
4273
4346
  uv[++uIndex] = i / radialSegments;
4274
4347
  // uvs.push(uvDist, r / radialSegments);
@@ -4383,5 +4456,263 @@ function plane(width, height, devideW, devideH) {
4383
4456
  };
4384
4457
  }
4385
4458
 
4386
- export { cylinder, expandLine, expandPaths, expandTubes, extrudePolygons, extrudePolylines, extrudeSlopes, isClockwise, leftOnLine, merge, plane };
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 };
4387
4718
  //# sourceMappingURL=poly-extrude.mjs.map