@itwin/core-geometry 5.0.0-dev.62 → 5.0.0-dev.64
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/bspline/BSpline1dNd.d.ts +90 -54
- package/lib/cjs/bspline/BSpline1dNd.d.ts.map +1 -1
- package/lib/cjs/bspline/BSpline1dNd.js +134 -99
- package/lib/cjs/bspline/BSpline1dNd.js.map +1 -1
- package/lib/cjs/bspline/BSplineCurve.d.ts +193 -155
- package/lib/cjs/bspline/BSplineCurve.d.ts.map +1 -1
- package/lib/cjs/bspline/BSplineCurve.js +245 -181
- package/lib/cjs/bspline/BSplineCurve.js.map +1 -1
- package/lib/cjs/bspline/BezierCurve3d.d.ts +3 -1
- package/lib/cjs/bspline/BezierCurve3d.d.ts.map +1 -1
- package/lib/cjs/bspline/BezierCurve3d.js +3 -5
- package/lib/cjs/bspline/BezierCurve3d.js.map +1 -1
- package/lib/cjs/bspline/KnotVector.d.ts +74 -54
- package/lib/cjs/bspline/KnotVector.d.ts.map +1 -1
- package/lib/cjs/bspline/KnotVector.js +127 -80
- package/lib/cjs/bspline/KnotVector.js.map +1 -1
- package/lib/cjs/curve/Arc3d.d.ts +2 -0
- package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
- package/lib/cjs/curve/Arc3d.js +2 -0
- package/lib/cjs/curve/Arc3d.js.map +1 -1
- package/lib/cjs/geometry3d/PointHelpers.d.ts +3 -3
- package/lib/cjs/geometry3d/PointHelpers.js +3 -3
- package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.d.ts +2 -2
- package/lib/cjs/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.js +8 -11
- package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
- package/lib/esm/bspline/BSpline1dNd.d.ts +90 -54
- package/lib/esm/bspline/BSpline1dNd.d.ts.map +1 -1
- package/lib/esm/bspline/BSpline1dNd.js +134 -99
- package/lib/esm/bspline/BSpline1dNd.js.map +1 -1
- package/lib/esm/bspline/BSplineCurve.d.ts +193 -155
- package/lib/esm/bspline/BSplineCurve.d.ts.map +1 -1
- package/lib/esm/bspline/BSplineCurve.js +245 -181
- package/lib/esm/bspline/BSplineCurve.js.map +1 -1
- package/lib/esm/bspline/BezierCurve3d.d.ts +3 -1
- package/lib/esm/bspline/BezierCurve3d.d.ts.map +1 -1
- package/lib/esm/bspline/BezierCurve3d.js +3 -5
- package/lib/esm/bspline/BezierCurve3d.js.map +1 -1
- package/lib/esm/bspline/KnotVector.d.ts +74 -54
- package/lib/esm/bspline/KnotVector.d.ts.map +1 -1
- package/lib/esm/bspline/KnotVector.js +127 -80
- package/lib/esm/bspline/KnotVector.js.map +1 -1
- package/lib/esm/curve/Arc3d.d.ts +2 -0
- package/lib/esm/curve/Arc3d.d.ts.map +1 -1
- package/lib/esm/curve/Arc3d.js +2 -0
- package/lib/esm/curve/Arc3d.js.map +1 -1
- package/lib/esm/geometry3d/PointHelpers.d.ts +3 -3
- package/lib/esm/geometry3d/PointHelpers.js +3 -3
- package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
- package/lib/esm/geometry3d/Ray3d.d.ts +2 -2
- package/lib/esm/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Ray3d.js +8 -11
- package/lib/esm/geometry3d/Ray3d.js.map +1 -1
- package/package.json +3 -3
|
@@ -31,83 +31,117 @@ const BSplineCurveOps_1 = require("./BSplineCurveOps");
|
|
|
31
31
|
const KnotVector_1 = require("./KnotVector");
|
|
32
32
|
/**
|
|
33
33
|
* Base class for BSplineCurve3d and BSplineCurve3dH.
|
|
34
|
-
* * A
|
|
35
|
-
* * The
|
|
36
|
-
*
|
|
37
|
-
*
|
|
34
|
+
* * A B-spline curve consists of an array of `knots`, an array of `poles`, and a `degree`.
|
|
35
|
+
* * The knot array is a non-decreasing sequence of numbers. It is also called a "knot vector".
|
|
36
|
+
* * The curve is a parametric function whose domain is a sub-range of its knots.
|
|
37
|
+
* * The API sometimes refers to a domain parameter `u` as a "knot", even if `u` is not actually an entry in the
|
|
38
|
+
* knot array.
|
|
39
|
+
* * The curve loosely "follows" the line string formed by the poles, aka the "control polygon".
|
|
40
|
+
* * The curve is a chain of polynomial segments, aka "spans" or "fragments". B-spline theory identifies these as
|
|
41
|
+
* Bezier curves.
|
|
38
42
|
* * The polynomial spans all have same `degree`.
|
|
39
|
-
* *
|
|
40
|
-
* *
|
|
41
|
-
* * The number of spans is `numSpan = numPoles - degree
|
|
42
|
-
* * For a
|
|
43
|
-
* * The `order` poles begin at index `spanIndex`.
|
|
44
|
-
* * The `2*
|
|
45
|
-
* * The
|
|
46
|
-
* * The
|
|
43
|
+
* * Each span is controlled by `order = degree + 1` contiguous points in the pole array.
|
|
44
|
+
* * There is a strict relationship between knot and poles counts: `numPoles + order = numKnots + 2'.
|
|
45
|
+
* * The number of spans is `numSpan = numPoles - degree`.
|
|
46
|
+
* * For a span with index `spanIndex`:
|
|
47
|
+
* * The `order` relevant poles begin at pole index `spanIndex`.
|
|
48
|
+
* * The `2*degree` relevant knots begin at knot index `spanIndex`.
|
|
49
|
+
* * The span domain is the knot range `[knot[spanIndex+degree-1], knot[spanIndex+degree]]`.
|
|
50
|
+
* * The curve domain is the knot range `[knot[degree-1], knot[numSpan+degree-1]]`, or equivalently
|
|
51
|
+
* `[knot[degree-1], knot[numPoles-1]]`. The API refers to this domain as the "active knot interval" of the curve.
|
|
47
52
|
*
|
|
48
|
-
* Nearly all
|
|
49
|
-
* *
|
|
50
|
-
*
|
|
51
|
-
* *
|
|
52
|
-
*
|
|
53
|
-
*
|
|
53
|
+
* Nearly all B-spline curves are "clamped".
|
|
54
|
+
* * This means that in the `knots` array, the first `degree` knots are equal, and the last `degree` knots are equal.
|
|
55
|
+
* We say the smallest knot and the largest knot have multiplicity `degree`.
|
|
56
|
+
* * Clamping make the curve pass through its first and last poles, with tangents directed along the first and
|
|
57
|
+
* last edges of the control polygon.
|
|
58
|
+
* * For instance, a cubic B-spline curve with knot vector `[0,0,0,1,2,3,3,3]`
|
|
59
|
+
* * can be evaluated at parameter values in the range `[0, 3]`
|
|
60
|
+
* * has 3 spans, with domains `[0, 1]`, `[1, 2]`, and `[2, 3]`
|
|
54
61
|
* * has 6 poles
|
|
55
62
|
* * passes through its first and last poles.
|
|
56
|
-
* * `create` methods may allow classic convention that has an extra knot at the beginning and end of the
|
|
57
|
-
*
|
|
58
|
-
* *
|
|
63
|
+
* * The `create` methods may allow the classic convention that has an extra knot at the beginning and end of the
|
|
64
|
+
* knot vector.
|
|
65
|
+
* * These two extra knots are not actually needed to define the B-spline curve.
|
|
66
|
+
* * When the `create` methods recognize the classic setup (`numPoles + order = numKnots`), the extra knots are
|
|
67
|
+
* not saved with the BSplineCurve3dBase knots.
|
|
59
68
|
*
|
|
60
|
-
* * The weighted variant has the problem that CurvePrimitive
|
|
61
|
-
*
|
|
69
|
+
* * The weighted variant [[BSplineCurve3dH]] has the problem that `CurvePrimitive` 3D typing does not allow the
|
|
70
|
+
* undefined result where a homogeneous pole has zero weight; the convention in this case is to return 000.
|
|
62
71
|
*
|
|
63
72
|
* * Note the class relationships:
|
|
64
|
-
* * BSpline1dNd knows the
|
|
65
|
-
* * BsplineCurve3dBase owns a protected BSpline1dNd
|
|
66
|
-
* * BsplineCurve3dBase is derived from CurvePrimitive, which creates obligation to act as a 3D curve,
|
|
67
|
-
* * evaluate fraction to point and derivatives wrt fraction
|
|
68
|
-
* * compute intersection with plane
|
|
69
|
-
* * BSplineCurve3d and BSplineCurve3dH have variant logic driven by whether or not there are "weights" on the poles.
|
|
70
|
-
* * For `BSplineCurve3d`, the xyz value of pole calculations are "final" values for 3d evaluation
|
|
73
|
+
* * [[BSpline1dNd]] knows the definitional B-spline recurrence relation with no physical interpretation for the poles.
|
|
74
|
+
* * BsplineCurve3dBase owns a protected BSpline1dNd.
|
|
75
|
+
* * `BsplineCurve3dBase` is derived from [[CurvePrimitive]], which creates obligation to act as a 3D curve, e.g.,
|
|
76
|
+
* * evaluate fraction to point and derivatives wrt fraction.
|
|
77
|
+
* * compute intersection with plane.
|
|
78
|
+
* * [[BSplineCurve3d]] and [[BSplineCurve3dH]] have variant logic driven by whether or not there are "weights" on the poles.
|
|
79
|
+
* * For `BSplineCurve3d`, the xyz value of pole calculations are "final" values for 3d evaluation.
|
|
71
80
|
* * For `BSplineCurve3dH`, various `BSpline1dNd` results with xyzw have to be normalized back to xyz.
|
|
72
81
|
*
|
|
73
82
|
* * These classes do not support "periodic" variants.
|
|
74
|
-
* * Periodic curves
|
|
83
|
+
* * Periodic curves historically have carried a flag (e.g., "closed") indicating that certain un-stored
|
|
84
|
+
* leading/trailing knots and poles are understood to wrap around periodically.
|
|
85
|
+
* * Instead, these classes carry no such flag. They represent such curves with explicitly wrapped knots/poles.
|
|
86
|
+
*
|
|
87
|
+
* * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/BSpline/
|
|
75
88
|
* @public
|
|
76
89
|
*/
|
|
77
90
|
class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
78
|
-
/** String name for schema properties */
|
|
91
|
+
/** String name for schema properties. */
|
|
79
92
|
curvePrimitiveType = "bsplineCurve";
|
|
80
|
-
/** The underlying blocked-pole spline, with simple x,y,z poles */
|
|
93
|
+
/** The underlying blocked-pole spline, with simple x,y,z poles. */
|
|
81
94
|
_bcurve;
|
|
82
95
|
_definitionData;
|
|
83
|
-
set definitionData(data) {
|
|
84
|
-
|
|
96
|
+
set definitionData(data) {
|
|
97
|
+
this._definitionData = data;
|
|
98
|
+
}
|
|
99
|
+
get definitionData() {
|
|
100
|
+
return this._definitionData;
|
|
101
|
+
}
|
|
85
102
|
constructor(poleDimension, numPoles, order, knots) {
|
|
86
103
|
super();
|
|
87
104
|
this._bcurve = BSpline1dNd_1.BSpline1dNd.create(numPoles, poleDimension, order, knots);
|
|
88
105
|
}
|
|
89
|
-
/** Return the degree (one less than the order) of the curve */
|
|
90
|
-
get degree() {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/** Return the
|
|
94
|
-
get
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
get knotsRef() { return this._bcurve.knots.knots; }
|
|
101
|
-
/** Number of components per pole.
|
|
102
|
-
* * 3 for conventional (x,y,z) curve
|
|
103
|
-
* * 4 for weighted (wx,wy,wz,w) curve
|
|
106
|
+
/** Return the degree (one less than the order) of the curve. */
|
|
107
|
+
get degree() {
|
|
108
|
+
return this._bcurve.degree;
|
|
109
|
+
}
|
|
110
|
+
/** Return the order (one more than degree) of the curve. */
|
|
111
|
+
get order() {
|
|
112
|
+
return this._bcurve.order;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Return the number of Bezier spans in the curve. Note that this number includes the number of null
|
|
116
|
+
* spans at repeated knows.
|
|
104
117
|
*/
|
|
105
|
-
get
|
|
118
|
+
get numSpan() {
|
|
119
|
+
return this._bcurve.numSpan;
|
|
120
|
+
}
|
|
121
|
+
/** Return the number of poles. */
|
|
122
|
+
get numPoles() {
|
|
123
|
+
return this._bcurve.numPoles;
|
|
124
|
+
}
|
|
125
|
+
/** Return live reference to the poles of the curve. */
|
|
126
|
+
get polesRef() {
|
|
127
|
+
return this._bcurve.packedData;
|
|
128
|
+
}
|
|
129
|
+
/** Return live reference to the knots of the curve. */
|
|
130
|
+
get knotsRef() {
|
|
131
|
+
return this._bcurve.knots.knots;
|
|
132
|
+
}
|
|
106
133
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
134
|
+
* Number of components per pole, e.g.,
|
|
135
|
+
* * 3 for conventional (x,y,z) curve.
|
|
136
|
+
* * 4 for weighted (wx,wy,wz,w) curve.
|
|
109
137
|
*/
|
|
110
|
-
|
|
138
|
+
get poleDimension() {
|
|
139
|
+
return this._bcurve.poleLength;
|
|
140
|
+
}
|
|
141
|
+
/** Return a simple array form of the knots. Optionally replicate the first and last in classic over-clamped manner. */
|
|
142
|
+
copyKnots(includeExtraEndKnot) {
|
|
143
|
+
return this._bcurve.knots.copyKnots(includeExtraEndKnot);
|
|
144
|
+
}
|
|
111
145
|
/** Get the flag indicating the curve might be suitable for having wrapped "closed" interpretation. */
|
|
112
146
|
getWrappable() {
|
|
113
147
|
return this._bcurve.knots.wrappable;
|
|
@@ -117,7 +151,7 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
117
151
|
this._bcurve.knots.wrappable = value;
|
|
118
152
|
}
|
|
119
153
|
/**
|
|
120
|
-
* Test knots and
|
|
154
|
+
* Test knots and poles to determine if it is possible to close (aka "wrap") the curve.
|
|
121
155
|
* @returns the manner in which it is possible to close the curve. See `BSplineWrapMode` for particulars of each mode.
|
|
122
156
|
*/
|
|
123
157
|
get isClosableCurve() {
|
|
@@ -130,25 +164,18 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
130
164
|
return KnotVector_1.BSplineWrapMode.None;
|
|
131
165
|
return mode;
|
|
132
166
|
}
|
|
133
|
-
/** Evaluate the curve point at
|
|
167
|
+
/** Evaluate the curve point at the given fractional parameter. */
|
|
134
168
|
fractionToPoint(fraction, result) {
|
|
135
169
|
return this.knotToPoint(this._bcurve.knots.fractionToKnot(fraction), result);
|
|
136
170
|
}
|
|
137
|
-
/**
|
|
138
|
-
* * origin at the fractional position along the arc
|
|
139
|
-
* * direction is the first derivative, i.e. tangent along the curve
|
|
140
|
-
*/
|
|
171
|
+
/** Evaluate the curve and derivative at the given fractional parameter. */
|
|
141
172
|
fractionToPointAndDerivative(fraction, result) {
|
|
142
173
|
const knot = this._bcurve.knots.fractionToKnot(fraction);
|
|
143
174
|
result = this.knotToPointAndDerivative(knot, result);
|
|
144
175
|
result.direction.scaleInPlace(this._bcurve.knots.knotLength01);
|
|
145
176
|
return result;
|
|
146
177
|
}
|
|
147
|
-
/**
|
|
148
|
-
* * origin at the fractional position along the arc
|
|
149
|
-
* * x axis is the first derivative, i.e. tangent along the curve
|
|
150
|
-
* * y axis is the second derivative
|
|
151
|
-
*/
|
|
178
|
+
/** Evaluate the curve and two derivatives at the given fractional parameter. */
|
|
152
179
|
fractionToPointAnd2Derivatives(fraction, result) {
|
|
153
180
|
const knot = this._bcurve.knots.fractionToKnot(fraction);
|
|
154
181
|
result = this.knotToPointAnd2Derivatives(knot, result);
|
|
@@ -157,22 +184,23 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
157
184
|
result.vectorV.scaleInPlace(a * a);
|
|
158
185
|
return result;
|
|
159
186
|
}
|
|
187
|
+
/** Return the start point of the curve. */
|
|
188
|
+
startPoint() {
|
|
189
|
+
return this.evaluatePointInSpan(0, 0.0);
|
|
190
|
+
}
|
|
191
|
+
/** Return the end point of the curve. */
|
|
192
|
+
endPoint() {
|
|
193
|
+
return this.evaluatePointInSpan(this.numSpan - 1, 1.0);
|
|
194
|
+
}
|
|
160
195
|
/**
|
|
161
|
-
*
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Return the end point of the curve
|
|
166
|
-
*/
|
|
167
|
-
endPoint() { return this.evaluatePointInSpan(this.numSpan - 1, 1.0); }
|
|
168
|
-
/** Reverse the curve in place.
|
|
169
|
-
* * Poles are reversed
|
|
170
|
-
* * knot values are mirrored around the middle of the
|
|
171
|
-
*/
|
|
172
|
-
reverseInPlace() { this._bcurve.reverseInPlace(); }
|
|
173
|
-
/**
|
|
174
|
-
* Return an array with this curve's bezier fragments.
|
|
196
|
+
* Reverse the curve in place.
|
|
197
|
+
* * Poles are reversed.
|
|
198
|
+
* * Knot values are mirrored around the middle of the knot array.
|
|
175
199
|
*/
|
|
200
|
+
reverseInPlace() {
|
|
201
|
+
this._bcurve.reverseInPlace();
|
|
202
|
+
}
|
|
203
|
+
/** Return an array with this curve's Bezier fragments. */
|
|
176
204
|
collectBezierSpans(prefer3dH) {
|
|
177
205
|
const result = [];
|
|
178
206
|
const numSpans = this.numSpan;
|
|
@@ -191,17 +219,18 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
191
219
|
return poleIndex * this._bcurve.poleLength;
|
|
192
220
|
return undefined;
|
|
193
221
|
}
|
|
194
|
-
/**
|
|
195
|
-
*
|
|
222
|
+
/**
|
|
223
|
+
* Search for the curve point that is closest to the spacePoint.
|
|
196
224
|
* * If the space point is exactly on the curve, this is the reverse of fractionToPoint.
|
|
197
|
-
* * Since CurvePrimitive should always have start and end available as candidate points, this method should always
|
|
198
|
-
*
|
|
225
|
+
* * Since CurvePrimitive should always have start and end available as candidate points, this method should always
|
|
226
|
+
* succeed.
|
|
227
|
+
* @param spacePoint point in space.
|
|
199
228
|
* @param _extend ignored (pass false). A BSplineCurve3dBase cannot be extended.
|
|
200
229
|
* @param result optional pre-allocated detail to populate and return.
|
|
201
230
|
* @returns details of the closest point.
|
|
202
231
|
*/
|
|
203
232
|
closestPoint(spacePoint, _extend, result) {
|
|
204
|
-
// seed at start point
|
|
233
|
+
// seed at start point; final point comes with final bezier perpendicular step
|
|
205
234
|
const point = this.fractionToPoint(0);
|
|
206
235
|
result = CurveLocationDetail_1.CurveLocationDetail.createCurveFractionPointDistance(this, 0.0, point, point.distance(spacePoint), result);
|
|
207
236
|
let span;
|
|
@@ -210,9 +239,9 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
210
239
|
if (this._bcurve.knots.isIndexOfRealSpan(i)) {
|
|
211
240
|
span = this.getSaturatedBezierSpan3dOr3dH(i, true, span);
|
|
212
241
|
if (span) {
|
|
213
|
-
//
|
|
242
|
+
// if the B-spline is discontinuous, both ends should be tested; ignore that possibility
|
|
214
243
|
if (span.updateClosestPointByTruePerpendicular(spacePoint, result, false, true)) {
|
|
215
|
-
// the detail records the span bezier
|
|
244
|
+
// the detail records the span bezier; promote it to the parent curve
|
|
216
245
|
result.curve = this;
|
|
217
246
|
result.fraction = span.fractionToParentFraction(result.fraction);
|
|
218
247
|
}
|
|
@@ -223,13 +252,14 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
223
252
|
}
|
|
224
253
|
/** Return a transformed deep clone. */
|
|
225
254
|
cloneTransformed(transform) {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
return
|
|
255
|
+
const curve = this.clone();
|
|
256
|
+
curve.tryTransformInPlace(transform);
|
|
257
|
+
return curve;
|
|
229
258
|
}
|
|
230
|
-
/**
|
|
231
|
-
*
|
|
232
|
-
* @param
|
|
259
|
+
/**
|
|
260
|
+
* Return a curve primitive which is a portion of this curve.
|
|
261
|
+
* @param fractionA start fraction.
|
|
262
|
+
* @param fractionB end fraction.
|
|
233
263
|
*/
|
|
234
264
|
clonePartialCurve(fractionA, fractionB) {
|
|
235
265
|
const clone = this.clone();
|
|
@@ -240,11 +270,8 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
240
270
|
clone._bcurve.addKnot(knotB, clone.degree);
|
|
241
271
|
if (origNumKnots === clone._bcurve.knots.knots.length)
|
|
242
272
|
return clone; // full curve
|
|
243
|
-
if (knotA > knotB)
|
|
244
|
-
|
|
245
|
-
knotA = knotB;
|
|
246
|
-
knotB = tmp;
|
|
247
|
-
}
|
|
273
|
+
if (knotA > knotB)
|
|
274
|
+
[knotA, knotB] = [knotB, knotA];
|
|
248
275
|
// choose first/last knot and pole such that knotA/knotB has degree multiplicity in the new knot sequence
|
|
249
276
|
const iStartKnot = clone._bcurve.knots.knotToLeftKnotIndex(knotA) - clone.degree + 1;
|
|
250
277
|
const iStartPole = iStartKnot * clone._bcurve.poleLength;
|
|
@@ -254,15 +281,17 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
254
281
|
iLastKnotLeftMultiple = iLastKnot + 1;
|
|
255
282
|
const iEndPole = (iLastKnotLeftMultiple + 1) * clone._bcurve.poleLength; // one past last pole
|
|
256
283
|
const iEndKnot = iLastKnotLeftMultiple + clone.degree; // one past last knot
|
|
257
|
-
// trim the arrays (leave knots unnormalized
|
|
284
|
+
// trim the arrays (leave knots unnormalized)
|
|
258
285
|
clone._bcurve.knots.setKnotsCapture(clone._bcurve.knots.knots.slice(iStartKnot, iEndKnot));
|
|
259
286
|
clone._bcurve.packedData = clone._bcurve.packedData.slice(iStartPole, iEndPole);
|
|
260
287
|
clone.setWrappable(KnotVector_1.BSplineWrapMode.None); // always open
|
|
261
288
|
return clone;
|
|
262
289
|
}
|
|
263
|
-
/**
|
|
264
|
-
*
|
|
265
|
-
* @param
|
|
290
|
+
/**
|
|
291
|
+
* Implement `CurvePrimitive.appendPlaneIntersections` to compute intersections of the curve with a plane.
|
|
292
|
+
* @param plane the plane with which to intersect the curve. Concrete types include [[Plane3dByOriginAndUnitNormal]],
|
|
293
|
+
* [[Point4d]], etc.
|
|
294
|
+
* @param result growing array of plane intersections.
|
|
266
295
|
* @return number of intersections appended to the array.
|
|
267
296
|
*/
|
|
268
297
|
appendPlaneIntersectionPoints(plane, result) {
|
|
@@ -273,34 +302,32 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
273
302
|
const point4d = Point4d_1.Point4d.create();
|
|
274
303
|
// compute all pole altitudes from the plane
|
|
275
304
|
const minMax = Range_1.Range1d.createNull();
|
|
276
|
-
//
|
|
305
|
+
// put the altitudes of all the B-spline poles in one array
|
|
277
306
|
for (let i = 0; i < numPole; i++) {
|
|
278
307
|
allCoffs[i] = plane.weightedAltitude(this.getPolePoint4d(i, point4d));
|
|
279
308
|
minMax.extendX(allCoffs[i]);
|
|
280
309
|
}
|
|
281
|
-
// A univariate
|
|
310
|
+
// A univariate B-spline through the altitude poles gives altitude as function of the B-spline knot.
|
|
282
311
|
// The (bspline) altitude function for each span is `order` consecutive altitudes.
|
|
283
312
|
// If those altitudes bracket zero, the span may potentially have a crossing.
|
|
284
|
-
// When that occurs,
|
|
285
313
|
let univariateBezier;
|
|
286
314
|
let numFound = 0;
|
|
287
315
|
let previousFraction = -1000.0;
|
|
288
316
|
if (minMax.containsX(0.0)) {
|
|
289
317
|
for (let spanIndex = 0; spanIndex < numSpan; spanIndex++) {
|
|
290
|
-
if (this._bcurve.knots.isIndexOfRealSpan(spanIndex)) { // ignore trivial knot intervals
|
|
318
|
+
if (this._bcurve.knots.isIndexOfRealSpan(spanIndex)) { // ignore trivial knot intervals
|
|
291
319
|
// outer range test ...
|
|
292
320
|
minMax.setNull();
|
|
293
321
|
minMax.extendArraySubset(allCoffs, spanIndex, order);
|
|
294
322
|
if (minMax.containsX(0.0)) {
|
|
295
|
-
// pack the
|
|
323
|
+
// pack the B-spline support into a univariate bezier
|
|
296
324
|
univariateBezier = BezierPolynomials_1.UnivariateBezier.createArraySubset(allCoffs, spanIndex, order, univariateBezier);
|
|
297
325
|
// saturate and solve the bezier
|
|
298
326
|
Bezier1dNd_1.Bezier1dNd.saturate1dInPlace(univariateBezier.coffs, this._bcurve.knots, spanIndex);
|
|
299
327
|
const roots = univariateBezier.roots(0.0, true);
|
|
300
328
|
if (roots) {
|
|
301
329
|
for (const spanFraction of roots) {
|
|
302
|
-
// promote each local bezier fraction to global fraction
|
|
303
|
-
// save the curve evaluation at that fraction.
|
|
330
|
+
// promote each local bezier fraction to global fraction and save the curve evaluation at that fraction
|
|
304
331
|
numFound++;
|
|
305
332
|
const fraction = this._bcurve.knots.spanFractionToFraction(spanIndex, spanFraction);
|
|
306
333
|
if (!Geometry_1.Geometry.isAlmostEqualNumber(fraction, previousFraction)) {
|
|
@@ -319,9 +346,7 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
319
346
|
}
|
|
320
347
|
/**
|
|
321
348
|
* Construct an offset of the instance curve as viewed in the xy-plane (ignoring z).
|
|
322
|
-
*
|
|
323
|
-
* for an aggregate instance (e.g., LineString3d, CurveChainWithDistanceIndex), use RegionOps.constructCurveXYOffset() instead.
|
|
324
|
-
* @param offsetDistanceOrOptions offset distance (positive to left of the instance curve), or options object
|
|
349
|
+
* @param offsetDistanceOrOptions offset distance (positive to left of the instance curve), or options object.
|
|
325
350
|
*/
|
|
326
351
|
constructOffsetXY(offsetDistanceOrOptions) {
|
|
327
352
|
const options = OffsetOptions_1.OffsetOptions.create(offsetDistanceOrOptions);
|
|
@@ -329,10 +354,13 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
329
354
|
this.emitStrokableParts(handler, options.strokeOptions);
|
|
330
355
|
return handler.claimResult();
|
|
331
356
|
}
|
|
332
|
-
/**
|
|
357
|
+
/**
|
|
358
|
+
* Project instance geometry (via dispatch) onto the given ray, and return the extreme fractional parameters
|
|
359
|
+
* of projection.
|
|
333
360
|
* @param ray ray onto which the instance is projected. A `Vector3d` is treated as a `Ray3d` with zero origin.
|
|
334
|
-
* @param lowHigh optional receiver for output
|
|
335
|
-
* @returns range of fractional projection parameters onto the ray, where 0.0 is start of the ray and 1.0 is the
|
|
361
|
+
* @param lowHigh optional receiver for output.
|
|
362
|
+
* @returns range of fractional projection parameters onto the ray, where 0.0 is start of the ray and 1.0 is the
|
|
363
|
+
* end of the ray.
|
|
336
364
|
*/
|
|
337
365
|
projectedParameterRange(ray, lowHigh) {
|
|
338
366
|
return PlaneAltitudeRangeContext_1.PlaneAltitudeRangeContext.findExtremeFractionsAlongDirection(this, ray, lowHigh);
|
|
@@ -340,8 +368,8 @@ class BSplineCurve3dBase extends CurvePrimitive_1.CurvePrimitive {
|
|
|
340
368
|
}
|
|
341
369
|
exports.BSplineCurve3dBase = BSplineCurve3dBase;
|
|
342
370
|
/**
|
|
343
|
-
* A BSplineCurve3d is a
|
|
344
|
-
* See BSplineCurve3dBase for description of knots, order, degree.
|
|
371
|
+
* A BSplineCurve3d is a B-spline curve whose poles are Point3d.
|
|
372
|
+
* See BSplineCurve3dBase for description of knots, order, degree, and poles.
|
|
345
373
|
* @public
|
|
346
374
|
*/
|
|
347
375
|
class BSplineCurve3d extends BSplineCurve3dBase {
|
|
@@ -351,11 +379,19 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
351
379
|
this._workBezier = BezierCurve3d_1.BezierCurve3d.createOrder(this.order);
|
|
352
380
|
return this._workBezier;
|
|
353
381
|
}
|
|
354
|
-
|
|
355
|
-
|
|
382
|
+
constructor(numPoles, order, knots) {
|
|
383
|
+
super(3, numPoles, order, knots);
|
|
384
|
+
}
|
|
385
|
+
/** Test if `other` is an instance of BSplineCurve3d. */
|
|
386
|
+
isSameGeometryClass(other) {
|
|
387
|
+
return other instanceof BSplineCurve3d;
|
|
388
|
+
}
|
|
356
389
|
/** Apply `transform` to the poles. */
|
|
357
|
-
tryTransformInPlace(transform) {
|
|
358
|
-
|
|
390
|
+
tryTransformInPlace(transform) {
|
|
391
|
+
PointHelpers_1.Point3dArray.multiplyInPlace(transform, this._bcurve.packedData);
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
/** Get a pole as a simple Point3d. */
|
|
359
395
|
getPolePoint3d(poleIndex, result) {
|
|
360
396
|
const k = this.poleIndexToDataIndex(poleIndex);
|
|
361
397
|
if (k !== undefined) {
|
|
@@ -364,7 +400,7 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
364
400
|
}
|
|
365
401
|
return undefined;
|
|
366
402
|
}
|
|
367
|
-
/** Get a pole as Point4d with weight 1 */
|
|
403
|
+
/** Get a pole as Point4d with weight 1. */
|
|
368
404
|
getPolePoint4d(poleIndex, result) {
|
|
369
405
|
const k = this.poleIndexToDataIndex(poleIndex);
|
|
370
406
|
if (k !== undefined) {
|
|
@@ -373,23 +409,26 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
373
409
|
}
|
|
374
410
|
return undefined;
|
|
375
411
|
}
|
|
376
|
-
/** Convert `spanIndex` and `localFraction` to a knot. */
|
|
377
|
-
spanFractionToKnot(span, localFraction) {
|
|
378
|
-
return this._bcurve.spanFractionToKnot(span, localFraction);
|
|
379
|
-
}
|
|
380
|
-
constructor(numPoles, order, knots) {
|
|
381
|
-
super(3, numPoles, order, knots);
|
|
382
|
-
}
|
|
383
|
-
/** Return a simple array of arrays with the control points as `[[x,y,z],[x,y,z],..]` */
|
|
384
|
-
copyPoints() { return PointHelpers_1.Point3dArray.unpackNumbersToNestedArrays(this._bcurve.packedData, 3); }
|
|
385
|
-
/** Return a simple array of the control points coordinates */
|
|
386
|
-
copyPointsFloat64Array() { return this._bcurve.packedData.slice(); }
|
|
387
412
|
/**
|
|
388
|
-
*
|
|
389
|
-
* in
|
|
413
|
+
* Convert the fractional position in the given span to a knot.
|
|
414
|
+
* * The returned value is not necessarily a knot, but it is a valid parameter in the domain of the B-spline curve.
|
|
390
415
|
*/
|
|
391
|
-
|
|
392
|
-
|
|
416
|
+
spanFractionToKnot(spanIndex, spanFraction) {
|
|
417
|
+
return this._bcurve.spanFractionToKnot(spanIndex, spanFraction);
|
|
418
|
+
}
|
|
419
|
+
/** Return a simple array of arrays with the poles as `[[x,y,z],[x,y,z],..]`. */
|
|
420
|
+
copyPoints() {
|
|
421
|
+
return PointHelpers_1.Point3dArray.unpackNumbersToNestedArrays(this._bcurve.packedData, 3);
|
|
422
|
+
}
|
|
423
|
+
/** Return a simple array of poles' coordinates. */
|
|
424
|
+
copyPointsFloat64Array() {
|
|
425
|
+
return this._bcurve.packedData.slice();
|
|
426
|
+
}
|
|
427
|
+
/** Return a simple array form of the knots. Optionally replicate the first and last in classic over-clamped manner. */
|
|
428
|
+
copyKnots(includeExtraEndKnot) {
|
|
429
|
+
return this._bcurve.knots.copyKnots(includeExtraEndKnot);
|
|
430
|
+
}
|
|
431
|
+
/** Create a B-spline with uniform knots. */
|
|
393
432
|
static createUniformKnots(poles, order) {
|
|
394
433
|
const numPoles = poles instanceof Float64Array ? poles.length / 3 : poles.length;
|
|
395
434
|
if (order < 2 || numPoles < order)
|
|
@@ -413,9 +452,10 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
413
452
|
}
|
|
414
453
|
return curve;
|
|
415
454
|
}
|
|
416
|
-
/**
|
|
417
|
-
*
|
|
418
|
-
|
|
455
|
+
/**
|
|
456
|
+
* Create a smoothly closed B-spline curve with uniform knots.
|
|
457
|
+
* * Note that the curve does not start at the first pole.
|
|
458
|
+
*/
|
|
419
459
|
static createPeriodicUniformKnots(poles, order) {
|
|
420
460
|
if (order < 2)
|
|
421
461
|
return undefined;
|
|
@@ -486,21 +526,23 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
486
526
|
return BSplineCurveOps_1.BSplineCurveOps.createThroughPointsC2Cubic(options);
|
|
487
527
|
}
|
|
488
528
|
/**
|
|
489
|
-
*
|
|
529
|
+
* Create a B-spline curve from an Akima curve.
|
|
490
530
|
* @param options collection of points and end conditions.
|
|
491
531
|
*/
|
|
492
532
|
static createFromAkimaCurve3dOptions(options) {
|
|
493
533
|
return BSplineCurveOps_1.BSplineCurveOps.createThroughPoints(options.fitPoints, 4); // temporary
|
|
494
534
|
}
|
|
495
535
|
/**
|
|
496
|
-
* Create a
|
|
536
|
+
* Create a B-spline curve with given knots.
|
|
497
537
|
* * The poles have several variants:
|
|
498
|
-
* * Float64Array(3 * numPoles) in blocks of [x,y,z]
|
|
499
|
-
* * Point3d[]
|
|
500
|
-
* * number[][], with inner dimension 3
|
|
538
|
+
* * Float64Array(3 * numPoles) in blocks of [x,y,z].
|
|
539
|
+
* * Point3d[].
|
|
540
|
+
* * number[][], with inner dimension 3.
|
|
501
541
|
* * Two count conditions are recognized:
|
|
502
|
-
* * If poleArray.length + order === knotArray.length, the first and last are assumed to be the extraneous knots
|
|
542
|
+
* * If poleArray.length + order === knotArray.length, the first and last are assumed to be the extraneous knots
|
|
543
|
+
* of classic clamping.
|
|
503
544
|
* * If poleArray.length + order === knotArray.length + 2, the knots are in modern form.
|
|
545
|
+
* * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/BSpline/
|
|
504
546
|
*/
|
|
505
547
|
static create(poleArray, knotArray, order) {
|
|
506
548
|
if (order < 2)
|
|
@@ -538,31 +580,42 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
538
580
|
}
|
|
539
581
|
return curve;
|
|
540
582
|
}
|
|
541
|
-
/** Return a deep clone */
|
|
583
|
+
/** Return a deep clone. */
|
|
542
584
|
clone() {
|
|
543
|
-
const
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
return
|
|
585
|
+
const knotVector = this._bcurve.knots.clone();
|
|
586
|
+
const curve = new BSplineCurve3d(this.numPoles, this.order, knotVector);
|
|
587
|
+
curve._bcurve.packedData = this._bcurve.packedData.slice();
|
|
588
|
+
return curve;
|
|
547
589
|
}
|
|
548
|
-
/** Evaluate at a
|
|
590
|
+
/** Evaluate the curve at a fractional position within a given span. */
|
|
549
591
|
evaluatePointInSpan(spanIndex, spanFraction) {
|
|
550
592
|
this._bcurve.evaluateBuffersInSpan(spanIndex, spanFraction);
|
|
551
593
|
return Point3dVector3d_1.Point3d.createFrom(this._bcurve.poleBuffer);
|
|
552
594
|
}
|
|
553
|
-
/**
|
|
554
|
-
*
|
|
595
|
+
/**
|
|
596
|
+
* Evaluate the curve and derivative at a fractional position within a given span.
|
|
597
|
+
* * The derivative is with respect to the span fractional parameter, _not_ to the curve's parameter or fractional parameter.
|
|
555
598
|
*/
|
|
556
599
|
evaluatePointAndDerivativeInSpan(spanIndex, spanFraction) {
|
|
557
600
|
this._bcurve.evaluateBuffersInSpan1(spanIndex, spanFraction);
|
|
558
601
|
return Ray3d_1.Ray3d.createCapture(Point3dVector3d_1.Point3d.createFrom(this._bcurve.poleBuffer), Point3dVector3d_1.Vector3d.createFrom(this._bcurve.poleBuffer1));
|
|
559
602
|
}
|
|
560
|
-
/**
|
|
603
|
+
/**
|
|
604
|
+
* Evaluate the curve at the given parameter.
|
|
605
|
+
* @param u parameter in curve domain.
|
|
606
|
+
* @param result optional result.
|
|
607
|
+
* @returns the point on the curve.
|
|
608
|
+
*/
|
|
561
609
|
knotToPoint(u, result) {
|
|
562
610
|
this._bcurve.evaluateBuffersAtKnot(u);
|
|
563
611
|
return Point3dVector3d_1.Point3d.createFrom(this._bcurve.poleBuffer, result);
|
|
564
612
|
}
|
|
565
|
-
/**
|
|
613
|
+
/**
|
|
614
|
+
* Evaluate the curve and derivative at the given parameter.
|
|
615
|
+
* @param u parameter in curve domain.
|
|
616
|
+
* @param result optional result.
|
|
617
|
+
* @returns the ray with origin at the curve point and direction as the derivative.
|
|
618
|
+
*/
|
|
566
619
|
knotToPointAndDerivative(u, result) {
|
|
567
620
|
this._bcurve.evaluateBuffersAtKnot(u, 1);
|
|
568
621
|
if (!result)
|
|
@@ -571,12 +624,17 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
571
624
|
result.direction.setFrom(this._bcurve.poleBuffer1);
|
|
572
625
|
return result;
|
|
573
626
|
}
|
|
574
|
-
/**
|
|
627
|
+
/**
|
|
628
|
+
* Evaluate the curve and two derivatives at the given parameter.
|
|
629
|
+
* @param u parameter in the curve domain.
|
|
630
|
+
* @param result optional result.
|
|
631
|
+
* @returns the plane with origin at the curve point, vectorU as the 1st derivative, and vectorV as the 2nd derivative.
|
|
632
|
+
*/
|
|
575
633
|
knotToPointAnd2Derivatives(u, result) {
|
|
576
634
|
this._bcurve.evaluateBuffersAtKnot(u, 2);
|
|
577
635
|
return Plane3dByOriginAndVectors_1.Plane3dByOriginAndVectors.createOriginAndVectorsXYZ(this._bcurve.poleBuffer[0], this._bcurve.poleBuffer[1], this._bcurve.poleBuffer[2], this._bcurve.poleBuffer1[0], this._bcurve.poleBuffer1[1], this._bcurve.poleBuffer1[2], this._bcurve.poleBuffer2[0], this._bcurve.poleBuffer2[1], this._bcurve.poleBuffer2[2], result);
|
|
578
636
|
}
|
|
579
|
-
/**
|
|
637
|
+
/** Test if `this` is almost the same curve as `other`. */
|
|
580
638
|
isAlmostEqual(other) {
|
|
581
639
|
if (other instanceof BSplineCurve3d) {
|
|
582
640
|
return this._bcurve.knots.isAlmostEqual(other._bcurve.knots)
|
|
@@ -584,15 +642,19 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
584
642
|
}
|
|
585
643
|
return false;
|
|
586
644
|
}
|
|
587
|
-
/**
|
|
645
|
+
/** Test if this curve lies entirely in the given plane. */
|
|
588
646
|
isInPlane(plane) {
|
|
589
647
|
return PointHelpers_1.Point3dArray.isCloseToPlane(this._bcurve.packedData, plane);
|
|
590
648
|
}
|
|
591
|
-
/**
|
|
592
|
-
|
|
593
|
-
|
|
649
|
+
/**
|
|
650
|
+
* Return the control polygon length as an approximation to the curve length.
|
|
651
|
+
* * The returned length is always an overestimate.
|
|
652
|
+
*/
|
|
653
|
+
quickLength() {
|
|
654
|
+
return PointHelpers_1.Point3dArray.sumEdgeLengths(this._bcurve.packedData);
|
|
655
|
+
}
|
|
656
|
+
/** Emit Beziers or strokes (selected by the stroke options) to the handler. */
|
|
594
657
|
emitStrokableParts(handler, options) {
|
|
595
|
-
const needBeziers = handler.announceBezierCurve !== undefined;
|
|
596
658
|
const workBezier = this.initializeWorkBezier();
|
|
597
659
|
const numSpan = this.numSpan;
|
|
598
660
|
let numStrokes;
|
|
@@ -600,7 +662,7 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
600
662
|
const bezier = this.getSaturatedBezierSpan3dOr3dH(spanIndex, false, workBezier);
|
|
601
663
|
if (bezier) {
|
|
602
664
|
numStrokes = bezier.computeStrokeCountForOptions(options);
|
|
603
|
-
if (
|
|
665
|
+
if (handler.announceBezierCurve) {
|
|
604
666
|
handler.announceBezierCurve(bezier, numStrokes, this, spanIndex, this._bcurve.knots.spanFractionToFraction(spanIndex, 0.0), this._bcurve.knots.spanFractionToFraction(spanIndex, 1.0));
|
|
605
667
|
}
|
|
606
668
|
else {
|
|
@@ -625,7 +687,7 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
625
687
|
return numStroke;
|
|
626
688
|
}
|
|
627
689
|
/**
|
|
628
|
-
* Compute individual segment stroke counts.
|
|
690
|
+
* Compute individual segment stroke counts. Attach in a StrokeCountMap.
|
|
629
691
|
* @param options StrokeOptions that determine count
|
|
630
692
|
* @param parentStrokeMap evolving parent map.
|
|
631
693
|
* @alpha
|
|
@@ -644,7 +706,7 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
644
706
|
}
|
|
645
707
|
CurvePrimitive_1.CurvePrimitive.installStrokeCountMap(this, myData, parentStrokeMap);
|
|
646
708
|
}
|
|
647
|
-
/** Append strokes to
|
|
709
|
+
/** Append strokes to the given linestring. */
|
|
648
710
|
emitStrokes(dest, options) {
|
|
649
711
|
const workBezier = this.initializeWorkBezier();
|
|
650
712
|
const numSpan = this.numSpan;
|
|
@@ -655,16 +717,17 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
655
717
|
}
|
|
656
718
|
}
|
|
657
719
|
/**
|
|
658
|
-
* Test knots and
|
|
720
|
+
* Test knots and poles to determine if it is possible to close (aka "wrap") the curve.
|
|
659
721
|
* @returns the manner in which it is possible to close the curve. See `BSplineWrapMode` for particulars of each mode.
|
|
660
722
|
*/
|
|
661
723
|
get isClosable() {
|
|
662
724
|
return this.isClosableCurve;
|
|
663
725
|
}
|
|
664
726
|
/**
|
|
665
|
-
* Return
|
|
666
|
-
*
|
|
667
|
-
* @param
|
|
727
|
+
* Return the Bezier fragment corresponding to the given span of this curve.
|
|
728
|
+
* * The concrete return type may be [[BezierCurve3d]] or [[BezierCurve3dH]] according to the instance type and `prefer3dH`.
|
|
729
|
+
* @param spanIndex index of span.
|
|
730
|
+
* @param result optional reusable curve. This will only be reused if its type and order matches.
|
|
668
731
|
*/
|
|
669
732
|
getSaturatedBezierSpan3dOr3dH(spanIndex, prefer3dH, result) {
|
|
670
733
|
if (prefer3dH)
|
|
@@ -672,9 +735,9 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
672
735
|
return this.getSaturatedBezierSpan3d(spanIndex, result);
|
|
673
736
|
}
|
|
674
737
|
/**
|
|
675
|
-
* Return
|
|
676
|
-
* @param spanIndex
|
|
677
|
-
* @param result optional reusable curve.
|
|
738
|
+
* Return the Bezier fragment corresponding to the given span of this curve.
|
|
739
|
+
* @param spanIndex index of span.
|
|
740
|
+
* @param result optional reusable curve. This will only be reused if its type and order matches.
|
|
678
741
|
*/
|
|
679
742
|
getSaturatedBezierSpan3d(spanIndex, result) {
|
|
680
743
|
if (spanIndex < 0 || spanIndex >= this.numSpan)
|
|
@@ -685,13 +748,13 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
685
748
|
const bezier = result;
|
|
686
749
|
bezier.loadSpanPoles(this._bcurve.packedData, spanIndex);
|
|
687
750
|
if (bezier.saturateInPlace(this._bcurve.knots, spanIndex))
|
|
688
|
-
return
|
|
751
|
+
return bezier;
|
|
689
752
|
return undefined;
|
|
690
753
|
}
|
|
691
754
|
/**
|
|
692
|
-
* Return
|
|
693
|
-
* @param spanIndex
|
|
694
|
-
* @param result optional reusable curve.
|
|
755
|
+
* Return the Bezier fragment corresponding to the given span of this curve.
|
|
756
|
+
* @param spanIndex index of span.
|
|
757
|
+
* @param result optional reusable curve. This will only be reused if its type and order matches.
|
|
695
758
|
*/
|
|
696
759
|
getSaturatedBezierSpan3dH(spanIndex, result) {
|
|
697
760
|
if (spanIndex < 0 || spanIndex >= this.numSpan)
|
|
@@ -705,15 +768,16 @@ class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
705
768
|
return bezier;
|
|
706
769
|
return undefined;
|
|
707
770
|
}
|
|
708
|
-
/** Second step of double dispatch:
|
|
771
|
+
/** Second step of double dispatch: call `handler.handleBSplineCurve3d(this)`. */
|
|
709
772
|
dispatchToGeometryHandler(handler) {
|
|
710
773
|
return handler.handleBSplineCurve3d(this);
|
|
711
774
|
}
|
|
712
775
|
/**
|
|
713
|
-
* Extend a range so
|
|
714
|
-
* *
|
|
715
|
-
*
|
|
716
|
-
* @param
|
|
776
|
+
* Extend a range so it contains the range of this curve.
|
|
777
|
+
* * This computation is based on the poles, not the curve itself, so the returned range is generally larger than the
|
|
778
|
+
* tightest possible range.
|
|
779
|
+
* @param rangeToExtend range to extend.
|
|
780
|
+
* @param transform transform to apply to the poles as they are entered into the range.
|
|
717
781
|
*/
|
|
718
782
|
extendRange(rangeToExtend, transform) {
|
|
719
783
|
const buffer = this._bcurve.packedData;
|