@itwin/core-geometry 5.0.0-dev.14 → 5.0.0-dev.16

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.
Files changed (95) hide show
  1. package/lib/cjs/bspline/BSplineCurveOps.d.ts.map +1 -1
  2. package/lib/cjs/bspline/BSplineCurveOps.js +18 -21
  3. package/lib/cjs/bspline/BSplineCurveOps.js.map +1 -1
  4. package/lib/cjs/curve/Arc3d.d.ts +5 -2
  5. package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
  6. package/lib/cjs/curve/Arc3d.js +9 -2
  7. package/lib/cjs/curve/Arc3d.js.map +1 -1
  8. package/lib/cjs/curve/CurveFactory.d.ts +68 -47
  9. package/lib/cjs/curve/CurveFactory.d.ts.map +1 -1
  10. package/lib/cjs/curve/CurveFactory.js +99 -70
  11. package/lib/cjs/curve/CurveFactory.js.map +1 -1
  12. package/lib/cjs/curve/StrokeOptions.d.ts +1 -1
  13. package/lib/cjs/curve/StrokeOptions.d.ts.map +1 -1
  14. package/lib/cjs/curve/StrokeOptions.js.map +1 -1
  15. package/lib/cjs/geometry3d/AngleSweep.d.ts +1 -1
  16. package/lib/cjs/geometry3d/AngleSweep.d.ts.map +1 -1
  17. package/lib/cjs/geometry3d/AngleSweep.js +1 -1
  18. package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
  19. package/lib/cjs/geometry3d/GrowableXYZArray.d.ts +32 -10
  20. package/lib/cjs/geometry3d/GrowableXYZArray.d.ts.map +1 -1
  21. package/lib/cjs/geometry3d/GrowableXYZArray.js +54 -16
  22. package/lib/cjs/geometry3d/GrowableXYZArray.js.map +1 -1
  23. package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts +13 -2
  24. package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
  25. package/lib/cjs/geometry3d/IndexedXYZCollection.js +24 -10
  26. package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
  27. package/lib/cjs/geometry3d/Matrix3d.d.ts +3 -4
  28. package/lib/cjs/geometry3d/Matrix3d.d.ts.map +1 -1
  29. package/lib/cjs/geometry3d/Matrix3d.js +3 -4
  30. package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
  31. package/lib/cjs/geometry3d/Point3dArrayCarrier.js +1 -1
  32. package/lib/cjs/geometry3d/Point3dArrayCarrier.js.map +1 -1
  33. package/lib/cjs/geometry3d/Point3dVector3d.d.ts +4 -4
  34. package/lib/cjs/geometry3d/Point3dVector3d.js +4 -4
  35. package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
  36. package/lib/cjs/geometry3d/PolylineOps.d.ts +7 -4
  37. package/lib/cjs/geometry3d/PolylineOps.d.ts.map +1 -1
  38. package/lib/cjs/geometry3d/PolylineOps.js +7 -4
  39. package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
  40. package/lib/cjs/polyface/PolyfaceBuilder.d.ts +13 -6
  41. package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
  42. package/lib/cjs/polyface/PolyfaceBuilder.js +42 -25
  43. package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
  44. package/lib/cjs/serialization/GeometrySamples.d.ts +5 -5
  45. package/lib/cjs/serialization/GeometrySamples.d.ts.map +1 -1
  46. package/lib/cjs/serialization/GeometrySamples.js +5 -5
  47. package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
  48. package/lib/esm/bspline/BSplineCurveOps.d.ts.map +1 -1
  49. package/lib/esm/bspline/BSplineCurveOps.js +18 -21
  50. package/lib/esm/bspline/BSplineCurveOps.js.map +1 -1
  51. package/lib/esm/curve/Arc3d.d.ts +5 -2
  52. package/lib/esm/curve/Arc3d.d.ts.map +1 -1
  53. package/lib/esm/curve/Arc3d.js +9 -2
  54. package/lib/esm/curve/Arc3d.js.map +1 -1
  55. package/lib/esm/curve/CurveFactory.d.ts +68 -47
  56. package/lib/esm/curve/CurveFactory.d.ts.map +1 -1
  57. package/lib/esm/curve/CurveFactory.js +99 -70
  58. package/lib/esm/curve/CurveFactory.js.map +1 -1
  59. package/lib/esm/curve/StrokeOptions.d.ts +1 -1
  60. package/lib/esm/curve/StrokeOptions.d.ts.map +1 -1
  61. package/lib/esm/curve/StrokeOptions.js.map +1 -1
  62. package/lib/esm/geometry3d/AngleSweep.d.ts +1 -1
  63. package/lib/esm/geometry3d/AngleSweep.d.ts.map +1 -1
  64. package/lib/esm/geometry3d/AngleSweep.js +1 -1
  65. package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
  66. package/lib/esm/geometry3d/GrowableXYZArray.d.ts +32 -10
  67. package/lib/esm/geometry3d/GrowableXYZArray.d.ts.map +1 -1
  68. package/lib/esm/geometry3d/GrowableXYZArray.js +54 -16
  69. package/lib/esm/geometry3d/GrowableXYZArray.js.map +1 -1
  70. package/lib/esm/geometry3d/IndexedXYZCollection.d.ts +13 -2
  71. package/lib/esm/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
  72. package/lib/esm/geometry3d/IndexedXYZCollection.js +24 -10
  73. package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
  74. package/lib/esm/geometry3d/Matrix3d.d.ts +3 -4
  75. package/lib/esm/geometry3d/Matrix3d.d.ts.map +1 -1
  76. package/lib/esm/geometry3d/Matrix3d.js +3 -4
  77. package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
  78. package/lib/esm/geometry3d/Point3dArrayCarrier.js +1 -1
  79. package/lib/esm/geometry3d/Point3dArrayCarrier.js.map +1 -1
  80. package/lib/esm/geometry3d/Point3dVector3d.d.ts +4 -4
  81. package/lib/esm/geometry3d/Point3dVector3d.js +4 -4
  82. package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
  83. package/lib/esm/geometry3d/PolylineOps.d.ts +7 -4
  84. package/lib/esm/geometry3d/PolylineOps.d.ts.map +1 -1
  85. package/lib/esm/geometry3d/PolylineOps.js +7 -4
  86. package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
  87. package/lib/esm/polyface/PolyfaceBuilder.d.ts +13 -6
  88. package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
  89. package/lib/esm/polyface/PolyfaceBuilder.js +42 -25
  90. package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
  91. package/lib/esm/serialization/GeometrySamples.d.ts +5 -5
  92. package/lib/esm/serialization/GeometrySamples.d.ts.map +1 -1
  93. package/lib/esm/serialization/GeometrySamples.js +5 -5
  94. package/lib/esm/serialization/GeometrySamples.js.map +1 -1
  95. package/package.json +3 -3
@@ -23,13 +23,14 @@ import { Path } from "./Path";
23
23
  import { IntegratedSpiralTypeName } from "./spiral/TransitionSpiral3d";
24
24
  import { StrokeOptions } from "./StrokeOptions";
25
25
  /**
26
- * Interface to carry parallel arrays of planes and sections, and optional geometry assembled from them, as returned by [CurveFactory.createMiteredSweepSections].
26
+ * Interface to carry parallel arrays of planes and sections, and optional geometry assembled from them,
27
+ * as returned by [CurveFactory.createMiteredSweepSections].
27
28
  * @public
28
29
  */
29
30
  export interface SectionSequenceWithPlanes {
30
- /** the plane of each section */
31
+ /** The plane of each section. */
31
32
  planes: Plane3dByOriginAndUnitNormal[];
32
- /** section curve projected onto the corresponding plane */
33
+ /** Section curve projected onto the corresponding plane. */
33
34
  sections: AnyCurve[];
34
35
  /**
35
36
  * Optional `RuledSweep` generated from the sections.
@@ -64,13 +65,25 @@ export interface MiteredSweepOptions {
64
65
  strokeOptions?: StrokeOptions;
65
66
  /** Whether to cap the ruled sweep if outputting a ruled sweep or mesh. Default value is `false`. */
66
67
  capped?: boolean;
68
+ /**
69
+ * If the centerline is not physically closed, the first section's normal is aligned to this vector (typically points
70
+ * toward the swept geometry). If the centerline is physically closed, the first section's normal is aligned to this
71
+ * vector if and only if endTangent is provided and is equal to startTangent.
72
+ */
73
+ startTangent?: Vector3d;
74
+ /**
75
+ * If the centerline is not physically closed, the last section's normal is aligned to this vector (typically points
76
+ * away from the swept geometry). If the centerline is physically closed, the last section's normal is aligned to this
77
+ * vector if and only if startTangent is provided and is equal to endTangent.
78
+ */
79
+ endTangent?: Vector3d;
67
80
  }
68
81
  /**
69
82
  * The `CurveFactory` class contains methods for specialized curve constructions.
70
83
  * @public
71
84
  */
72
85
  export declare class CurveFactory {
73
- /** (cautiously) construct and save a line segment between fractional positions. */
86
+ /** (Cautiously) construct and save a line segment between fractional positions. */
74
87
  private static addPartialSegment;
75
88
  /**
76
89
  * Create a circular arc defined by start point, tangent at start point, and end point.
@@ -89,23 +102,25 @@ export declare class CurveFactory {
89
102
  * @param allowBackupAlongEdge true to allow edges to be created going "backwards" along edges if needed to create the blend.
90
103
  */
91
104
  static createFilletsInLineString(points: LineString3d | IndexedXYZCollection | Point3d[], radius: number | number[], allowBackupAlongEdge?: boolean): Path | undefined;
92
- /** Create a `Loop` with given xy corners and fixed z.
105
+ /**
106
+ * Create a `Loop` with given xy corners and fixed z.
93
107
  * * The corners always proceed counter clockwise from lower left.
94
108
  * * If the radius is too large for the outer rectangle size, it is reduced to half of the the smaller x or y size.
95
- */
109
+ */
96
110
  static createRectangleXY(x0: number, y0: number, x1: number, y1: number, z?: number, filletRadius?: number): Loop;
97
111
  /**
98
112
  * If `arcB` is a continuation of `arcA`, extend `arcA` (in place) to include the range of `arcB`
99
113
  * * This only succeeds if the two arcs are part of identical complete arcs and end of `arcA` matches the beginning of `arcB`.
100
- * @param arcA first arc, modified in place
101
- * @param arcB second arc, unmodified
102
- * @param allowReversed whether to consolidate even when second arc is reversed
103
- * @returns whether `arcA` was modified
114
+ * @param arcA first arc, modified in place.
115
+ * @param arcB second arc, unmodified.
116
+ * @param allowReversed whether to consolidate even when second arc is reversed.
117
+ * @returns whether `arcA` was modified.
104
118
  */
105
119
  static appendToArcInPlace(arcA: Arc3d, arcB: Arc3d, allowReverse?: boolean): boolean;
106
120
  /**
107
121
  * Return a `Path` containing arcs are on the surface of an ellipsoid and pass through a sequence of points.
108
- * * Each arc passes through the two given endpoints and in the plane containing the true surface normal at given `fractionForIntermediateNormal`
122
+ * * Each arc passes through the two given endpoints and in the plane containing the true surface normal at
123
+ * given `fractionForIntermediateNormal`
109
124
  * @param ellipsoid
110
125
  * @param pathPoints
111
126
  * @param fractionForIntermediateNormal fractional position for surface normal used to create the section plane.
@@ -114,36 +129,47 @@ export declare class CurveFactory {
114
129
  private static appendGeometryQueryArray;
115
130
  /**
116
131
  * Create solid primitives for pipe segments (e.g. Cone or TorusPipe) around line and arc primitives.
117
- * @param centerline centerline geometry/
132
+ * @param centerline centerline geometry.
118
133
  * @param pipeRadius radius of pipe.
119
134
  */
120
135
  static createPipeSegments(centerline: CurvePrimitive | CurveChain, pipeRadius: number): GeometryQuery | GeometryQuery[] | undefined;
121
136
  /**
122
- * * Create section arcs for mitered pipe.
123
- * * At each end of each pipe, the pipe is cut by the plane that bisects the angle between successive pipe centerlines.
124
- * * The arc definitions are constructed so that lines between corresponding fractional positions on the arcs are
125
- * axial lines on the pipes.
126
- * * This means that each arc definition axes (aka vector0 and vector90) are _not_ perpendicular to each other.
127
- * * Circular or elliptical pipe cross sections can be specified by supplying either a radius, a pair of semi-axis lengths, or a full Arc3d.
128
- * * For semi-axis length input, x corresponds to an ellipse local axis nominally situated parallel to the xy-plane.
129
- * * The center of Arc3d input is translated to the centerline start point to act as initial cross section.
130
- * @param centerline centerline of pipe
131
- * @param sectionData circle radius, ellipse semi-axis lengths, or full Arc3d
137
+ * Create section arcs for mitered pipe.
138
+ * * At the end of each pipe segment, the pipe is mitered by the plane that bisects the angle between successive
139
+ * centerline segments.
140
+ * * The section arcs are constructed so that lines between corresponding fractional positions on the arcs are
141
+ * axial lines on the pipes.
142
+ * * This means that the initial arc's vector0 and vector90 lengths and angular separation are _not_ preserved in
143
+ * the section arcs.
144
+ * * Circular or elliptical pipe cross sections can be specified by supplying either a radius, a pair of semi-axis
145
+ * lengths, or an Arc3d:
146
+ * * For semi-axis length input, x and y correspond to ellipse local axes perpendicular to each other and to the
147
+ * start tangent.
148
+ * * For Arc3d input, the center is translated to the centerline start point, but otherwise the arc is used as-is
149
+ * for the first section. For best results, the arc should be perpendicular to the centerline start tangent.
150
+ * @param centerline centerline of pipe. For best results, ensure no successive duplicate points with e.g.,
151
+ * [[GrowableXYZArray.createCompressed]].
152
+ * @param sectionData circle radius, ellipse semi-axis lengths, or full Arc3d (if not full, function makes it full).
132
153
  */
133
154
  static createMiteredPipeSections(centerline: IndexedXYZCollection, sectionData: number | XAndY | Arc3d): Arc3d[];
134
155
  /**
135
156
  * Sweep the initialSection along each segment of the centerLine until it hits the bisector plane at the next vertex.
136
157
  * * The caller should place the initialSection on a plane perpendicular to the first edge.
137
158
  * * This plane is commonly (but not necessarily) through the start point itself.
138
- * * If the geometry is not "on a perpendicular plane", the output geometry will still be flattened onto the various planes.
139
- * * In the "open path" case (i.e when wrapIfPhysicallyClosed is false or the path does not have matched first and last points)
140
- * the first/last output plane will be at the start/end of the first/last edge and on a perpendicular plane.
141
- * * In the "closed path" case, the output plane for the first and last point is the bisector of the start and end planes from the "open path" case,
142
- * and the first/last section geometry may be different from `initialSection`.
143
- * * The centerline path does NOT have to be planar, however twisting effects effects will appear in the various bisector planes.
144
- * @param centerline sweep path, e.g., as stroked from a smooth centerline curve
145
- * @param initialSection profile curve to be swept. As noted above, this should be on a plane perpendicular to the first segment of the centerline.
146
- * @param options options for computation and output
159
+ * * If the initialSection is not "on a perpendicular plane", the output geometry will still be flattened onto the
160
+ * various planes.
161
+ * * In the "open path" case (i.e when `wrapIfPhysicallyClosed` is false or the path does not have matched first and
162
+ * last points), the first/last output plane will be at the start/end of the first/last edge and on a perpendicular
163
+ * plane.
164
+ * * In the "closed path" case, if start/edn tangents are not provided in the `options`, then the output plane for the
165
+ * first and last point is the bisector of the start and end planes from the "open path" case, and the first/last
166
+ * section geometry may be different from `initialSection`.
167
+ * * The centerline path does NOT have to be planar, however twisting effects effects will appear in the various bisector
168
+ * planes.
169
+ * @param centerline sweep path, e.g., as stroked from a smooth centerline curve.
170
+ * @param initialSection profile curve to be swept. As noted above, this should be on a plane perpendicular to the
171
+ * first segment of the centerline.
172
+ * @param options options for computation and output.
147
173
  * @return array of sections, starting with `initialSection` projected along the first edge to the first plane.
148
174
  */
149
175
  static createMiteredSweepSections(centerline: IndexedXYZCollection | Point3d[], initialSection: AnyCurve, options: MiteredSweepOptions): SectionSequenceWithPlanes | undefined;
@@ -160,11 +186,11 @@ export declare class CurveFactory {
160
186
  /**
161
187
  * Compute 2 spirals (all in XY) for a symmetric line-to-line transition.
162
188
  * * First spiral begins at given start point.
163
- * * first tangent aims at shoulder
189
+ * * first tangent aims at shoulder.
164
190
  * * outbound spiral joins line from shoulder to target.
165
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
191
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
166
192
  * @param startPoint inbound start point.
167
- * @param shoulder point target point for (both) spiral-to-line tangencies
193
+ * @param shoulder point target point for (both) spiral-to-line tangencies.
168
194
  * @return array with the computed spirals, or undefined if failure.
169
195
  */
170
196
  static createLineSpiralSpiralLine(spiralType: IntegratedSpiralTypeName, startPoint: Point3d, shoulderPoint: Point3d, targetPoint: Point3d): GeometryQuery[] | undefined;
@@ -172,30 +198,25 @@ export declare class CurveFactory {
172
198
  * Compute 2 spirals (all in XY) for a symmetric line-to-line transition.
173
199
  * * Spiral length is given.
174
200
  * * tangency points float on both lines.
175
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
201
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
176
202
  * @param pointA inbound start point.
177
- * @param shoulder point target point for (both) spiral-to-line tangencies
203
+ * @param shoulder point target point for (both) spiral-to-line tangencies.
178
204
  * @param spiralLength for each part of the spiral pair.
179
205
  * @return array with the computed spirals, or undefined if failure.
180
206
  */
181
207
  static createLineSpiralSpiralLineWithSpiralLength(spiralType: IntegratedSpiralTypeName, pointA: Point3d, pointB: Point3d, pointC: Point3d, spiralLength: number): GeometryQuery[] | undefined;
182
208
  /**
183
209
  * Compute 2 spirals and an arc (all in XY) for a symmetric line-to-line transition.
184
- * Spiral lengths and arc radius are given. (e.g. from design speed standards.)
185
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
210
+ * Spiral lengths and arc radius are given (e.g., from design speed standards).
211
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
186
212
  * @param pointA inbound start point.
187
- * @param pointB shoulder (target) point for (both) spiral-to-line tangencies
188
- * @param lengthA inbound spiral length
189
- * @param lengthB outbound spiral length
213
+ * @param pointB shoulder (target) point for (both) spiral-to-line tangencies.
214
+ * @param lengthA inbound spiral length.
215
+ * @param lengthB outbound spiral length.
190
216
  * @return array with the computed spirals, or undefined if failure.
191
217
  */
192
218
  static createLineSpiralArcSpiralLine(spiralType: IntegratedSpiralTypeName, pointA: Point3d, pointB: Point3d, pointC: Point3d, lengthA: number, lengthB: number, arcRadius: number): GeometryQuery[] | undefined;
193
- /**
194
- * Return the intersection point of 3 planes.
195
- * @param planeA
196
- * @param planeB
197
- * @param planeC
198
- */
219
+ /** Return the intersection point of 3 planes. */
199
220
  static planePlaneIntersectionRay(planeA: PlaneAltitudeEvaluator, planeB: PlaneAltitudeEvaluator): Ray3d | undefined;
200
221
  }
201
222
  //# sourceMappingURL=CurveFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CurveFactory.d.ts","sourceRoot":"","sources":["../../../src/curve/CurveFactory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CurveFactory.d.ts","sourceRoot":"","sources":["../../../src/curve/CurveFactory.ts"],"names":[],"mappings":"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"}
@@ -49,7 +49,7 @@ export var MiteredSweepOutputSelect;
49
49
  * @public
50
50
  */
51
51
  export class CurveFactory {
52
- /** (cautiously) construct and save a line segment between fractional positions. */
52
+ /** (Cautiously) construct and save a line segment between fractional positions. */
53
53
  static addPartialSegment(path, allowBackup, pointA, pointB, fraction0, fraction1) {
54
54
  if (allowBackup || (fraction1 > fraction0)) {
55
55
  if (pointA !== undefined && pointB !== undefined && !Geometry.isAlmostEqualNumber(fraction0, fraction1))
@@ -146,10 +146,11 @@ export class CurveFactory {
146
146
  }
147
147
  return path;
148
148
  }
149
- /** Create a `Loop` with given xy corners and fixed z.
149
+ /**
150
+ * Create a `Loop` with given xy corners and fixed z.
150
151
  * * The corners always proceed counter clockwise from lower left.
151
152
  * * If the radius is too large for the outer rectangle size, it is reduced to half of the the smaller x or y size.
152
- */
153
+ */
153
154
  static createRectangleXY(x0, y0, x1, y1, z = 0, filletRadius) {
154
155
  let radius = Geometry.correctSmallMetricDistance(filletRadius);
155
156
  const xMin = Math.min(x0, x1);
@@ -158,7 +159,13 @@ export class CurveFactory {
158
159
  const yMax = Math.max(y0, y1);
159
160
  radius = Math.min(Math.abs(radius), 0.5 * (xMax - xMin), 0.5 * (yMax - yMin));
160
161
  if (radius === 0.0)
161
- return Loop.createPolygon([Point3d.create(xMin, yMin, z), Point3d.create(xMax, yMin, z), Point3d.create(xMax, yMax, z), Point3d.create(xMin, yMax, z), Point3d.create(xMin, yMin, z)]);
162
+ return Loop.createPolygon([
163
+ Point3d.create(xMin, yMin, z),
164
+ Point3d.create(xMax, yMin, z),
165
+ Point3d.create(xMax, yMax, z),
166
+ Point3d.create(xMin, yMax, z),
167
+ Point3d.create(xMin, yMin, z),
168
+ ]);
162
169
  else {
163
170
  const vectorU = Vector3d.create(radius, 0, 0);
164
171
  const vectorV = Vector3d.create(0, radius, 0);
@@ -166,7 +173,12 @@ export class CurveFactory {
166
173
  const y0A = yMin + radius;
167
174
  const x1A = xMax - radius;
168
175
  const y1A = yMax - radius;
169
- const centers = [Point3d.create(x1A, y1A, z), Point3d.create(x0A, y1A, z), Point3d.create(x0A, y0A, z), Point3d.create(x1A, y0A, z)];
176
+ const centers = [
177
+ Point3d.create(x1A, y1A, z),
178
+ Point3d.create(x0A, y1A, z),
179
+ Point3d.create(x0A, y0A, z),
180
+ Point3d.create(x1A, y0A, z),
181
+ ];
170
182
  const loop = Loop.create();
171
183
  for (let i = 0; i < 4; i++) {
172
184
  const center = centers[i];
@@ -186,10 +198,10 @@ export class CurveFactory {
186
198
  /**
187
199
  * If `arcB` is a continuation of `arcA`, extend `arcA` (in place) to include the range of `arcB`
188
200
  * * This only succeeds if the two arcs are part of identical complete arcs and end of `arcA` matches the beginning of `arcB`.
189
- * @param arcA first arc, modified in place
190
- * @param arcB second arc, unmodified
191
- * @param allowReversed whether to consolidate even when second arc is reversed
192
- * @returns whether `arcA` was modified
201
+ * @param arcA first arc, modified in place.
202
+ * @param arcB second arc, unmodified.
203
+ * @param allowReversed whether to consolidate even when second arc is reversed.
204
+ * @returns whether `arcA` was modified.
193
205
  */
194
206
  static appendToArcInPlace(arcA, arcB, allowReverse = false) {
195
207
  if (arcA.center.isAlmostEqual(arcB.center)) {
@@ -205,7 +217,7 @@ export class CurveFactory {
205
217
  arcA.sweep.setStartEndRadians(arcA.sweep.startRadians, arcA.sweep.startRadians + arcA.sweep.sweepRadians + sweepSign * arcB.sweep.sweepRadians);
206
218
  return true;
207
219
  }
208
- // Also ok if negated tangent . ..
220
+ // Also ok if negated tangent
209
221
  if (allowReverse) {
210
222
  startB.direction.scaleInPlace(-1.0);
211
223
  if (endA.isAlmostEqual(startB)) {
@@ -218,7 +230,8 @@ export class CurveFactory {
218
230
  }
219
231
  /**
220
232
  * Return a `Path` containing arcs are on the surface of an ellipsoid and pass through a sequence of points.
221
- * * Each arc passes through the two given endpoints and in the plane containing the true surface normal at given `fractionForIntermediateNormal`
233
+ * * Each arc passes through the two given endpoints and in the plane containing the true surface normal at
234
+ * given `fractionForIntermediateNormal`
222
235
  * @param ellipsoid
223
236
  * @param pathPoints
224
237
  * @param fractionForIntermediateNormal fractional position for surface normal used to create the section plane.
@@ -241,7 +254,7 @@ export class CurveFactory {
241
254
  }
242
255
  /**
243
256
  * Create solid primitives for pipe segments (e.g. Cone or TorusPipe) around line and arc primitives.
244
- * @param centerline centerline geometry/
257
+ * @param centerline centerline geometry.
245
258
  * @param pipeRadius radius of pipe.
246
259
  */
247
260
  static createPipeSegments(centerline, pipeRadius) {
@@ -267,16 +280,22 @@ export class CurveFactory {
267
280
  return undefined;
268
281
  }
269
282
  /**
270
- * * Create section arcs for mitered pipe.
271
- * * At each end of each pipe, the pipe is cut by the plane that bisects the angle between successive pipe centerlines.
272
- * * The arc definitions are constructed so that lines between corresponding fractional positions on the arcs are
273
- * axial lines on the pipes.
274
- * * This means that each arc definition axes (aka vector0 and vector90) are _not_ perpendicular to each other.
275
- * * Circular or elliptical pipe cross sections can be specified by supplying either a radius, a pair of semi-axis lengths, or a full Arc3d.
276
- * * For semi-axis length input, x corresponds to an ellipse local axis nominally situated parallel to the xy-plane.
277
- * * The center of Arc3d input is translated to the centerline start point to act as initial cross section.
278
- * @param centerline centerline of pipe
279
- * @param sectionData circle radius, ellipse semi-axis lengths, or full Arc3d
283
+ * Create section arcs for mitered pipe.
284
+ * * At the end of each pipe segment, the pipe is mitered by the plane that bisects the angle between successive
285
+ * centerline segments.
286
+ * * The section arcs are constructed so that lines between corresponding fractional positions on the arcs are
287
+ * axial lines on the pipes.
288
+ * * This means that the initial arc's vector0 and vector90 lengths and angular separation are _not_ preserved in
289
+ * the section arcs.
290
+ * * Circular or elliptical pipe cross sections can be specified by supplying either a radius, a pair of semi-axis
291
+ * lengths, or an Arc3d:
292
+ * * For semi-axis length input, x and y correspond to ellipse local axes perpendicular to each other and to the
293
+ * start tangent.
294
+ * * For Arc3d input, the center is translated to the centerline start point, but otherwise the arc is used as-is
295
+ * for the first section. For best results, the arc should be perpendicular to the centerline start tangent.
296
+ * @param centerline centerline of pipe. For best results, ensure no successive duplicate points with e.g.,
297
+ * [[GrowableXYZArray.createCompressed]].
298
+ * @param sectionData circle radius, ellipse semi-axis lengths, or full Arc3d (if not full, function makes it full).
280
299
  */
281
300
  static createMiteredPipeSections(centerline, sectionData) {
282
301
  const arcs = [];
@@ -285,15 +304,15 @@ export class CurveFactory {
285
304
  const vector0 = Vector3d.create();
286
305
  const vector90 = Vector3d.create();
287
306
  const vectorBC = Vector3d.create();
288
- const currentCenter = Point3d.create();
289
- centerline.vectorIndexIndex(0, 1, vectorBC);
290
- centerline.getPoint3dAtUncheckedPointIndex(0, currentCenter);
291
- let initialSection;
307
+ const sweep = AngleSweep.create360();
308
+ centerline.vectorIndexIndex(0, 1, vectorBC); // initially, the start tangent
292
309
  if (sectionData instanceof Arc3d) {
293
- initialSection = sectionData.clone();
294
- initialSection.center.setFrom(currentCenter);
295
310
  vector0.setFrom(sectionData.vector0);
296
311
  vector90.setFrom(sectionData.vector90);
312
+ sweep.setFrom(sectionData.sweep); // allow e.g., half-pipe
313
+ const sectionFacesForward = sectionData.matrixRef.columnDotXYZ(AxisIndex.Z, vectorBC.x, vectorBC.y, vectorBC.z) > 0;
314
+ if (sectionFacesForward !== sectionData.sweep.isCCW)
315
+ sweep.reverseInPlace();
297
316
  }
298
317
  else if (typeof sectionData === "number" || Point3d.isXAndY(sectionData)) {
299
318
  const length0 = (typeof sectionData === "number") ? sectionData : sectionData.x;
@@ -301,31 +320,31 @@ export class CurveFactory {
301
320
  const baseFrame = Matrix3d.createRigidHeadsUp(vectorBC, AxisOrder.ZXY);
302
321
  baseFrame.columnX(vector0).scaleInPlace(length0);
303
322
  baseFrame.columnY(vector90).scaleInPlace(length90);
304
- initialSection = Arc3d.create(currentCenter, vector0, vector90, AngleSweep.create360());
305
323
  }
306
324
  else {
307
325
  return [];
308
326
  }
327
+ // ASSUME: initial section normal points toward sweep direction for subsequent facet creation
328
+ const initialSection = Arc3d.create(undefined, vector0, vector90, sweep);
329
+ centerline.getPoint3dAtUncheckedPointIndex(0, initialSection.centerRef);
309
330
  arcs.push(initialSection);
310
331
  const vectorAB = Vector3d.create();
311
332
  const bisector = Vector3d.create();
333
+ const center = Point3d.create();
312
334
  for (let i = 1; i < centerline.length; i++) {
313
335
  vectorAB.setFromVector3d(vectorBC);
314
- centerline.getPoint3dAtUncheckedPointIndex(i, currentCenter);
315
- if (i + 1 < centerline.length) {
336
+ centerline.getPoint3dAtUncheckedPointIndex(i, center);
337
+ if (i + 1 < centerline.length)
316
338
  centerline.vectorIndexIndex(i, i + 1, vectorBC);
317
- }
318
- else {
339
+ else
319
340
  vectorBC.setFromVector3d(vectorAB);
320
- }
321
341
  if (vectorAB.normalizeInPlace() && vectorBC.normalizeInPlace()) {
322
342
  vectorAB.interpolate(0.5, vectorBC, bisector);
323
- // On the end ellipse for this pipe section. ..
324
- // center comes directly from centerline[i]
325
- // vector0 and vector90 are obtained by sweeping the corresponding vectors of the start ellipse to the split plane.
343
+ // At pipe end, the ellipse center comes directly from centerline[i], and vector0/vector90 are
344
+ // obtained by sweeping the corresponding vectors of the pipe start ellipse to the bisector plane.
326
345
  moveVectorToPlane(vector0, vectorAB, bisector, vector0);
327
346
  moveVectorToPlane(vector90, vectorAB, bisector, vector90);
328
- arcs.push(Arc3d.create(currentCenter, vector0, vector90, AngleSweep.create360()));
347
+ arcs.push(Arc3d.create(center, vector0, vector90, sweep));
329
348
  }
330
349
  }
331
350
  return arcs;
@@ -334,21 +353,38 @@ export class CurveFactory {
334
353
  * Sweep the initialSection along each segment of the centerLine until it hits the bisector plane at the next vertex.
335
354
  * * The caller should place the initialSection on a plane perpendicular to the first edge.
336
355
  * * This plane is commonly (but not necessarily) through the start point itself.
337
- * * If the geometry is not "on a perpendicular plane", the output geometry will still be flattened onto the various planes.
338
- * * In the "open path" case (i.e when wrapIfPhysicallyClosed is false or the path does not have matched first and last points)
339
- * the first/last output plane will be at the start/end of the first/last edge and on a perpendicular plane.
340
- * * In the "closed path" case, the output plane for the first and last point is the bisector of the start and end planes from the "open path" case,
341
- * and the first/last section geometry may be different from `initialSection`.
342
- * * The centerline path does NOT have to be planar, however twisting effects effects will appear in the various bisector planes.
343
- * @param centerline sweep path, e.g., as stroked from a smooth centerline curve
344
- * @param initialSection profile curve to be swept. As noted above, this should be on a plane perpendicular to the first segment of the centerline.
345
- * @param options options for computation and output
356
+ * * If the initialSection is not "on a perpendicular plane", the output geometry will still be flattened onto the
357
+ * various planes.
358
+ * * In the "open path" case (i.e when `wrapIfPhysicallyClosed` is false or the path does not have matched first and
359
+ * last points), the first/last output plane will be at the start/end of the first/last edge and on a perpendicular
360
+ * plane.
361
+ * * In the "closed path" case, if start/edn tangents are not provided in the `options`, then the output plane for the
362
+ * first and last point is the bisector of the start and end planes from the "open path" case, and the first/last
363
+ * section geometry may be different from `initialSection`.
364
+ * * The centerline path does NOT have to be planar, however twisting effects effects will appear in the various bisector
365
+ * planes.
366
+ * @param centerline sweep path, e.g., as stroked from a smooth centerline curve.
367
+ * @param initialSection profile curve to be swept. As noted above, this should be on a plane perpendicular to the
368
+ * first segment of the centerline.
369
+ * @param options options for computation and output.
346
370
  * @return array of sections, starting with `initialSection` projected along the first edge to the first plane.
347
371
  */
348
372
  static createMiteredSweepSections(centerline, initialSection, options) {
349
373
  const sectionData = { sections: [], planes: [] };
350
374
  const planes = PolylineOps.createBisectorPlanesForDistinctPoints(centerline, options.wrapIfPhysicallyClosed);
375
+ // apply start/end tangent options
351
376
  if (planes !== undefined && planes.length > 1) {
377
+ const firstPlane = planes[0];
378
+ const lastPlane = planes[planes.length - 1];
379
+ const startTang = options.startTangent;
380
+ const endTang = options.endTangent;
381
+ if (!firstPlane.getOriginRef().isAlmostEqual(lastPlane.getOriginRef()) ||
382
+ (startTang && endTang && startTang.isAlmostEqual(endTang, 0.0))) {
383
+ if (startTang?.tryNormalizeInPlace())
384
+ firstPlane.getNormalRef().setFrom(startTang);
385
+ if (endTang?.tryNormalizeInPlace())
386
+ lastPlane.getNormalRef().setFrom(endTang);
387
+ }
352
388
  // Projection to target plane, constructing sweep direction from two given planes.
353
389
  // If successful, push the target plane and swept section to the output arrays and return the swept section.
354
390
  // If unsuccessful, leave the output arrays alone and return the input section.
@@ -357,12 +393,12 @@ export class CurveFactory {
357
393
  const transform = Transform.createFlattenAlongVectorToPlane(sweepVector, targetPlane.getOriginRef(), targetPlane.getNormalRef());
358
394
  if (transform === undefined)
359
395
  return section;
360
- const section1 = section.cloneTransformed(transform);
361
- if (section1 === undefined)
396
+ const transformedSection = section.cloneTransformed(transform);
397
+ if (transformedSection === undefined)
362
398
  return section;
363
399
  sectionData.planes.push(targetPlane);
364
- sectionData.sections.push(section1);
365
- return section1;
400
+ sectionData.sections.push(transformedSection);
401
+ return transformedSection;
366
402
  };
367
403
  let currentSection = doSweepToPlane(planes[0], planes[1], planes[0], initialSection);
368
404
  for (let i = 1; i < planes.length; i++) {
@@ -398,11 +434,11 @@ export class CurveFactory {
398
434
  /**
399
435
  * Compute 2 spirals (all in XY) for a symmetric line-to-line transition.
400
436
  * * First spiral begins at given start point.
401
- * * first tangent aims at shoulder
437
+ * * first tangent aims at shoulder.
402
438
  * * outbound spiral joins line from shoulder to target.
403
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
439
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
404
440
  * @param startPoint inbound start point.
405
- * @param shoulder point target point for (both) spiral-to-line tangencies
441
+ * @param shoulder point target point for (both) spiral-to-line tangencies.
406
442
  * @return array with the computed spirals, or undefined if failure.
407
443
  */
408
444
  static createLineSpiralSpiralLine(spiralType, startPoint, shoulderPoint, targetPoint) {
@@ -440,9 +476,9 @@ export class CurveFactory {
440
476
  * Compute 2 spirals (all in XY) for a symmetric line-to-line transition.
441
477
  * * Spiral length is given.
442
478
  * * tangency points float on both lines.
443
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
479
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
444
480
  * @param pointA inbound start point.
445
- * @param shoulder point target point for (both) spiral-to-line tangencies
481
+ * @param shoulder point target point for (both) spiral-to-line tangencies.
446
482
  * @param spiralLength for each part of the spiral pair.
447
483
  * @return array with the computed spirals, or undefined if failure.
448
484
  */
@@ -480,12 +516,12 @@ export class CurveFactory {
480
516
  }
481
517
  /**
482
518
  * Compute 2 spirals and an arc (all in XY) for a symmetric line-to-line transition.
483
- * Spiral lengths and arc radius are given. (e.g. from design speed standards.)
484
- * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE
519
+ * Spiral lengths and arc radius are given (e.g., from design speed standards).
520
+ * @param spiralType name of spiral type. THIS MUST BE AN "Integrated" SPIRAL TYPE.
485
521
  * @param pointA inbound start point.
486
- * @param pointB shoulder (target) point for (both) spiral-to-line tangencies
487
- * @param lengthA inbound spiral length
488
- * @param lengthB outbound spiral length
522
+ * @param pointB shoulder (target) point for (both) spiral-to-line tangencies.
523
+ * @param lengthA inbound spiral length.
524
+ * @param lengthB outbound spiral length.
489
525
  * @return array with the computed spirals, or undefined if failure.
490
526
  */
491
527
  static createLineSpiralArcSpiralLine(spiralType, pointA, pointB, pointC, lengthA, lengthB, arcRadius) {
@@ -535,12 +571,7 @@ export class CurveFactory {
535
571
  }
536
572
  return undefined;
537
573
  }
538
- /**
539
- * Return the intersection point of 3 planes.
540
- * @param planeA
541
- * @param planeB
542
- * @param planeC
543
- */
574
+ /** Return the intersection point of 3 planes. */
544
575
  static planePlaneIntersectionRay(planeA, planeB) {
545
576
  const altitudeA = planeA.altitudeXYZ(0, 0, 0);
546
577
  const altitudeB = planeB.altitudeXYZ(0, 0, 0);
@@ -560,9 +591,7 @@ export class CurveFactory {
560
591
  return undefined;
561
592
  }
562
593
  }
563
- /**
564
- * Starting at vectorR, move parallel to vectorV until perpendicular to planeNormal
565
- */
594
+ /** Starting at vectorR, move parallel to vectorV until perpendicular to planeNormal. */
566
595
  function moveVectorToPlane(vectorR, vectorV, planeNormal, result) {
567
596
  // find s such that (vectorR + s * vectorV) DOT planeNormal = 0.
568
597
  const dotRN = vectorR.dotProduct(planeNormal);