@itwin/core-geometry 5.0.0-dev.16 → 5.0.0-dev.20
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/curve/CurveCollection.d.ts +10 -0
- package/lib/cjs/curve/CurveCollection.d.ts.map +1 -1
- package/lib/cjs/curve/CurveCollection.js +22 -0
- package/lib/cjs/curve/CurveCollection.js.map +1 -1
- package/lib/cjs/curve/CurveFactory.d.ts +35 -28
- package/lib/cjs/curve/CurveFactory.d.ts.map +1 -1
- package/lib/cjs/curve/CurveFactory.js +119 -61
- package/lib/cjs/curve/CurveFactory.js.map +1 -1
- package/lib/cjs/geometry3d/FrameBuilder.js +4 -4
- package/lib/cjs/geometry3d/FrameBuilder.js.map +1 -1
- package/lib/cjs/geometry3d/Point3dVector3d.d.ts +2 -2
- package/lib/cjs/geometry3d/Point3dVector3d.js +2 -2
- package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
- package/lib/cjs/geometry3d/PolygonOps.d.ts +2 -2
- package/lib/cjs/geometry3d/PolygonOps.js +2 -2
- package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
- package/lib/cjs/geometry3d/PolylineOps.d.ts +1 -1
- package/lib/cjs/geometry3d/PolylineOps.d.ts.map +1 -1
- package/lib/cjs/geometry3d/PolylineOps.js +1 -1
- package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
- package/lib/cjs/geometry4d/MomentData.d.ts +72 -73
- package/lib/cjs/geometry4d/MomentData.d.ts.map +1 -1
- package/lib/cjs/geometry4d/MomentData.js +62 -64
- package/lib/cjs/geometry4d/MomentData.js.map +1 -1
- package/lib/cjs/solid/RuledSweep.d.ts +26 -23
- package/lib/cjs/solid/RuledSweep.d.ts.map +1 -1
- package/lib/cjs/solid/RuledSweep.js +30 -23
- package/lib/cjs/solid/RuledSweep.js.map +1 -1
- package/lib/cjs/solid/SolidPrimitive.d.ts +12 -11
- package/lib/cjs/solid/SolidPrimitive.d.ts.map +1 -1
- package/lib/cjs/solid/SolidPrimitive.js +8 -5
- package/lib/cjs/solid/SolidPrimitive.js.map +1 -1
- package/lib/esm/curve/CurveCollection.d.ts +10 -0
- package/lib/esm/curve/CurveCollection.d.ts.map +1 -1
- package/lib/esm/curve/CurveCollection.js +22 -0
- package/lib/esm/curve/CurveCollection.js.map +1 -1
- package/lib/esm/curve/CurveFactory.d.ts +35 -28
- package/lib/esm/curve/CurveFactory.d.ts.map +1 -1
- package/lib/esm/curve/CurveFactory.js +119 -61
- package/lib/esm/curve/CurveFactory.js.map +1 -1
- package/lib/esm/geometry3d/FrameBuilder.js +4 -4
- package/lib/esm/geometry3d/FrameBuilder.js.map +1 -1
- package/lib/esm/geometry3d/Point3dVector3d.d.ts +2 -2
- package/lib/esm/geometry3d/Point3dVector3d.js +2 -2
- package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
- package/lib/esm/geometry3d/PolygonOps.d.ts +2 -2
- package/lib/esm/geometry3d/PolygonOps.js +2 -2
- package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
- package/lib/esm/geometry3d/PolylineOps.d.ts +1 -1
- package/lib/esm/geometry3d/PolylineOps.d.ts.map +1 -1
- package/lib/esm/geometry3d/PolylineOps.js +1 -1
- package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
- package/lib/esm/geometry4d/MomentData.d.ts +72 -73
- package/lib/esm/geometry4d/MomentData.d.ts.map +1 -1
- package/lib/esm/geometry4d/MomentData.js +62 -64
- package/lib/esm/geometry4d/MomentData.js.map +1 -1
- package/lib/esm/solid/RuledSweep.d.ts +26 -23
- package/lib/esm/solid/RuledSweep.d.ts.map +1 -1
- package/lib/esm/solid/RuledSweep.js +30 -23
- package/lib/esm/solid/RuledSweep.js.map +1 -1
- package/lib/esm/solid/SolidPrimitive.d.ts +12 -11
- package/lib/esm/solid/SolidPrimitive.d.ts.map +1 -1
- package/lib/esm/solid/SolidPrimitive.js +8 -5
- package/lib/esm/solid/SolidPrimitive.js.map +1 -1
- package/package.json +3 -3
|
@@ -61,21 +61,13 @@ export interface MiteredSweepOptions {
|
|
|
61
61
|
wrapIfPhysicallyClosed?: boolean;
|
|
62
62
|
/** Whether to output sections only, or sections plus optional geometry constructed from them. Default value is `MiteredSweepOutputSelect.Sections`. */
|
|
63
63
|
outputSelect?: MiteredSweepOutputSelect;
|
|
64
|
-
/** How to stroke the ruled sweep if outputting a mesh. If undefined, default stroke options are used. */
|
|
64
|
+
/** How to stroke smooth input curves and the ruled sweep (if outputting a mesh). If undefined, default stroke options are used. */
|
|
65
65
|
strokeOptions?: StrokeOptions;
|
|
66
66
|
/** Whether to cap the ruled sweep if outputting a ruled sweep or mesh. Default value is `false`. */
|
|
67
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
|
-
*/
|
|
68
|
+
/** The first section's normal is aligned to this vector, typically the start tangent of the smooth curve stroked for the centerline. */
|
|
73
69
|
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
|
-
*/
|
|
70
|
+
/** The last section's normal is aligned to this vector, typically the end tangent of the smooth curve stroked for the centerline. */
|
|
79
71
|
endTangent?: Vector3d;
|
|
80
72
|
}
|
|
81
73
|
/**
|
|
@@ -152,27 +144,42 @@ export declare class CurveFactory {
|
|
|
152
144
|
* @param sectionData circle radius, ellipse semi-axis lengths, or full Arc3d (if not full, function makes it full).
|
|
153
145
|
*/
|
|
154
146
|
static createMiteredPipeSections(centerline: IndexedXYZCollection, sectionData: number | XAndY | Arc3d): Arc3d[];
|
|
147
|
+
/** For a smooth curve, stroke and return unnormalized start/end tangents. */
|
|
148
|
+
private static strokeSmoothCurve;
|
|
155
149
|
/**
|
|
156
|
-
*
|
|
157
|
-
* *
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
*
|
|
164
|
-
* *
|
|
165
|
-
*
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
*
|
|
150
|
+
* Align two bisector plane normals to given smooth rail tangents or optional overrides.
|
|
151
|
+
* * Optionally average the normals for physically closed rail.
|
|
152
|
+
*/
|
|
153
|
+
private static alignFirstAndLastBisectorPlanes;
|
|
154
|
+
/** Reverse a closed curve or region if necessary so that its orientation is CCW with respect to the plane normal. */
|
|
155
|
+
private static alignClosedCurveToPlane;
|
|
156
|
+
/**
|
|
157
|
+
* Projection to target plane, constructing sweep direction from two given planes.
|
|
158
|
+
* * If successful, push the target plane and swept section to the output arrays and return the swept section.
|
|
159
|
+
* * If unsuccessful, leave the output arrays alone and return the input section.
|
|
160
|
+
*/
|
|
161
|
+
private static doSweepToPlane;
|
|
162
|
+
/**
|
|
163
|
+
* Sweep the `initialSection` along each segment of the (stroked) `centerline` until it hits the bisector plane at
|
|
164
|
+
* the next vertex.
|
|
165
|
+
* * For best results, the caller should place `initialSection` in a plane perpendicular to the `centerline`
|
|
166
|
+
* start tangent.
|
|
167
|
+
* * This plane is commonly (but not necessarily) through the centerline start point itself.
|
|
168
|
+
* * To compute the sections, `initialSection` is projected in the direction of the centerline start tangent onto
|
|
169
|
+
* the first bisector plane at the centerline start. The result of this projection will be likewise projected onto
|
|
170
|
+
* the second plane, and so on in sequence.
|
|
171
|
+
* * By default, the first/last bisector plane normals are set to the centerline start/end tangents. The caller can
|
|
172
|
+
* override these with tangents supplied in `options`. If the centerline is physically closed and
|
|
173
|
+
* `options.wrapIfPhysicallyClosed` is true, the first and last plane normals are averaged and equated.
|
|
174
|
+
* * The centerline path does NOT have to be planar, however non-planarity will result in twisting of the sections
|
|
175
|
+
* in the bisector planes.
|
|
176
|
+
* @param centerline sweep path. Will be stroked if smooth.
|
|
170
177
|
* @param initialSection profile curve to be swept. As noted above, this should be on a plane perpendicular to the
|
|
171
|
-
*
|
|
178
|
+
* centerline start tangent.
|
|
172
179
|
* @param options options for computation and output.
|
|
173
|
-
* @return array of sections,
|
|
180
|
+
* @return array of sections, formed from projecting `initialSection` successively onto the bisector planes.
|
|
174
181
|
*/
|
|
175
|
-
static createMiteredSweepSections(centerline: IndexedXYZCollection | Point3d[], initialSection: AnyCurve, options: MiteredSweepOptions): SectionSequenceWithPlanes | undefined;
|
|
182
|
+
static createMiteredSweepSections(centerline: IndexedXYZCollection | Point3d[] | CurvePrimitive | CurveChain, initialSection: AnyCurve, options: MiteredSweepOptions): SectionSequenceWithPlanes | undefined;
|
|
176
183
|
/**
|
|
177
184
|
* Create a circular arc from start point, tangent at start, radius, optional plane normal, arc sweep.
|
|
178
185
|
* * The vector from start point to center is in the direction of upVector crossed with tangentA.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurveFactory.d.ts","sourceRoot":"","sources":["../../../src/curve/CurveFactory.ts"],"names":[],"mappings":"AAKA;;GAEG;
|
|
1
|
+
{"version":3,"file":"CurveFactory.d.ts","sourceRoot":"","sources":["../../../src/curve/CurveFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
/** @packageDocumentation
|
|
6
6
|
* @module Curve
|
|
7
7
|
*/
|
|
8
|
-
// import { Geometry, Angle, AngleSweep } from "../Geometry";
|
|
9
8
|
import { AxisIndex, AxisOrder, Geometry } from "../Geometry";
|
|
10
9
|
import { Angle } from "../geometry3d/Angle";
|
|
11
10
|
import { AngleSweep } from "../geometry3d/AngleSweep";
|
|
@@ -30,6 +29,7 @@ import { LineSegment3d } from "./LineSegment3d";
|
|
|
30
29
|
import { LineString3d } from "./LineString3d";
|
|
31
30
|
import { Loop } from "./Loop";
|
|
32
31
|
import { Path } from "./Path";
|
|
32
|
+
import { RegionOps } from "./RegionOps";
|
|
33
33
|
import { IntegratedSpiral3d } from "./spiral/IntegratedSpiral3d";
|
|
34
34
|
/**
|
|
35
35
|
* Enumeration of geometric output for [CurveFactory.createMiteredSweepSections].
|
|
@@ -44,6 +44,7 @@ export var MiteredSweepOutputSelect;
|
|
|
44
44
|
/** Output planes and sections, as well as the assembled ruled sweep and its stroked mesh. */
|
|
45
45
|
MiteredSweepOutputSelect[MiteredSweepOutputSelect["AlsoMesh"] = 2] = "AlsoMesh";
|
|
46
46
|
})(MiteredSweepOutputSelect || (MiteredSweepOutputSelect = {}));
|
|
47
|
+
;
|
|
47
48
|
/**
|
|
48
49
|
* The `CurveFactory` class contains methods for specialized curve constructions.
|
|
49
50
|
* @public
|
|
@@ -349,75 +350,132 @@ export class CurveFactory {
|
|
|
349
350
|
}
|
|
350
351
|
return arcs;
|
|
351
352
|
}
|
|
353
|
+
/** For a smooth curve, stroke and return unnormalized start/end tangents. */
|
|
354
|
+
static strokeSmoothCurve(curve, options) {
|
|
355
|
+
let startTangent, endTangent;
|
|
356
|
+
if (curve instanceof CurvePrimitive) {
|
|
357
|
+
startTangent = curve.fractionToPointAndDerivative(0.0).direction;
|
|
358
|
+
endTangent = curve.fractionToPointAndDerivative(1.0).direction;
|
|
359
|
+
const strokes = LineString3d.create();
|
|
360
|
+
curve.emitStrokes(strokes, options);
|
|
361
|
+
curve = strokes.packedPoints;
|
|
362
|
+
}
|
|
363
|
+
else if (curve instanceof CurveChain) {
|
|
364
|
+
startTangent = curve.startPointAndDerivative()?.direction;
|
|
365
|
+
endTangent = curve.endPointAndDerivative()?.direction;
|
|
366
|
+
const strokes = curve.getPackedStrokes(options);
|
|
367
|
+
if (!strokes)
|
|
368
|
+
return undefined;
|
|
369
|
+
curve = strokes;
|
|
370
|
+
}
|
|
371
|
+
else if (Array.isArray(curve))
|
|
372
|
+
curve = new Point3dArrayCarrier(curve);
|
|
373
|
+
return { strokes: curve, startTangent, endTangent };
|
|
374
|
+
}
|
|
352
375
|
/**
|
|
353
|
-
*
|
|
354
|
-
* *
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
376
|
+
* Align two bisector plane normals to given smooth rail tangents or optional overrides.
|
|
377
|
+
* * Optionally average the normals for physically closed rail.
|
|
378
|
+
*/
|
|
379
|
+
static alignFirstAndLastBisectorPlanes(firstPlane, lastPlane, smoothRailData, options) {
|
|
380
|
+
const normal0 = options?.startTangent ?? (smoothRailData?.startTangent ?? firstPlane.getNormalRef());
|
|
381
|
+
const normal1 = options?.endTangent ?? (smoothRailData?.endTangent ?? lastPlane.getNormalRef());
|
|
382
|
+
if (options?.wrapIfPhysicallyClosed && firstPlane.getOriginRef().isAlmostEqual(lastPlane.getOriginRef())) {
|
|
383
|
+
const avgNormal = normal0.plus(normal1);
|
|
384
|
+
if (avgNormal.tryNormalizeInPlace()) { // ignore cusp at seam
|
|
385
|
+
firstPlane.getNormalRef().setFrom(avgNormal);
|
|
386
|
+
lastPlane.getNormalRef().setFrom(avgNormal);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (normal0.tryNormalizeInPlace())
|
|
391
|
+
firstPlane.getNormalRef().setFrom(normal0);
|
|
392
|
+
if (normal1.tryNormalizeInPlace())
|
|
393
|
+
lastPlane.getNormalRef().setFrom(normal1);
|
|
394
|
+
}
|
|
395
|
+
/** Reverse a closed curve or region if necessary so that its orientation is CCW with respect to the plane normal. */
|
|
396
|
+
static alignClosedCurveToPlane(curve, planeNormal) {
|
|
397
|
+
let closedCurve;
|
|
398
|
+
if (curve instanceof CurvePrimitive) {
|
|
399
|
+
if (curve.startPoint().isAlmostEqual(curve.endPoint()))
|
|
400
|
+
closedCurve = Loop.create(curve);
|
|
401
|
+
}
|
|
402
|
+
else if (curve.isAnyRegion())
|
|
403
|
+
closedCurve = curve;
|
|
404
|
+
if (closedCurve) {
|
|
405
|
+
// The alignment condition is equivalent to positive projected curve area computed wrt to the plane normal.
|
|
406
|
+
const toLocal = Matrix3d.createRigidHeadsUp(planeNormal).transpose();
|
|
407
|
+
const projection = closedCurve.cloneTransformed(Transform.createOriginAndMatrix(undefined, toLocal));
|
|
408
|
+
if (projection) { // now we can ignore z-coords
|
|
409
|
+
const areaXY = RegionOps.computeXYArea(projection);
|
|
410
|
+
if (areaXY && areaXY < 0)
|
|
411
|
+
curve.reverseInPlace();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Projection to target plane, constructing sweep direction from two given planes.
|
|
417
|
+
* * If successful, push the target plane and swept section to the output arrays and return the swept section.
|
|
418
|
+
* * If unsuccessful, leave the output arrays alone and return the input section.
|
|
419
|
+
*/
|
|
420
|
+
static doSweepToPlane(output, edgePlane0, edgePlane1, targetPlane, section) {
|
|
421
|
+
const sweepVector = Vector3d.createStartEnd(edgePlane0.getOriginRef(), edgePlane1.getOriginRef());
|
|
422
|
+
const transform = Transform.createFlattenAlongVectorToPlane(sweepVector, targetPlane.getOriginRef(), targetPlane.getNormalRef());
|
|
423
|
+
if (transform === undefined)
|
|
424
|
+
return section;
|
|
425
|
+
const transformedSection = section.cloneTransformed(transform);
|
|
426
|
+
if (transformedSection === undefined)
|
|
427
|
+
return section;
|
|
428
|
+
output.planes.push(targetPlane);
|
|
429
|
+
output.sections.push(transformedSection);
|
|
430
|
+
return transformedSection;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Sweep the `initialSection` along each segment of the (stroked) `centerline` until it hits the bisector plane at
|
|
434
|
+
* the next vertex.
|
|
435
|
+
* * For best results, the caller should place `initialSection` in a plane perpendicular to the `centerline`
|
|
436
|
+
* start tangent.
|
|
437
|
+
* * This plane is commonly (but not necessarily) through the centerline start point itself.
|
|
438
|
+
* * To compute the sections, `initialSection` is projected in the direction of the centerline start tangent onto
|
|
439
|
+
* the first bisector plane at the centerline start. The result of this projection will be likewise projected onto
|
|
440
|
+
* the second plane, and so on in sequence.
|
|
441
|
+
* * By default, the first/last bisector plane normals are set to the centerline start/end tangents. The caller can
|
|
442
|
+
* override these with tangents supplied in `options`. If the centerline is physically closed and
|
|
443
|
+
* `options.wrapIfPhysicallyClosed` is true, the first and last plane normals are averaged and equated.
|
|
444
|
+
* * The centerline path does NOT have to be planar, however non-planarity will result in twisting of the sections
|
|
445
|
+
* in the bisector planes.
|
|
446
|
+
* @param centerline sweep path. Will be stroked if smooth.
|
|
367
447
|
* @param initialSection profile curve to be swept. As noted above, this should be on a plane perpendicular to the
|
|
368
|
-
*
|
|
448
|
+
* centerline start tangent.
|
|
369
449
|
* @param options options for computation and output.
|
|
370
|
-
* @return array of sections,
|
|
450
|
+
* @return array of sections, formed from projecting `initialSection` successively onto the bisector planes.
|
|
371
451
|
*/
|
|
372
452
|
static createMiteredSweepSections(centerline, initialSection, options) {
|
|
453
|
+
const rail = this.strokeSmoothCurve(centerline, options.strokeOptions);
|
|
454
|
+
if (!rail)
|
|
455
|
+
return undefined;
|
|
456
|
+
const planes = PolylineOps.createBisectorPlanesForDistinctPoints(rail.strokes);
|
|
457
|
+
if (!planes || planes.length < 2)
|
|
458
|
+
return undefined;
|
|
459
|
+
this.alignFirstAndLastBisectorPlanes(planes[0], planes[planes.length - 1], rail, options);
|
|
460
|
+
// RuledSweep facet construction assumes the contours are oriented CCW with respect to the sweep direction so that
|
|
461
|
+
// facet normals point outward. We only have to align the first contour; the rest will inherit its orientation.
|
|
462
|
+
this.alignClosedCurveToPlane(initialSection, planes[0].getNormalRef());
|
|
373
463
|
const sectionData = { sections: [], planes: [] };
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (endTang?.tryNormalizeInPlace())
|
|
386
|
-
lastPlane.getNormalRef().setFrom(endTang);
|
|
387
|
-
}
|
|
388
|
-
// Projection to target plane, constructing sweep direction from two given planes.
|
|
389
|
-
// If successful, push the target plane and swept section to the output arrays and return the swept section.
|
|
390
|
-
// If unsuccessful, leave the output arrays alone and return the input section.
|
|
391
|
-
const doSweepToPlane = function (edgePlane0, edgePlane1, targetPlane, section) {
|
|
392
|
-
const sweepVector = Vector3d.createStartEnd(edgePlane0.getOriginRef(), edgePlane1.getOriginRef());
|
|
393
|
-
const transform = Transform.createFlattenAlongVectorToPlane(sweepVector, targetPlane.getOriginRef(), targetPlane.getNormalRef());
|
|
394
|
-
if (transform === undefined)
|
|
395
|
-
return section;
|
|
396
|
-
const transformedSection = section.cloneTransformed(transform);
|
|
397
|
-
if (transformedSection === undefined)
|
|
398
|
-
return section;
|
|
399
|
-
sectionData.planes.push(targetPlane);
|
|
400
|
-
sectionData.sections.push(transformedSection);
|
|
401
|
-
return transformedSection;
|
|
402
|
-
};
|
|
403
|
-
let currentSection = doSweepToPlane(planes[0], planes[1], planes[0], initialSection);
|
|
404
|
-
for (let i = 1; i < planes.length; i++) {
|
|
405
|
-
currentSection = doSweepToPlane(planes[i - 1], planes[i], planes[i], currentSection);
|
|
406
|
-
}
|
|
407
|
-
if (options.outputSelect) {
|
|
408
|
-
const ruledSweep = RuledSweep.create(sectionData.sections, options.capped ?? false);
|
|
409
|
-
if (ruledSweep) {
|
|
410
|
-
sectionData.ruledSweep = ruledSweep;
|
|
411
|
-
if (MiteredSweepOutputSelect.AlsoMesh === options.outputSelect) {
|
|
412
|
-
const builder = PolyfaceBuilder.create(options.strokeOptions);
|
|
413
|
-
builder.addRuledSweep(ruledSweep);
|
|
414
|
-
sectionData.mesh = builder.claimPolyface();
|
|
415
|
-
}
|
|
464
|
+
let currentSection = this.doSweepToPlane(sectionData, planes[0], planes[1], planes[0], initialSection);
|
|
465
|
+
for (let i = 1; i < planes.length; i++)
|
|
466
|
+
currentSection = this.doSweepToPlane(sectionData, planes[i - 1], planes[i], planes[i], currentSection);
|
|
467
|
+
if (options.outputSelect) {
|
|
468
|
+
const ruledSweep = RuledSweep.create(sectionData.sections, options.capped ?? false);
|
|
469
|
+
if (ruledSweep) {
|
|
470
|
+
sectionData.ruledSweep = ruledSweep;
|
|
471
|
+
if (MiteredSweepOutputSelect.AlsoMesh === options.outputSelect) {
|
|
472
|
+
const builder = PolyfaceBuilder.create(options.strokeOptions);
|
|
473
|
+
builder.addRuledSweep(ruledSweep);
|
|
474
|
+
sectionData.mesh = builder.claimPolyface();
|
|
416
475
|
}
|
|
417
476
|
}
|
|
418
|
-
return sectionData;
|
|
419
477
|
}
|
|
420
|
-
return
|
|
478
|
+
return sectionData;
|
|
421
479
|
}
|
|
422
480
|
/**
|
|
423
481
|
* Create a circular arc from start point, tangent at start, radius, optional plane normal, arc sweep.
|