## BSplineSurface3d Class

BSplineSurface3d is a parametric surface in xyz space.

• This (BSplineSurface3d) is an unweighted surface. Use the separate class BSplineSurface3dH for a weighted surface.

The various static "create" methods have subtle differences in how grid sizes are conveyed: | Method | control point array | counts | | create | flat array of [x,y,z] | arguments numPolesU, numPolesV | | createGrid | array of array of [x,y,z ] | There are no `numPolesU` or `numPolesV` args. The counts are conveyed by the deep arrays |

### Methods

Name Description
constructor(numPolesU: number, numPolesV: number, poleLength: number, knotsU: KnotVector, knotsV: KnotVector): Protected initialize arrays for given spline dimensions.
clone(): Return a complete copy of the bspline surface.
cloneTransformed(transform: Transform): Return a complete copy of the bspline surface, with a transform applied to the control points.
copyKnots(select: UVSelect, includeExtraEndKnot: boolean): number[] return a simple array form of the knots.
copyPointsFloat64Array(): Float64Array Return a simple array of the control points coordinates
dispatchToGeometryHandler(handler: GeometryHandler): any Second step of double dispatch: call `handler.handleBSplineSurface3d(this)`
extendRange(rangeToExtend: Range3d, transform?: Transform): void Extend the range to include all poles
* This is not a tight range.

fractionToPoint(fractionU: number, fractionV: number): Evaluate at a position given by fractional coordinate in each direction.
fractionToPointAndDerivatives(fractionU: number, fractionV: number, result?: Plane3dByOriginAndVectors): evaluate the surface at u and v fractions.
getPointArray(flatArray: boolean = true): any[] Return control points json arrays.
getPointGridJSON(): Return control points json arrays.
getPole(i: number, j: number, result?: Point3d): Point3d | undefined Return a pole by u and v indices
isAlmostEqual(other: any): boolean test for identical counts and near-equal coordinates
isInPlane(): boolean Test if all poles are in a plane
isSameGeometryClass(other: any): boolean Test if `other` is an instance of `BSplineSurface3d
knotToPoint(u: number, v: number): Evaluate at a position given by u and v coordinates in knot space.
knotToPointAndDerivatives(u: number, v: number, result?: Plane3dByOriginAndVectors): Evaluate at a position given by a knot value.
tryTransformInPlace(transform: Transform): boolean Apply the transform to the poles
create(controlPointArray: Point3d[] | Float64Array, numPolesU: number, orderU: number, knotArrayU: number[] | Float64Array | undefined, numPolesV: number, orderV: number, knotArrayV: number[] | Float64Array | undefined): BSplineSurface3d | undefined Static Create a bspline surface.
createGrid(points: number[][][], orderU: number, knotArrayU: number[] | Float64Array | undefined, orderV: number, knotArrayV: number[] | Float64Array | undefined): BSplineSurface3d | undefined Static Create a bspline surface.

### Inherited methods

Name Inherited from Description
degreeUV(select: UVSelect): number BSpline2dNd Return the degree (one less than order) for the `select` direction (0 or 1)
evaluateBuffersAtKnot(u: number, v: number, numDerivative: number = 0): void BSpline2dNd Evaluate the _basisBuffer, _poleBuffer and (optionally) _basisBuffer1 and _poleBuffer1 arrays at given knot.
extendRangeXYZ(rangeToExtend: Range3d, transform?: Transform): void BSpline2dNd extend a range, treating each block as simple XYZ
extendRangeXYZH(rangeToExtend: Range3d, transform?: Transform): void BSpline2dNd extend a range, treating each block as homogeneous xyzw, with weight at offset 3
fractionToRigidFrame(fractionU: number, fractionV: number, result?: Transform): Transform | undefined BSpline2dNd evaluate the surface at u and v fractions.
getPoint3dPole(i: number, j: number, result?: Point3d): Point3d | undefined BSpline2dNd Get the Point3d by row and column.
getPoint3dPoleXYZW(i: number, j: number, result?: Point3d): Point3d | undefined BSpline2dNd Get the Point3d by row and column, projecting the weight away to get to xyz
* (IMPORTANT) This assumes this is an xyzw surface.
isClosable(select: UVSelect): boolean BSpline2dNd Test if `degree` leading and trailing (one of U or V) blocks match, as if the data is an unwrapped closed spline in the selected direction.
numPolesTotal(): number BSpline2dNd Return the total number of poles (product of x and y pole counts)
numPolesUV(select: UVSelect): number BSpline2dNd Return the number of poles for the `select` direction (0 or 1)
numSpanUV(select: UVSelect): number BSpline2dNd Return the number of spans (INCLUDING NULL SPANS) for the `select` direction (0 or 1)
numberToUVSelect(value: number): BSpline2dNd Return 0 for 0 input, 1 for any nonzero input.
orderUV(select: UVSelect): number BSpline2dNd Return the order (one more than degree) for the `select` direction (0 or 1)
poleStepUV(select: UVSelect): number BSpline2dNd Return the step between adjacent poles for the `select` direction (0 or 1)
range(transform?: Transform, result?: Range3d): GeometryQuery return the range of the entire (tree) GeometryQuery
reverseInPlace(select: UVSelect): void BSpline2dNd Reverse the parameter direction for either u or v.
setWrappable(select: UVSelect, value: BSplineWrapMode): void BSpline2dNd Set the flag indicating the bspline might be suitable for having wrapped "closed" interpretation.
spanFractionToKnot(select: UVSelect, span: number, localFraction: number): number BSpline2dNd Map a position, specified as (uv direction, bezier span, fraction within the bezier), to an overall knot value.
spanFractionsToBasisFunctions(select: UVSelect, spanIndex: number, spanFraction: number, f: Float64Array, df?: Float64Array): void BSpline2dNd Evaluate basis functions given
choice of u or v
span index
* local fraction within the span.
sumPoleBufferForSpan(spanIndexU: number, spanIndexV: number): void BSpline2dNd sum poles by the weights in the basisBuffer, using poles for given span
sumpoleBufferDerivativesForSpan(spanIndexU: number, spanIndexV: number): void BSpline2dNd sum derivatives by the weights in the basisBuffer, using poles for given span
tryTranslateInPlace(dx: number, dy: number = 0, dz: number = 0): boolean GeometryQuery try to move the geometry by dx,dy,dz
validOrderAndPoleCounts(orderU: number, numPolesU: number, orderV: number, numPolesV: number, numUV: number): boolean Static BSpline2dNd Confirm that order and pole counts agree for both u and v directions

### Inherited properties

Name Type Inherited from Description
_basisBuffer1UV Protected Float64Array[] BSpline2dNd a scratch array sized for `order` numbers
_basisBufferUV Protected Float64Array[] BSpline2dNd a scratch array sized for `order` numbers
_poleBuffer Protected Float64Array BSpline2dNd a scratch array sized for one pole
_poleBuffer1UV Protected Float64Array[] BSpline2dNd array of 2 scratch array, each sized for one pole
* used in derivative evaluations, with respective u and v derivatives in the respective arrays.
children Accessor ReadOnly GeometryQuery[] | undefined GeometryQuery return GeometryQuery children for recursive queries.

* leaf classes do not need to implement.
coffs Float64Array BSpline2dNd flat array of coordinate daa, blocked by poleDimension and row
geometryCategory "bsurf" = "bsurf" BSpline2dNd
knots BSpline2dNd Array of (exactly 2) knot vectors for the u, v directions
poleDimension number BSpline2dNd Number of componets per pole.

### Defined in

Last Updated: 20 September, 2019