/** @packageDocumentation
 * @module Bspline
 */
import { VariantCurveExtendParameter } from "../curve/CurveExtendMode";
import { CurveLocationDetail } from "../curve/CurveLocationDetail";
import { CurvePrimitive } from "../curve/CurvePrimitive";
import { LineString3d } from "../curve/LineString3d";
import { OffsetOptions } from "../curve/OffsetOptions";
import { StrokeCountMap } from "../curve/Query/StrokeCountMap";
import { StrokeOptions } from "../curve/StrokeOptions";
import { PlaneAltitudeEvaluator } from "../Geometry";
import { GeometryHandler, IStrokeHandler } from "../geometry3d/GeometryHandler";
import { GrowableXYZArray } from "../geometry3d/GrowableXYZArray";
import { Plane3dByOriginAndUnitNormal } from "../geometry3d/Plane3dByOriginAndUnitNormal";
import { Plane3dByOriginAndVectors } from "../geometry3d/Plane3dByOriginAndVectors";
import { Point3d, Vector3d } from "../geometry3d/Point3dVector3d";
import { Range1d, Range3d } from "../geometry3d/Range";
import { Ray3d } from "../geometry3d/Ray3d";
import { Transform } from "../geometry3d/Transform";
import { Point4d } from "../geometry4d/Point4d";
import { AkimaCurve3dOptions } from "./AkimaCurve3d";
import { BezierCurve3d } from "./BezierCurve3d";
import { BezierCurve3dH } from "./BezierCurve3dH";
import { BezierCurveBase } from "./BezierCurveBase";
import { BSpline1dNd } from "./BSpline1dNd";
import { InterpolationCurve3dOptions } from "./InterpolationCurve3d";
import { BSplineWrapMode, KnotVector } from "./KnotVector";
/**
 * Base class for BSplineCurve3d and BSplineCurve3dH.
 * * A B-spline curve consists of an array of `knots`, an array of `poles`, and a `degree`.
 * * The knot array is a non-decreasing sequence of numbers. It is also called a "knot vector".
 *   * The curve is a parametric function whose domain is a sub-range of its knots.
 *   * The API sometimes refers to a domain parameter `u` as a "knot", even if `u` is not actually an entry in the
 * knot array.
 * * The curve loosely "follows" the line string formed by the poles, aka the "control polygon".
 * * The curve is a chain of polynomial segments, aka "spans" or "fragments". B-spline theory identifies these as
 * Bezier curves.
 * * The polynomial spans all have same `degree`.
 * * Each span is controlled by `order = degree + 1` contiguous points in the pole array.
 * * There is a strict relationship between knot and poles counts: `numPoles + order = numKnots + 2'.
 * * The number of spans is `numSpan = numPoles - degree`.
 * * For a span with index `spanIndex`:
 *   * The `order` relevant poles begin at pole index `spanIndex`.
 *   * The `2*degree` relevant knots begin at knot index `spanIndex`.
 *   * The span domain is the knot range `[knot[spanIndex+degree-1], knot[spanIndex+degree]]`.
 * * The curve domain is the knot range `[knot[degree-1], knot[numSpan+degree-1]]`, or equivalently
 * `[knot[degree-1], knot[numPoles-1]]`. The API refers to this domain as the "active knot interval" of the curve.
 *
 * Nearly all B-spline curves are "clamped".
 * * This means that in the `knots` array, the first `degree` knots are equal, and the last `degree` knots are equal.
 * We say the smallest knot and the largest knot have multiplicity `degree`.
 * * Clamping make the curve pass through its first and last poles, with tangents directed along the first and
 * last edges of the control polygon.
 * * For instance, a cubic B-spline curve with knot vector `[0,0,0,1,2,3,3,3]`
 *   * can be evaluated at parameter values in the range `[0, 3]`
 *   * has 3 spans, with domains `[0, 1]`, `[1, 2]`, and `[2, 3]`
 *   * has 6 poles
 *   * passes through its first and last poles.
 * * The `create` methods may allow the classic convention that has an extra knot at the beginning and end of the
 * knot vector.
 *   * These two extra knots are not actually needed to define the B-spline curve.
 *   * When the `create` methods recognize the classic setup (`numPoles + order = numKnots`), the extra knots are
 * not saved with the BSplineCurve3dBase knots.
 *
 * * The weighted variant [[BSplineCurve3dH]] has the problem that `CurvePrimitive` 3D typing does not allow the
 *  undefined result where a homogeneous pole has zero weight; the convention in this case is to return 000.
 *
 * * Note the class relationships:
 *   * [[BSpline1dNd]] knows the definitional B-spline recurrence relation with no physical interpretation for the poles.
 *   * BsplineCurve3dBase owns a protected BSpline1dNd.
 *   * `BsplineCurve3dBase` is derived from [[CurvePrimitive]], which creates obligation to act as a 3D curve, e.g.,
 *     * evaluate fraction to point and derivatives wrt fraction.
 *     * compute intersection with plane.
 *   * [[BSplineCurve3d]] and [[BSplineCurve3dH]] have variant logic driven by whether or not there are "weights" on the poles.
 *     * For `BSplineCurve3d`, the xyz value of pole calculations are "final" values for 3d evaluation.
 *     * For `BSplineCurve3dH`, various `BSpline1dNd` results with xyzw have to be normalized back to xyz.
 *
 * * These classes do not support "periodic" variants.
 *   * Periodic curves historically have carried a flag (e.g., "closed") indicating that certain un-stored
 * leading/trailing knots and poles are understood to wrap around periodically.
 *   * Instead, these classes carry no such flag. They represent such curves with explicitly wrapped knots/poles.
 *
 * * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/BSpline/
 * @public
 */
export declare abstract class BSplineCurve3dBase extends CurvePrimitive {
    /** String name for schema properties. */
    readonly curvePrimitiveType = "bsplineCurve";
    /** The underlying blocked-pole spline, with simple x,y,z poles. */
    protected _bcurve: BSpline1dNd;
    private _definitionData?;
    set definitionData(data: any);
    get definitionData(): any;
    protected constructor(poleDimension: number, numPoles: number, order: number, knots: KnotVector);
    /** Return the degree (one less than the order) of the curve. */
    get degree(): number;
    /** Return the order (one more than degree) of the curve. */
    get order(): number;
    /**
     * Return the number of Bezier spans in the curve. Note that this number includes the number of null
     * spans at repeated knows.
     */
    get numSpan(): number;
    /** Return the number of poles. */
    get numPoles(): number;
    /** Return live reference to the poles of the curve. */
    get polesRef(): Float64Array;
    /** Return live reference to the knots of the curve. */
    get knotsRef(): Float64Array;
    /**
     * Number of components per pole, e.g.,
     * * 3 for conventional (x,y,z) curve.
     * * 4 for weighted (wx,wy,wz,w) curve.
     */
    get poleDimension(): number;
    /** Return a simple array form of the knots. Optionally replicate the first and last in classic over-clamped manner. */
    copyKnots(includeExtraEndKnot: boolean): number[];
    /** Get the flag indicating the curve might be suitable for having wrapped "closed" interpretation. */
    getWrappable(): BSplineWrapMode;
    /** Set the flag indicating the curve might be suitable for having wrapped "closed" interpretation. */
    setWrappable(value: BSplineWrapMode): void;
    /**
     * Test knots and poles to determine if it is possible to close (aka "wrap") the curve.
     * @returns the manner in which it is possible to close the curve. See `BSplineWrapMode` for particulars of each mode.
     */
    get isClosableCurve(): BSplineWrapMode;
    /** Evaluate the curve at a fractional position within a given span. */
    abstract evaluatePointInSpan(spanIndex: number, spanFraction: number, result?: Point3d): Point3d;
    /**
     * Evaluate the curve and derivative at a fractional position within a given span.
     * * The derivative is with respect to the span fractional parameter, _not_ to the curve's parameter or fractional parameter.
    */
    abstract evaluatePointAndDerivativeInSpan(spanIndex: number, spanFraction: number, result?: Ray3d): Ray3d;
    /** Evaluate the curve at the given parameter. */
    abstract knotToPoint(knot: number, result?: Point3d): Point3d;
    /** Evaluate the curve and derivative at the given parameter. */
    abstract knotToPointAndDerivative(knot: number, result?: Ray3d): Ray3d;
    /** Evaluate the curve and two derivatives at the given parameter. */
    abstract knotToPointAnd2Derivatives(knot: number, result?: Plane3dByOriginAndVectors): Plane3dByOriginAndVectors;
    /** Evaluate the curve point at the given fractional parameter. */
    fractionToPoint(fraction: number, result?: Point3d): Point3d;
    /** Evaluate the curve and derivative at the given fractional parameter. */
    fractionToPointAndDerivative(fraction: number, result?: Ray3d): Ray3d;
    /** Evaluate the curve and two derivatives at the given fractional parameter. */
    fractionToPointAnd2Derivatives(fraction: number, result?: Plane3dByOriginAndVectors): Plane3dByOriginAndVectors;
    /** Return the start point of the curve. */
    startPoint(result?: Point3d): Point3d;
    /** Return the end point of the curve. */
    endPoint(result?: Point3d): Point3d;
    /**
     * Reverse the curve in place.
     * * Poles are reversed.
     * * Knot values are mirrored around the middle of the knot array.
     */
    reverseInPlace(): void;
    /** Return an array with this curve's Bezier fragments. */
    collectBezierSpans(prefer3dH: boolean): BezierCurveBase[];
    /**
     * Return the Bezier fragment corresponding to the given span of this curve.
     * * The concrete return type may be [[BezierCurve3d]] or [[BezierCurve3dH]] according to the instance type and `prefer3dH`.
     * @param spanIndex index of span.
     * @param prefer3dH true to force promotion to homogeneous.
     * @param result optional reusable curve. This will only be reused if its type and order matches.
     */
    abstract getSaturatedBezierSpan3dOr3dH(spanIndex: number, prefer3dH: boolean, result?: BezierCurveBase): BezierCurveBase | undefined;
    /**
     * Return a specified pole as a Point4d.
     * * BSplineCurve3d appends weight 1 to its xyz.
     * * BSplineCurve3dH with pole whose "normalized" point is (x,y,z) but has weight w returns the weighted form (wx,wy,wz,w).
     */
    abstract getPolePoint4d(poleIndex: number, result?: Point4d): Point4d | undefined;
    /**
     * Return a specified pole as a Point3d.
     * * BSplineCurve3d returns its simple xyz.
     * * BSplineCurve3dH attempts to normalize its (wx,wy,wz,w) back to (x,y,z), and returns undefined if weight is zero.
     * @param poleIndex index of the pole.
     * @param result optional result.
     */
    abstract getPolePoint3d(poleIndex: number, result?: Point3d): Point3d | undefined;
    /** Given a pole index, return the starting index for the contiguous array. */
    poleIndexToDataIndex(poleIndex: number): number | undefined;
    /**
     * Search for the curve point that is closest to the spacePoint.
     * * If the space point is exactly on the curve, this is the reverse of fractionToPoint.
     * * Since CurvePrimitive should always have start and end available as candidate points, this method should always
     * succeed.
     * @param spacePoint point in space.
     * @param _extend ignored (pass false). A BSplineCurve3dBase cannot be extended.
     * @param result optional pre-allocated detail to populate and return.
     * @returns details of the closest point.
     */
    closestPoint(spacePoint: Point3d, _extend: VariantCurveExtendParameter, result?: CurveLocationDetail): CurveLocationDetail | undefined;
    /** Return a deep clone. */
    abstract clone(): BSplineCurve3dBase;
    /** Return a transformed deep clone. */
    cloneTransformed(transform: Transform): BSplineCurve3dBase;
    /**
     * Return a curve primitive which is a portion of this curve.
     * @param fractionA start fraction.
     * @param fractionB end fraction.
     */
    clonePartialCurve(fractionA: number, fractionB: number): BSplineCurve3dBase;
    /**
     * Implement `CurvePrimitive.appendPlaneIntersections` to compute intersections of the curve with a plane.
     * @param plane the plane with which to intersect the curve. Concrete types include [[Plane3dByOriginAndUnitNormal]],
     * [[Point4d]], etc.
     * @param result growing array of plane intersections.
     * @return number of intersections appended to the array.
    */
    appendPlaneIntersectionPoints(plane: PlaneAltitudeEvaluator, result: CurveLocationDetail[]): number;
    /**
     * Construct an offset of the instance curve as viewed in the xy-plane (ignoring z).
     * @param offsetDistanceOrOptions offset distance (positive to left of the instance curve), or options object.
     */
    constructOffsetXY(offsetDistanceOrOptions: number | OffsetOptions): BSplineCurve3d | undefined;
    /**
     * Project instance geometry (via dispatch) onto the given ray, and return the extreme fractional parameters
     * of projection.
     * @param ray ray onto which the instance is projected. A `Vector3d` is treated as a `Ray3d` with zero origin.
     * @param lowHigh optional receiver for output.
     * @returns range of fractional projection parameters onto the ray, where 0.0 is start of the ray and 1.0 is the
     * end of the ray.
     */
    projectedParameterRange(ray: Vector3d | Ray3d, lowHigh?: Range1d): Range1d | undefined;
}
/**
 * A BSplineCurve3d is a B-spline curve whose poles are Point3d.
 * See BSplineCurve3dBase for description of knots, order, degree, and poles.
 * @public
 */
export declare class BSplineCurve3d extends BSplineCurve3dBase {
    private _workBezier?;
    private initializeWorkBezier;
    private constructor();
    /** Test if `other` is an instance of BSplineCurve3d. */
    isSameGeometryClass(other: any): boolean;
    /** Apply `transform` to the poles. */
    tryTransformInPlace(transform: Transform): boolean;
    /** Get a pole as a simple Point3d. */
    getPolePoint3d(poleIndex: number, result?: Point3d): Point3d | undefined;
    /** Get a pole as Point4d with weight 1. */
    getPolePoint4d(poleIndex: number, result?: Point4d): Point4d | undefined;
    /**
     * Convert the fractional position in the given span to a knot.
     * * The returned value is not necessarily a knot, but it is a valid parameter in the domain of the B-spline curve.
     */
    spanFractionToKnot(spanIndex: number, spanFraction: number): number;
    /** Return a simple array of arrays with the poles as `[[x,y,z],[x,y,z],..]`. */
    copyPoints(): any[];
    /** Return a simple array of poles' coordinates. */
    copyPointsFloat64Array(): Float64Array;
    /** Return a simple array form of the knots. Optionally replicate the first and last in classic over-clamped manner. */
    copyKnots(includeExtraEndKnot: boolean): number[];
    /** Create a B-spline with uniform knots. */
    static createUniformKnots(poles: Point3d[] | Float64Array | GrowableXYZArray, order: number): BSplineCurve3d | undefined;
    /**
     * Create a smoothly closed B-spline curve with uniform knots.
     * * Note that the curve does not start at the first pole.
     */
    static createPeriodicUniformKnots(poles: Point3d[] | Float64Array | GrowableXYZArray, order: number): BSplineCurve3d | undefined;
    /**
     * Create a C2 cubic B-spline curve that interpolates the given points and optional end tangents.
     * @param options collection of points and end conditions.
     */
    static createFromInterpolationCurve3dOptions(options: InterpolationCurve3dOptions): BSplineCurve3d | undefined;
    /**
     * Create a B-spline curve from an Akima curve.
     * @param options collection of points and end conditions.
     */
    static createFromAkimaCurve3dOptions(options: AkimaCurve3dOptions): BSplineCurve3d | undefined;
    /**
     * Create a B-spline curve with given knots.
     * * The poles have several variants:
     *    * Float64Array(3 * numPoles) in blocks of [x,y,z].
     *    * Point3d[].
     *    * number[][], with inner dimension 3.
     * * Two count conditions are recognized:
     *    * If poleArray.length + order === knotArray.length, the first and last are assumed to be the extraneous knots
     *      of classic clamping.
     *    * If poleArray.length + order === knotArray.length + 2, the knots are in modern form.
     * * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/BSpline/
     */
    static create(poleArray: Float64Array | Point3d[] | number[][], knotArray: Float64Array | number[], order: number): BSplineCurve3d | undefined;
    /** Return a deep clone. */
    clone(): BSplineCurve3d;
    /** Evaluate the curve at a fractional position within a given span. */
    evaluatePointInSpan(spanIndex: number, spanFraction: number, result?: Point3d): Point3d;
    /**
     * Evaluate the curve and derivative at a fractional position within a given span.
     * * The derivative is with respect to the span fractional parameter, _not_ to the curve's parameter or fractional parameter.
     */
    evaluatePointAndDerivativeInSpan(spanIndex: number, spanFraction: number): Ray3d;
    /**
     * Evaluate the curve at the given parameter.
     * @param u parameter in curve domain.
     * @param result optional result.
     * @returns the point on the curve.
     */
    knotToPoint(u: number, result?: Point3d): Point3d;
    /**
     * Evaluate the curve and derivative at the given parameter.
     * @param u parameter in curve domain.
     * @param result optional result.
     * @returns the ray with origin at the curve point and direction as the derivative.
     */
    knotToPointAndDerivative(u: number, result?: Ray3d): Ray3d;
    /**
     * Evaluate the curve and two derivatives at the given parameter.
     * @param u parameter in the curve domain.
     * @param result optional result.
     * @returns the plane with origin at the curve point, vectorU as the 1st derivative, and vectorV as the 2nd derivative.
     */
    knotToPointAnd2Derivatives(u: number, result?: Plane3dByOriginAndVectors): Plane3dByOriginAndVectors;
    /** Test if `this` is almost the same curve as `other`. */
    isAlmostEqual(other: any): boolean;
    /** Test if this curve lies entirely in the given plane. */
    isInPlane(plane: Plane3dByOriginAndUnitNormal): boolean;
    /**
     * Return the control polygon length as an approximation to the curve length.
     * * The returned length is always an overestimate.
     */
    quickLength(): number;
    /** Emit Beziers or strokes (selected by the stroke options) to the handler. */
    emitStrokableParts(handler: IStrokeHandler, options?: StrokeOptions): void;
    /**
     * Assess length and turn to determine a stroke count.
     * @param options stroke options structure.
     */
    computeStrokeCountForOptions(options?: StrokeOptions): number;
    /**
     * Compute individual segment stroke counts. Attach in a StrokeCountMap.
     * @param options StrokeOptions that determine count
     * @param parentStrokeMap evolving parent map.
     * @alpha
     */
    computeAndAttachRecursiveStrokeCounts(options?: StrokeOptions, parentStrokeMap?: StrokeCountMap): void;
    /** Append strokes to the given linestring. */
    emitStrokes(dest: LineString3d, options?: StrokeOptions): void;
    /**
     * Test knots and poles to determine if it is possible to close (aka "wrap") the curve.
     * @returns the manner in which it is possible to close the curve. See `BSplineWrapMode` for particulars of each mode.
     */
    get isClosable(): BSplineWrapMode;
    /**
     * Return the Bezier fragment corresponding to the given span of this curve.
     * * The concrete return type may be [[BezierCurve3d]] or [[BezierCurve3dH]] according to the instance type and `prefer3dH`.
     * @param spanIndex index of span.
     * @param result optional reusable curve. This will only be reused if its type and order matches.
     */
    getSaturatedBezierSpan3dOr3dH(spanIndex: number, prefer3dH: boolean, result?: BezierCurveBase): BezierCurveBase | undefined;
    /**
     * Return the Bezier fragment corresponding to the given span of this curve.
     * @param spanIndex index of span.
     * @param result optional reusable curve. This will only be reused if its type and order matches.
     */
    getSaturatedBezierSpan3d(spanIndex: number, result?: BezierCurveBase): BezierCurve3d | undefined;
    /**
     * Return the Bezier fragment corresponding to the given span of this curve.
     * @param spanIndex index of span.
     * @param result optional reusable curve. This will only be reused if its type and order matches.
     */
    getSaturatedBezierSpan3dH(spanIndex: number, result?: BezierCurveBase): BezierCurve3dH | undefined;
    /** Second step of double dispatch: call `handler.handleBSplineCurve3d(this)`. */
    dispatchToGeometryHandler(handler: GeometryHandler): any;
    /**
     * Extend a range so it contains the range of this curve.
     * * This computation is based on the poles, not the curve itself, so the returned range is generally larger than the
     * tightest possible range.
     * @param rangeToExtend range to extend.
     * @param transform transform to apply to the poles as they are entered into the range.
     */
    extendRange(rangeToExtend: Range3d, transform?: Transform): void;
}
//# sourceMappingURL=BSplineCurve.d.ts.map