@itwin/core-geometry 5.9.0-dev.1 → 5.9.0-dev.2

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 (34) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/lib/cjs/Geometry.d.ts +2 -1
  3. package/lib/cjs/Geometry.d.ts.map +1 -1
  4. package/lib/cjs/Geometry.js.map +1 -1
  5. package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
  6. package/lib/cjs/curve/Arc3d.js +7 -6
  7. package/lib/cjs/curve/Arc3d.js.map +1 -1
  8. package/lib/cjs/curve/CurveFactory.d.ts +73 -1
  9. package/lib/cjs/curve/CurveFactory.d.ts.map +1 -1
  10. package/lib/cjs/curve/CurveFactory.js +228 -1
  11. package/lib/cjs/curve/CurveFactory.js.map +1 -1
  12. package/lib/cjs/geometry3d/Point3dVector3d.js +1 -1
  13. package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
  14. package/lib/cjs/numerics/Polynomials.d.ts +1 -1
  15. package/lib/cjs/numerics/Polynomials.d.ts.map +1 -1
  16. package/lib/cjs/numerics/Polynomials.js +21 -9
  17. package/lib/cjs/numerics/Polynomials.js.map +1 -1
  18. package/lib/esm/Geometry.d.ts +2 -1
  19. package/lib/esm/Geometry.d.ts.map +1 -1
  20. package/lib/esm/Geometry.js.map +1 -1
  21. package/lib/esm/curve/Arc3d.d.ts.map +1 -1
  22. package/lib/esm/curve/Arc3d.js +7 -6
  23. package/lib/esm/curve/Arc3d.js.map +1 -1
  24. package/lib/esm/curve/CurveFactory.d.ts +73 -1
  25. package/lib/esm/curve/CurveFactory.d.ts.map +1 -1
  26. package/lib/esm/curve/CurveFactory.js +228 -1
  27. package/lib/esm/curve/CurveFactory.js.map +1 -1
  28. package/lib/esm/geometry3d/Point3dVector3d.js +1 -1
  29. package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
  30. package/lib/esm/numerics/Polynomials.d.ts +1 -1
  31. package/lib/esm/numerics/Polynomials.d.ts.map +1 -1
  32. package/lib/esm/numerics/Polynomials.js +21 -9
  33. package/lib/esm/numerics/Polynomials.js.map +1 -1
  34. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import { PlaneAltitudeEvaluator } from "../Geometry";
1
+ import { PerpParallelOptions, PlaneAltitudeEvaluator } from "../Geometry";
2
2
  import { Angle } from "../geometry3d/Angle";
3
3
  import { AngleSweep } from "../geometry3d/AngleSweep";
4
4
  import { Ellipsoid, GeodesicPathPoint } from "../geometry3d/Ellipsoid";
@@ -88,6 +88,27 @@ export interface CreateFilletsInLineStringOptions {
88
88
  */
89
89
  filletClosure?: boolean;
90
90
  }
91
+ /**
92
+ * Options used for method [[CurveFactory.fromFilletedLineString]].
93
+ * @public
94
+ */
95
+ export interface FilletedLineStringOptions {
96
+ /**
97
+ * Options for {@link Vector3d.isParallelTo}.
98
+ * Default: See the documentation for {@link PerpParallelOptions}
99
+ */
100
+ parallelOptions?: PerpParallelOptions;
101
+ /**
102
+ * Distance tolerance for detecting equal points.
103
+ * Default: {@link Geometry.smallMetricDistance}.
104
+ */
105
+ distanceTol?: number;
106
+ /**
107
+ * Whether to allow relaxed validation of the filleted linestring, which allows more chains to serve as valid input.
108
+ * Default: false.
109
+ */
110
+ relaxedValidation?: boolean;
111
+ }
91
112
  /**
92
113
  * The `CurveFactory` class contains methods for specialized curve constructions.
93
114
  * @public
@@ -111,6 +132,57 @@ export declare class CurveFactory {
111
132
  * @param allowCuspOrOptions flag to allow cusps in output (default `true`), or a list of extended options.
112
133
  */
113
134
  static createFilletsInLineString(points: LineString3d | IndexedXYZCollection | Point3d[], radius: number | number[], allowCuspOrOptions?: boolean | CreateFilletsInLineStringOptions): Path | undefined;
135
+ /** If an open filletedLineString starts/ends with an arc, add a zero-length line segment to its start/end. */
136
+ private static validateOpenPathStartEnd;
137
+ /**
138
+ * Split `arc` according to the partition given by `fractions` and append the pieces to `output` with zero-length
139
+ * line segments in between.
140
+ * @param fractions a complete partition of the fractional parameter space, e.g., [0, 0.5, 1] splits the arc into
141
+ * two pieces.
142
+ */
143
+ private static splitAndAppendArc;
144
+ /**
145
+ * Update the path for relaxed validation:
146
+ * * If there are 2 connected arcs, add a zero-length line segment between them.
147
+ * * If there is a pair of arc and line segment/string with non-parallel tangents, add a zero-length line segment
148
+ * between them.
149
+ * * If there is an arc with sweep degrees in [180, 360), break the arc into 2 pieces separated by a zero-length
150
+ * line segment. Similarly, break a 360-degree arc into 3 pieces separated by 2 zero-length line segments. Return
151
+ * `undefined` if there is an arc with sweep greater than 360 degrees.
152
+ */
153
+ private static updatePathForRelaxedValidation;
154
+ /**
155
+ * Verify each neighboring curve to an arc is a line segment/string. Also verify arc tangents are parallel
156
+ * (but not anti-parallel) to neighboring line segment/string tangents.
157
+ */
158
+ private static validateArcNeighbors;
159
+ /** Validate a filleted line string. */
160
+ private static validateFilletedLineString;
161
+ /** If we have 2 connected arcs (with a zero-length line segment in between), add the joint with zero radius. */
162
+ private static addJointBetweenConnectedArcs;
163
+ /**
164
+ * Extract points and radii from a valid filleted linestring.
165
+ * * A valid filleted linestring is a `CurveChain` that satisfies the following conditions:
166
+ * * Its children have type `Arc3d`, `LineSegment3d`, or `LineString3d`.
167
+ * * Each `Arc3d` is circular.
168
+ * * Each `Arc3d` sweep is less than 180 degrees.
169
+ * * Each `Arc3d` cannot be adjacent to another `Arc3d`.
170
+ * * Each `Arc3d` is G1 continuous with each of its neighbors, i.e., at their common point, the curves have the same
171
+ * tangent direction.
172
+ * * To treat more input chains as valid, pass `options.relaxedValidation = true`. Internally, this setting performs
173
+ * several transformations on the input to produce a valid filleted linestring:
174
+ * * Each `Arc3d` whose sweep is between 180 and 360 degrees is split into 2 arcs of equal sweep separated by a
175
+ * zero-length `LineSegment3d`. A 360-degree arc is split into 3 arcs of equal sweep separated by 2 zero-length
176
+ * `LineSegment3d`s. Arcs with sweep greater than 360 degrees are not allowed.
177
+ * * Adjacent `Arc3d`s are separated by a zero-length `LineSegment3d`.
178
+ * * An `Arc3d` that is not G1 continuous with its neighbor is separated from its neighbor by a zero-length
179
+ * `LineSegment3d`.
180
+ * @param filletedLineString A linestring with corner fillets, e.g., as created by {@link CurveFactory.createFilletsInLineString}.
181
+ * @param options optional validation settings.
182
+ * @returns Array of [point, radius] pairs extracted from input, or `undefined` if the input is not valid. A radius
183
+ * of zero means no fillet at the vertex.
184
+ */
185
+ static fromFilletedLineString(filletedLineString: CurveChain, options?: FilletedLineStringOptions): Array<[Point3d, number]> | undefined;
114
186
  /**
115
187
  * Create a `Loop` with given xy corners and fixed z.
116
188
  * * The corners always proceed counter clockwise from lower left.
@@ -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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"}
@@ -126,7 +126,7 @@ export class CurveFactory {
126
126
  continue;
127
127
  const bA = blendArray[Geometry.modulo(i - 1, n)];
128
128
  const bC = blendArray[Geometry.modulo(i + 1, n)];
129
- if (bB.fraction10 > 1 || bB.fraction12 > 1 || 1 - bB.fraction10 < bA.fraction12 || bB.fraction12 > 1 - bC.fraction10) {
129
+ if (bB.fraction10 > 1 || bB.fraction12 > 1 || bB.fraction10 + bA.fraction12 > 1 || bB.fraction12 + bC.fraction10 > 1) {
130
130
  bB.fraction10 = bB.fraction12 = 0;
131
131
  bB.arc = undefined;
132
132
  }
@@ -143,6 +143,233 @@ export class CurveFactory {
143
143
  }
144
144
  return path;
145
145
  }
146
+ /** If an open filletedLineString starts/ends with an arc, add a zero-length line segment to its start/end. */
147
+ static validateOpenPathStartEnd(filletedLineString) {
148
+ const numOfChildren = filletedLineString.children.length;
149
+ assert(numOfChildren > 0);
150
+ const firstChild = filletedLineString.children[0];
151
+ const lastChild = filletedLineString.children[numOfChildren - 1];
152
+ if (firstChild instanceof Arc3d) {
153
+ const startPoint = firstChild.startPoint();
154
+ filletedLineString = Path.create(LineSegment3d.create(startPoint, startPoint), ...filletedLineString.children);
155
+ }
156
+ if (lastChild instanceof Arc3d) {
157
+ const endPoint = lastChild.endPoint();
158
+ filletedLineString = Path.create(...filletedLineString.children, LineSegment3d.create(endPoint, endPoint));
159
+ }
160
+ return filletedLineString;
161
+ }
162
+ /**
163
+ * Split `arc` according to the partition given by `fractions` and append the pieces to `output` with zero-length
164
+ * line segments in between.
165
+ * @param fractions a complete partition of the fractional parameter space, e.g., [0, 0.5, 1] splits the arc into
166
+ * two pieces.
167
+ */
168
+ static splitAndAppendArc(output, arc, fractions) {
169
+ const pt = Point3d.createZero();
170
+ for (let k = 0; k < fractions.length - 1; k++) {
171
+ output.tryAddChild(arc.clonePartialCurve(fractions[k], fractions[k + 1]));
172
+ if (k + 1 < fractions.length - 1) {
173
+ arc.fractionToPoint(fractions[k + 1], pt);
174
+ output.tryAddChild(LineSegment3d.create(pt, pt));
175
+ }
176
+ }
177
+ }
178
+ /**
179
+ * Update the path for relaxed validation:
180
+ * * If there are 2 connected arcs, add a zero-length line segment between them.
181
+ * * If there is a pair of arc and line segment/string with non-parallel tangents, add a zero-length line segment
182
+ * between them.
183
+ * * If there is an arc with sweep degrees in [180, 360), break the arc into 2 pieces separated by a zero-length
184
+ * line segment. Similarly, break a 360-degree arc into 3 pieces separated by 2 zero-length line segments. Return
185
+ * `undefined` if there is an arc with sweep greater than 360 degrees.
186
+ */
187
+ static updatePathForRelaxedValidation(filletedLineString, isClosed, parallelOptions) {
188
+ const newFilletedLineString = new Path();
189
+ const numOfChildren = filletedLineString.children.length;
190
+ for (let i = 0; i < numOfChildren; i++) { // examine each child and its predecessor
191
+ const child = filletedLineString.children[i];
192
+ const arcSweep = child instanceof Arc3d ? Math.abs(child.sweep.sweepDegrees) : undefined;
193
+ const sweepTol = Geometry.smallAngleDegrees;
194
+ if (arcSweep !== undefined && arcSweep > 360 + sweepTol)
195
+ return undefined;
196
+ if (!isClosed && i === 0) {
197
+ newFilletedLineString.tryAddChild(child);
198
+ continue; // skip first child for open path since it won't have a previous child
199
+ }
200
+ const prevChild = filletedLineString.cyclicCurvePrimitive(i - 1);
201
+ assert(prevChild !== undefined, "Cyclic neighbor is defined within loop extents");
202
+ const childStartTangent = child.fractionToPointAndDerivative(0).direction;
203
+ const prevChildEndTangent = prevChild.fractionToPointAndDerivative(1).direction;
204
+ const childrenAreParallel = childStartTangent.isParallelTo(prevChildEndTangent, false, true, parallelOptions);
205
+ const arcLineStringCorner = !childrenAreParallel &&
206
+ ((child instanceof Arc3d && (prevChild instanceof LineSegment3d || prevChild instanceof LineString3d)) ||
207
+ ((prevChild instanceof Arc3d && (child instanceof LineSegment3d || child instanceof LineString3d))));
208
+ const twoConnectedArcs = child instanceof Arc3d && prevChild instanceof Arc3d;
209
+ // apply relaxed validation rules
210
+ if (twoConnectedArcs || arcLineStringCorner) {
211
+ const linePoint = child.startPoint();
212
+ newFilletedLineString.tryAddChild(LineSegment3d.create(linePoint, linePoint));
213
+ }
214
+ if (arcSweep !== undefined && arcSweep > 180 - sweepTol && arcSweep <= 360 - sweepTol) {
215
+ CurveFactory.splitAndAppendArc(newFilletedLineString, child, [0, 0.5, 1]); // 2 pieces
216
+ }
217
+ else if (arcSweep !== undefined && arcSweep > 360 - sweepTol && arcSweep <= 360 + sweepTol) {
218
+ CurveFactory.splitAndAppendArc(newFilletedLineString, child, [0, 1 / 3, 2 / 3, 1]); // 3 pieces
219
+ }
220
+ else {
221
+ newFilletedLineString.tryAddChild(child);
222
+ }
223
+ }
224
+ return newFilletedLineString;
225
+ }
226
+ /**
227
+ * Verify each neighboring curve to an arc is a line segment/string. Also verify arc tangents are parallel
228
+ * (but not anti-parallel) to neighboring line segment/string tangents.
229
+ */
230
+ static validateArcNeighbors(validatedFilletedLineString, i, perpOptions) {
231
+ const child = validatedFilletedLineString.getChild(i);
232
+ if (!child || !(child instanceof Arc3d))
233
+ return false;
234
+ // previous child before arc must be line segment/string
235
+ const prevChild = validatedFilletedLineString.cyclicCurvePrimitive(i - 1); // ASSUME: i === 0 only if the path is closed
236
+ if (!prevChild || (!(prevChild instanceof LineSegment3d) && !(prevChild instanceof LineString3d)))
237
+ return false;
238
+ // arc start tangent must be parallel (but not anti-parallel) to previous line segment
239
+ const arcStartTangent = child.fractionToPointAndDerivative(0).direction;
240
+ const prevChildEndTangent = prevChild.fractionToPointAndDerivative(1).direction;
241
+ if (!arcStartTangent.isParallelTo(prevChildEndTangent, false, true, perpOptions))
242
+ return false;
243
+ // next child after arc must be line segment/string
244
+ const nextChild = validatedFilletedLineString.cyclicCurvePrimitive(i + 1); // ASSUME: i === numOfChildren-1 only if the path is closed
245
+ if (!nextChild || (!(nextChild instanceof LineSegment3d) && !(nextChild instanceof LineString3d)))
246
+ return false;
247
+ // arc end tangent must be parallel (and not anti-parallel) to next line segment
248
+ const arcEndTangent = child.fractionToPointAndDerivative(1).direction;
249
+ const nextChildStartTangent = nextChild.fractionToPointAndDerivative(0).direction;
250
+ if (!arcEndTangent.isParallelTo(nextChildStartTangent, false, true, perpOptions))
251
+ return false;
252
+ return true;
253
+ }
254
+ /** Validate a filleted line string. */
255
+ static validateFilletedLineString(filletedLineString, isClosed, options) {
256
+ if (filletedLineString.children.length === 0)
257
+ return undefined;
258
+ const relaxedValidation = options?.relaxedValidation ?? false;
259
+ let validatedFilletedLineString = filletedLineString;
260
+ if (!isClosed)
261
+ validatedFilletedLineString = this.validateOpenPathStartEnd(validatedFilletedLineString);
262
+ if (relaxedValidation)
263
+ validatedFilletedLineString = this.updatePathForRelaxedValidation(validatedFilletedLineString, isClosed, options?.parallelOptions);
264
+ if (validatedFilletedLineString === undefined)
265
+ return undefined;
266
+ const numOfChildren = validatedFilletedLineString.children.length;
267
+ // validate the children
268
+ for (let i = 0; i < numOfChildren; i++) {
269
+ const child = validatedFilletedLineString.children[i];
270
+ if (!(child instanceof Arc3d) && !(child instanceof LineSegment3d) && !(child instanceof LineString3d))
271
+ return undefined;
272
+ if (child instanceof Arc3d) {
273
+ if (child.circularRadius() === undefined || Math.abs(child.sweep.sweepDegrees) > 180 - Geometry.smallAngleDegrees)
274
+ return undefined;
275
+ if (!this.validateArcNeighbors(validatedFilletedLineString, i, options?.parallelOptions))
276
+ return undefined;
277
+ }
278
+ }
279
+ return validatedFilletedLineString;
280
+ }
281
+ /** If we have 2 connected arcs (with a zero-length line segment in between), add the joint with zero radius. */
282
+ static addJointBetweenConnectedArcs(validatedFilletedLineString, i, isClosed, result) {
283
+ if (!isClosed && i < 2) // for open path, skip the first 2 children
284
+ return;
285
+ const child = validatedFilletedLineString.getChild(i);
286
+ if (!child || !(child instanceof Arc3d))
287
+ return;
288
+ const prevChild = validatedFilletedLineString.cyclicCurvePrimitive(i - 1);
289
+ if (!prevChild || !(prevChild instanceof LineSegment3d) || prevChild.curveLength() > 0)
290
+ return;
291
+ const prevPrevChild = validatedFilletedLineString.cyclicCurvePrimitive(i - 2);
292
+ if (!prevPrevChild || !(prevPrevChild instanceof Arc3d))
293
+ return;
294
+ result.push([prevChild.startPoint(), 0]);
295
+ }
296
+ /**
297
+ * Extract points and radii from a valid filleted linestring.
298
+ * * A valid filleted linestring is a `CurveChain` that satisfies the following conditions:
299
+ * * Its children have type `Arc3d`, `LineSegment3d`, or `LineString3d`.
300
+ * * Each `Arc3d` is circular.
301
+ * * Each `Arc3d` sweep is less than 180 degrees.
302
+ * * Each `Arc3d` cannot be adjacent to another `Arc3d`.
303
+ * * Each `Arc3d` is G1 continuous with each of its neighbors, i.e., at their common point, the curves have the same
304
+ * tangent direction.
305
+ * * To treat more input chains as valid, pass `options.relaxedValidation = true`. Internally, this setting performs
306
+ * several transformations on the input to produce a valid filleted linestring:
307
+ * * Each `Arc3d` whose sweep is between 180 and 360 degrees is split into 2 arcs of equal sweep separated by a
308
+ * zero-length `LineSegment3d`. A 360-degree arc is split into 3 arcs of equal sweep separated by 2 zero-length
309
+ * `LineSegment3d`s. Arcs with sweep greater than 360 degrees are not allowed.
310
+ * * Adjacent `Arc3d`s are separated by a zero-length `LineSegment3d`.
311
+ * * An `Arc3d` that is not G1 continuous with its neighbor is separated from its neighbor by a zero-length
312
+ * `LineSegment3d`.
313
+ * @param filletedLineString A linestring with corner fillets, e.g., as created by {@link CurveFactory.createFilletsInLineString}.
314
+ * @param options optional validation settings.
315
+ * @returns Array of [point, radius] pairs extracted from input, or `undefined` if the input is not valid. A radius
316
+ * of zero means no fillet at the vertex.
317
+ */
318
+ static fromFilletedLineString(filletedLineString, options) {
319
+ const path = filletedLineString instanceof Loop
320
+ ? Path.create(...filletedLineString.children)
321
+ : filletedLineString;
322
+ const isClosed = path.isPhysicallyClosedCurve(options?.distanceTol);
323
+ const validatedFilletedLineString = this.validateFilletedLineString(path, isClosed, options);
324
+ if (!validatedFilletedLineString)
325
+ return undefined;
326
+ // Algorithm:
327
+ // Each arc contributes a point with the arc's radius. If arc consumed the entire edge (2 points), we make sure to
328
+ // add both points (one with the arc's radius and one with zero radius).
329
+ // Each line segment contributes its start point with zero radius, except when it follows an arc, in which case
330
+ // it is ignored since the arc already contributes that point with the correct radius.
331
+ // For open validatedFilletedLineString (which is guaranteed to start and end with a line segment) we also add
332
+ // start and end points with zero radius.
333
+ const result = [];
334
+ const numOfChildren = validatedFilletedLineString.children.length;
335
+ const lastChild = validatedFilletedLineString.cyclicCurvePrimitive(-1);
336
+ let ignoreLineSegment = isClosed && lastChild && lastChild instanceof Arc3d;
337
+ for (let i = 0; i < numOfChildren; i++) {
338
+ const child = validatedFilletedLineString.children[i];
339
+ if (child instanceof Arc3d) {
340
+ this.addJointBetweenConnectedArcs(validatedFilletedLineString, i, isClosed, result);
341
+ ignoreLineSegment = true; // ignore next line segment that follows this arc
342
+ const tangIntersection = child.computeTangentIntersection();
343
+ const radius = child.circularRadius();
344
+ if (radius !== undefined && tangIntersection !== undefined)
345
+ result.push([tangIntersection, radius]);
346
+ else
347
+ return undefined;
348
+ }
349
+ else if (child instanceof LineSegment3d) {
350
+ if (ignoreLineSegment)
351
+ ignoreLineSegment = false;
352
+ else
353
+ result.push([child.startPoint(), 0]);
354
+ }
355
+ else if (child instanceof LineString3d) {
356
+ const j0 = ignoreLineSegment ? 1 : 0;
357
+ ignoreLineSegment = false;
358
+ for (let j = j0; j < child.numPoints() - 1; j++)
359
+ result.push([child.pointAtUnchecked(j), 0]);
360
+ }
361
+ }
362
+ if (isClosed) {
363
+ if (result.length > 0 && !result[0][0].isAlmostEqual(result[result.length - 1][0], options?.distanceTol))
364
+ result.push(result[0]);
365
+ }
366
+ else {
367
+ const endPoint = validatedFilletedLineString.endPoint();
368
+ if (endPoint)
369
+ result.push([endPoint, 0]);
370
+ }
371
+ return result;
372
+ }
146
373
  /**
147
374
  * Create a `Loop` with given xy corners and fixed z.
148
375
  * * The corners always proceed counter clockwise from lower left.