@itwin/core-geometry 3.4.0-dev.34 → 3.4.0-dev.35
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/lib/cjs/core-geometry.d.ts +1 -0
- package/lib/cjs/core-geometry.d.ts.map +1 -1
- package/lib/cjs/core-geometry.js +1 -0
- package/lib/cjs/core-geometry.js.map +1 -1
- package/lib/cjs/curve/LineString3d.d.ts +3 -0
- package/lib/cjs/curve/LineString3d.d.ts.map +1 -1
- package/lib/cjs/curve/LineString3d.js +24 -0
- package/lib/cjs/curve/LineString3d.js.map +1 -1
- package/lib/cjs/curve/internalContexts/MultiChainCollector.d.ts +4 -1
- package/lib/cjs/curve/internalContexts/MultiChainCollector.d.ts.map +1 -1
- package/lib/cjs/curve/internalContexts/MultiChainCollector.js +26 -1
- package/lib/cjs/curve/internalContexts/MultiChainCollector.js.map +1 -1
- package/lib/cjs/geometry3d/PointHelpers.d.ts +8 -1
- package/lib/cjs/geometry3d/PointHelpers.d.ts.map +1 -1
- package/lib/cjs/geometry3d/PointHelpers.js +37 -3
- package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
- package/lib/cjs/geometry3d/PolygonOps.d.ts +7 -0
- package/lib/cjs/geometry3d/PolygonOps.d.ts.map +1 -1
- package/lib/cjs/geometry3d/PolygonOps.js +35 -0
- package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
- package/lib/cjs/geometry3d/PolylineOps.d.ts +5 -0
- package/lib/cjs/geometry3d/PolylineOps.d.ts.map +1 -1
- package/lib/cjs/geometry3d/PolylineOps.js +20 -0
- package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.d.ts +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.js +5 -3
- package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceQuery.d.ts +68 -10
- package/lib/cjs/polyface/PolyfaceQuery.d.ts.map +1 -1
- package/lib/cjs/polyface/PolyfaceQuery.js +162 -14
- package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
- package/lib/cjs/serialization/GeometrySamples.d.ts +9 -0
- package/lib/cjs/serialization/GeometrySamples.d.ts.map +1 -1
- package/lib/cjs/serialization/GeometrySamples.js +31 -0
- package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
- package/lib/cjs/topology/SpaceTriangulation.d.ts +47 -0
- package/lib/cjs/topology/SpaceTriangulation.d.ts.map +1 -0
- package/lib/cjs/topology/SpaceTriangulation.js +135 -0
- package/lib/cjs/topology/SpaceTriangulation.js.map +1 -0
- package/lib/esm/core-geometry.d.ts +1 -0
- package/lib/esm/core-geometry.d.ts.map +1 -1
- package/lib/esm/core-geometry.js +1 -0
- package/lib/esm/core-geometry.js.map +1 -1
- package/lib/esm/curve/LineString3d.d.ts +3 -0
- package/lib/esm/curve/LineString3d.d.ts.map +1 -1
- package/lib/esm/curve/LineString3d.js +24 -0
- package/lib/esm/curve/LineString3d.js.map +1 -1
- package/lib/esm/curve/internalContexts/MultiChainCollector.d.ts +4 -1
- package/lib/esm/curve/internalContexts/MultiChainCollector.d.ts.map +1 -1
- package/lib/esm/curve/internalContexts/MultiChainCollector.js +26 -1
- package/lib/esm/curve/internalContexts/MultiChainCollector.js.map +1 -1
- package/lib/esm/geometry3d/PointHelpers.d.ts +8 -1
- package/lib/esm/geometry3d/PointHelpers.d.ts.map +1 -1
- package/lib/esm/geometry3d/PointHelpers.js +37 -3
- package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
- package/lib/esm/geometry3d/PolygonOps.d.ts +7 -0
- package/lib/esm/geometry3d/PolygonOps.d.ts.map +1 -1
- package/lib/esm/geometry3d/PolygonOps.js +35 -0
- package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
- package/lib/esm/geometry3d/PolylineOps.d.ts +5 -0
- package/lib/esm/geometry3d/PolylineOps.d.ts.map +1 -1
- package/lib/esm/geometry3d/PolylineOps.js +20 -0
- package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.d.ts +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.js +5 -3
- package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/esm/polyface/PolyfaceQuery.d.ts +68 -10
- package/lib/esm/polyface/PolyfaceQuery.d.ts.map +1 -1
- package/lib/esm/polyface/PolyfaceQuery.js +163 -15
- package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
- package/lib/esm/serialization/GeometrySamples.d.ts +9 -0
- package/lib/esm/serialization/GeometrySamples.d.ts.map +1 -1
- package/lib/esm/serialization/GeometrySamples.js +31 -0
- package/lib/esm/serialization/GeometrySamples.js.map +1 -1
- package/lib/esm/topology/SpaceTriangulation.d.ts +47 -0
- package/lib/esm/topology/SpaceTriangulation.d.ts.map +1 -0
- package/lib/esm/topology/SpaceTriangulation.js +131 -0
- package/lib/esm/topology/SpaceTriangulation.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** @packageDocumentation
|
|
2
|
+
* @module Topology
|
|
3
|
+
*/
|
|
4
|
+
import { LineString3d } from "../curve/LineString3d";
|
|
5
|
+
import { Point3d } from "../geometry3d/Point3dVector3d";
|
|
6
|
+
declare type AnnounceLoopAndTrianglesFunction = (loop: Point3d[], triangles: Point3d[][]) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Class with static methods to triangulate various forms of possibly non-planar polygons.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export declare class SpacePolygonTriangulation {
|
|
12
|
+
/**
|
|
13
|
+
* * Return a number which is:
|
|
14
|
+
* * 0 for collapsed (zero area) triangle
|
|
15
|
+
* * positive for non-zero area
|
|
16
|
+
* * larger is "better"
|
|
17
|
+
* * Specifically, return (if well defined) the area divided by summed squares of edge lengths.
|
|
18
|
+
* @param point0
|
|
19
|
+
* @param point1
|
|
20
|
+
* @param point2
|
|
21
|
+
*/
|
|
22
|
+
static spaceTriangleAspectRatio(point0: Point3d, point1: Point3d, point2: Point3d): number;
|
|
23
|
+
/**
|
|
24
|
+
* * Treat a space quad as two triangles with interior diagonal from point0 to point2
|
|
25
|
+
* * Return the smaller of the aspect ratios of the two triangles.
|
|
26
|
+
* * The quad edges proceed in the order [point0, point1, point2, point3]
|
|
27
|
+
* @param point0 first point of quad
|
|
28
|
+
* @param point1 second point of quad (diagonally opposite of point3)
|
|
29
|
+
* @param point2 third point (diagonally opposite point0)
|
|
30
|
+
* @param point3 fourth point
|
|
31
|
+
*/
|
|
32
|
+
static spaceQuadDiagonalAspectRatio(point0: Point3d, point1: Point3d, point2: Point3d, point3: Point3d): number;
|
|
33
|
+
/** "Triangulate" by cutting of the ear with best aspect ratio. Reject if successive normals have negative dot product with PolygonOps.AreaNormal */
|
|
34
|
+
static triangulateGreedyEarCut(points: Point3d[], announceLoopAndTriangles: AnnounceLoopAndTrianglesFunction): boolean;
|
|
35
|
+
private static triangulateSimplestSpaceLoopGo;
|
|
36
|
+
/**
|
|
37
|
+
* * Emit triangles for a (possibly non-planar) loop for various simple cases:
|
|
38
|
+
* * only 3 points: just emit that triangle.
|
|
39
|
+
* * only 4 points: split across a diagonal, choosing the one with better aspect ratios of its two triangles.
|
|
40
|
+
* * BUT
|
|
41
|
+
* * do not complete the triangulation if perimeter is larger than maxPerimeter (i.e. only consider small areas)
|
|
42
|
+
* * Hence it is expected that the caller will use this as the first attempt, possibly followed by calls to other more adventurous methods.
|
|
43
|
+
*/
|
|
44
|
+
static triangulateSimplestSpaceLoop(loop: Point3d[] | LineString3d, announceLoopAndTriangles: AnnounceLoopAndTrianglesFunction, maxPerimeter?: number): boolean;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=SpaceTriangulation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpaceTriangulation.d.ts","sourceRoot":"","sources":["../../../src/topology/SpaceTriangulation.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAIxD,aAAK,gCAAgC,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,CAAC;AAE1F;;;GAGG;AACH,qBAAa,yBAAyB;IAEpC;;;;;;;;;OASG;WACW,wBAAwB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM;IAMjG;;;;;;;;OAQG;WACW,4BAA4B,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM;IAKtH,qJAAqJ;WACvI,uBAAuB,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,wBAAwB,EAAE,gCAAgC,GAAG,OAAO;IAsC7H,OAAO,CAAC,MAAM,CAAC,8BAA8B;IA8B7C;;;;;;;OAOG;WACW,4BAA4B,CAAC,IAAI,EAAE,OAAO,EAAG,GAAG,YAAY,EACxE,wBAAwB,EAAE,gCAAgC,EAC1D,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO;CAOlC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/** @packageDocumentation
|
|
6
|
+
* @module Topology
|
|
7
|
+
*/
|
|
8
|
+
import { LineString3d } from "../curve/LineString3d";
|
|
9
|
+
import { Geometry } from "../Geometry";
|
|
10
|
+
import { Point3dArray } from "../geometry3d/PointHelpers";
|
|
11
|
+
import { PolygonOps } from "../geometry3d/PolygonOps";
|
|
12
|
+
import { PolylineOps } from "../geometry3d/PolylineOps";
|
|
13
|
+
/**
|
|
14
|
+
* Class with static methods to triangulate various forms of possibly non-planar polygons.
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export class SpacePolygonTriangulation {
|
|
18
|
+
/**
|
|
19
|
+
* * Return a number which is:
|
|
20
|
+
* * 0 for collapsed (zero area) triangle
|
|
21
|
+
* * positive for non-zero area
|
|
22
|
+
* * larger is "better"
|
|
23
|
+
* * Specifically, return (if well defined) the area divided by summed squares of edge lengths.
|
|
24
|
+
* @param point0
|
|
25
|
+
* @param point1
|
|
26
|
+
* @param point2
|
|
27
|
+
*/
|
|
28
|
+
static spaceTriangleAspectRatio(point0, point1, point2) {
|
|
29
|
+
const crossProduct = point0.crossProductToPoints(point1, point2);
|
|
30
|
+
const area = 0.5 * crossProduct.magnitude();
|
|
31
|
+
const summedEdgeSquares = point0.distanceSquared(point1) + point1.distanceSquared(point2) + point2.distanceSquared(point0);
|
|
32
|
+
return Geometry.safeDivideFraction(area, summedEdgeSquares, 0.0);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* * Treat a space quad as two triangles with interior diagonal from point0 to point2
|
|
36
|
+
* * Return the smaller of the aspect ratios of the two triangles.
|
|
37
|
+
* * The quad edges proceed in the order [point0, point1, point2, point3]
|
|
38
|
+
* @param point0 first point of quad
|
|
39
|
+
* @param point1 second point of quad (diagonally opposite of point3)
|
|
40
|
+
* @param point2 third point (diagonally opposite point0)
|
|
41
|
+
* @param point3 fourth point
|
|
42
|
+
*/
|
|
43
|
+
static spaceQuadDiagonalAspectRatio(point0, point1, point2, point3) {
|
|
44
|
+
const q012 = this.spaceTriangleAspectRatio(point0, point1, point2);
|
|
45
|
+
const q023 = this.spaceTriangleAspectRatio(point0, point2, point3);
|
|
46
|
+
return Math.max(q012, q023);
|
|
47
|
+
}
|
|
48
|
+
/** "Triangulate" by cutting of the ear with best aspect ratio. Reject if successive normals have negative dot product with PolygonOps.AreaNormal */
|
|
49
|
+
static triangulateGreedyEarCut(points, announceLoopAndTriangles) {
|
|
50
|
+
const normalA = PolygonOps.areaNormal(points);
|
|
51
|
+
const triangles = [];
|
|
52
|
+
const myPoints = points.slice();
|
|
53
|
+
PolylineOps.removeClosurePoint(myPoints);
|
|
54
|
+
// first pass deals with entire array.
|
|
55
|
+
// each pass lops off one point.
|
|
56
|
+
for (; myPoints.length > 2;) {
|
|
57
|
+
// Find the ear candidate whose cross product vector has largest dot product (large area, best alignment with overall).
|
|
58
|
+
let bestRatio = -1.0;
|
|
59
|
+
let bestRatioIndex0 = 0;
|
|
60
|
+
let i0 = myPoints.length - 2;
|
|
61
|
+
let i1 = myPoints.length - 1;
|
|
62
|
+
let i2;
|
|
63
|
+
for (i2 = 0; i2 < myPoints.length; i0 = i1, i1 = i2, i2++) {
|
|
64
|
+
const ratio = this.spaceTriangleAspectRatio(myPoints[i0], myPoints[i1], myPoints[i2]);
|
|
65
|
+
const normalB = myPoints[i0].crossProductToPoints(myPoints[i1], myPoints[i2]);
|
|
66
|
+
if (normalB.dotProduct(normalA) > 0 && ratio > bestRatio) {
|
|
67
|
+
bestRatio = ratio;
|
|
68
|
+
bestRatioIndex0 = i0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (bestRatio <= 0.0)
|
|
72
|
+
return false;
|
|
73
|
+
// add the ear to the result
|
|
74
|
+
i0 = bestRatioIndex0;
|
|
75
|
+
i1 = (i0 + 1) % myPoints.length;
|
|
76
|
+
i2 = (i1 + 1) % myPoints.length;
|
|
77
|
+
const t = [];
|
|
78
|
+
t.push(myPoints[i0], myPoints[i1], myPoints[i2]);
|
|
79
|
+
// remove the middle point
|
|
80
|
+
myPoints.splice(i1, 1);
|
|
81
|
+
triangles.push(t);
|
|
82
|
+
}
|
|
83
|
+
announceLoopAndTriangles(points, triangles);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
static triangulateSimplestSpaceLoopGo(points, announceLoopAndTriangles, maxPerimeter) {
|
|
87
|
+
const n = Point3dArray.countNonDuplicates(points);
|
|
88
|
+
if (maxPerimeter !== undefined && Point3dArray.sumEdgeLengths(points, true, n) > maxPerimeter)
|
|
89
|
+
return false;
|
|
90
|
+
if (n < 3)
|
|
91
|
+
return false;
|
|
92
|
+
if (n === 3) {
|
|
93
|
+
if (this.spaceTriangleAspectRatio(points[0], points[1], points[2]) === 0)
|
|
94
|
+
return false;
|
|
95
|
+
// already a triangle . . .
|
|
96
|
+
announceLoopAndTriangles(points, [points.slice()]);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
if (n === 4) {
|
|
100
|
+
const d02 = this.spaceQuadDiagonalAspectRatio(points[0], points[1], points[2], points[3]);
|
|
101
|
+
const d13 = this.spaceQuadDiagonalAspectRatio(points[1], points[2], points[3], points[0]);
|
|
102
|
+
if (d02 === 0.0 && d13 === 0.0)
|
|
103
|
+
return false;
|
|
104
|
+
// announce the two triangles with better aspect ratios ....
|
|
105
|
+
if (d02 > d13) {
|
|
106
|
+
announceLoopAndTriangles(points, [[points[0], points[1], points[2]], [points[2], points[3], points[0]]]);
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
announceLoopAndTriangles(points, [[points[0], points[1], points[3]], [points[3], points[1], points[2]]]);
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return this.triangulateGreedyEarCut(points, announceLoopAndTriangles);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* * Emit triangles for a (possibly non-planar) loop for various simple cases:
|
|
118
|
+
* * only 3 points: just emit that triangle.
|
|
119
|
+
* * only 4 points: split across a diagonal, choosing the one with better aspect ratios of its two triangles.
|
|
120
|
+
* * BUT
|
|
121
|
+
* * do not complete the triangulation if perimeter is larger than maxPerimeter (i.e. only consider small areas)
|
|
122
|
+
* * Hence it is expected that the caller will use this as the first attempt, possibly followed by calls to other more adventurous methods.
|
|
123
|
+
*/
|
|
124
|
+
static triangulateSimplestSpaceLoop(loop, announceLoopAndTriangles, maxPerimeter) {
|
|
125
|
+
if (loop instanceof LineString3d)
|
|
126
|
+
return this.triangulateSimplestSpaceLoopGo(loop.points, announceLoopAndTriangles, maxPerimeter);
|
|
127
|
+
// (array case by exhaustion)
|
|
128
|
+
return this.triangulateSimplestSpaceLoopGo(loop, announceLoopAndTriangles, maxPerimeter);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=SpaceTriangulation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpaceTriangulation.js","sourceRoot":"","sources":["../../../src/topology/SpaceTriangulation.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Topology\r\n */\r\n\r\nimport { LineString3d } from \"../curve/LineString3d\";\r\nimport { Geometry } from \"../Geometry\";\r\nimport { Point3d } from \"../geometry3d/Point3dVector3d\";\r\nimport { Point3dArray } from \"../geometry3d/PointHelpers\";\r\nimport {PolygonOps} from \"../geometry3d/PolygonOps\";\r\nimport {PolylineOps} from \"../geometry3d/PolylineOps\";\r\ntype AnnounceLoopAndTrianglesFunction = (loop: Point3d[], triangles: Point3d[][]) => void;\r\n\r\n/**\r\n * Class with static methods to triangulate various forms of possibly non-planar polygons.\r\n * @public\r\n */\r\nexport class SpacePolygonTriangulation {\r\n\r\n /**\r\n * * Return a number which is:\r\n * * 0 for collapsed (zero area) triangle\r\n * * positive for non-zero area\r\n * * larger is \"better\"\r\n * * Specifically, return (if well defined) the area divided by summed squares of edge lengths.\r\n * @param point0\r\n * @param point1\r\n * @param point2\r\n */\r\n public static spaceTriangleAspectRatio(point0: Point3d, point1: Point3d, point2: Point3d): number {\r\n const crossProduct = point0.crossProductToPoints (point1, point2);\r\n const area = 0.5 * crossProduct.magnitude ();\r\n const summedEdgeSquares = point0.distanceSquared (point1) + point1.distanceSquared (point2) + point2.distanceSquared (point0);\r\n return Geometry.safeDivideFraction (area, summedEdgeSquares, 0.0);\r\n }\r\n /**\r\n * * Treat a space quad as two triangles with interior diagonal from point0 to point2\r\n * * Return the smaller of the aspect ratios of the two triangles.\r\n * * The quad edges proceed in the order [point0, point1, point2, point3]\r\n * @param point0 first point of quad\r\n * @param point1 second point of quad (diagonally opposite of point3)\r\n * @param point2 third point (diagonally opposite point0)\r\n * @param point3 fourth point\r\n */\r\n public static spaceQuadDiagonalAspectRatio(point0: Point3d, point1: Point3d, point2: Point3d, point3: Point3d): number{\r\n const q012 = this.spaceTriangleAspectRatio (point0, point1, point2);\r\n const q023 = this.spaceTriangleAspectRatio (point0, point2, point3);\r\n return Math.max (q012, q023);\r\n }\r\n /** \"Triangulate\" by cutting of the ear with best aspect ratio. Reject if successive normals have negative dot product with PolygonOps.AreaNormal */\r\n public static triangulateGreedyEarCut(points: Point3d[], announceLoopAndTriangles: AnnounceLoopAndTrianglesFunction): boolean{\r\n const normalA = PolygonOps.areaNormal (points);\r\n const triangles: Point3d[][] = [];\r\n const myPoints = points.slice ();\r\n PolylineOps.removeClosurePoint (myPoints);\r\n // first pass deals with entire array.\r\n // each pass lops off one point.\r\n for (;myPoints.length > 2;){\r\n // Find the ear candidate whose cross product vector has largest dot product (large area, best alignment with overall).\r\n let bestRatio = -1.0;\r\n let bestRatioIndex0 = 0;\r\n let i0 = myPoints.length - 2;\r\n let i1 = myPoints.length - 1;\r\n let i2;\r\n for (i2 = 0; i2 < myPoints.length; i0 = i1, i1 = i2, i2++){\r\n const ratio = this.spaceTriangleAspectRatio (myPoints[i0], myPoints[i1], myPoints[i2]);\r\n const normalB = myPoints[i0].crossProductToPoints (myPoints[i1], myPoints[i2]);\r\n if (normalB.dotProduct (normalA) > 0 && ratio > bestRatio){\r\n bestRatio = ratio;\r\n bestRatioIndex0 = i0;\r\n }\r\n }\r\n if (bestRatio <= 0.0)\r\n return false;\r\n // add the ear to the result\r\n i0 = bestRatioIndex0;\r\n i1 = (i0 + 1) % myPoints.length;\r\n i2 = (i1 + 1) % myPoints.length;\r\n const t = [];\r\n t.push (myPoints[i0], myPoints[i1], myPoints[i2]);\r\n // remove the middle point\r\n myPoints.splice (i1, 1);\r\n triangles.push(t);\r\n }\r\n announceLoopAndTriangles (points, triangles);\r\n return true;\r\n }\r\n\r\n private static triangulateSimplestSpaceLoopGo(points: Point3d[], announceLoopAndTriangles: AnnounceLoopAndTrianglesFunction,\r\n maxPerimeter: number | undefined): boolean{\r\n const n = Point3dArray.countNonDuplicates (points);\r\n if (maxPerimeter !== undefined && Point3dArray.sumEdgeLengths (points, true, n) > maxPerimeter)\r\n return false;\r\n if (n < 3)\r\n return false;\r\n if (n === 3){\r\n if (this.spaceTriangleAspectRatio (points[0], points[1], points[2]) === 0)\r\n return false;\r\n // already a triangle . . .\r\n announceLoopAndTriangles (points, [points.slice ()]);\r\n return true;\r\n }\r\n if (n === 4){\r\n const d02 = this.spaceQuadDiagonalAspectRatio (points[0], points[1], points[2], points[3]);\r\n const d13 = this.spaceQuadDiagonalAspectRatio (points[1], points[2], points[3], points[0]);\r\n if (d02 === 0.0 && d13 === 0.0)\r\n return false;\r\n // announce the two triangles with better aspect ratios ....\r\n if (d02 > d13){\r\n announceLoopAndTriangles (points, [[points[0], points[1], points[2]], [points[2], points[3], points[0]]]);\r\n return true;\r\n } else {\r\n announceLoopAndTriangles (points, [[points[0], points[1], points[3]], [points[3], points[1], points[2]]]);\r\n return true;\r\n }\r\n }\r\n return this.triangulateGreedyEarCut (points, announceLoopAndTriangles);\r\n }\r\n /**\r\n * * Emit triangles for a (possibly non-planar) loop for various simple cases:\r\n * * only 3 points: just emit that triangle.\r\n * * only 4 points: split across a diagonal, choosing the one with better aspect ratios of its two triangles.\r\n * * BUT\r\n * * do not complete the triangulation if perimeter is larger than maxPerimeter (i.e. only consider small areas)\r\n * * Hence it is expected that the caller will use this as the first attempt, possibly followed by calls to other more adventurous methods.\r\n */\r\n public static triangulateSimplestSpaceLoop(loop: Point3d [] | LineString3d,\r\n announceLoopAndTriangles: AnnounceLoopAndTrianglesFunction,\r\n maxPerimeter?: number): boolean{\r\n if (loop instanceof LineString3d)\r\n return this.triangulateSimplestSpaceLoopGo (loop.points, announceLoopAndTriangles, maxPerimeter);\r\n // (array case by exhaustion)\r\n return this.triangulateSimplestSpaceLoopGo (loop, announceLoopAndTriangles, maxPerimeter);\r\n }\r\n\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/core-geometry",
|
|
3
|
-
"version": "3.4.0-dev.
|
|
3
|
+
"version": "3.4.0-dev.35",
|
|
4
4
|
"description": "iTwin.js Core Geometry library",
|
|
5
5
|
"main": "lib/cjs/core-geometry.js",
|
|
6
6
|
"module": "lib/esm/core-geometry.js",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"url": "http://www.bentley.com"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@itwin/build-tools": "3.4.0-dev.
|
|
26
|
-
"@itwin/eslint-plugin": "3.4.0-dev.
|
|
25
|
+
"@itwin/build-tools": "3.4.0-dev.35",
|
|
26
|
+
"@itwin/eslint-plugin": "3.4.0-dev.35",
|
|
27
27
|
"@types/chai": "4.3.1",
|
|
28
28
|
"@types/flatbuffers": "~1.10.0",
|
|
29
29
|
"@types/mocha": "^8.2.2",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"typescript": "~4.4.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@itwin/core-bentley": "3.4.0-dev.
|
|
41
|
+
"@itwin/core-bentley": "3.4.0-dev.35",
|
|
42
42
|
"flatbuffers": "~1.12.0"
|
|
43
43
|
},
|
|
44
44
|
"nyc": {
|