/* $NoKeywords: $ */ /* // // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert // McNeel & Associates. // // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF // MERCHANTABILITY ARE HEREBY DISCLAIMED. // // For complete openNURBS copyright information see . // //////////////////////////////////////////////////////////////// */ #if !defined(OPENNURBS_BEZIER_INC_) #define OPENNURBS_BEZIER_INC_ class ON_PolynomialCurve; class ON_PolynomialSurface; class ON_BezierCurve; class ON_BezierSurface; class ON_TextLog; class ON_NurbsCurve; class ON_NurbsSurface; class ON_X_EVENT; class ON_CLASS ON_PolynomialCurve { public: ON_PolynomialCurve(); // Description: // See ON_PolynomialCurve::Create. // Parameters: // dim - [in] dimension of the curve // bIsRational - [in] true if rational // order - [in] (>=2) order = degree+1 ON_PolynomialCurve( int dim, ON_BOOL32 bIsRational, int order ); ~ON_PolynomialCurve(); ON_PolynomialCurve(const ON_PolynomialCurve&); ON_PolynomialCurve(const ON_BezierCurve&); ON_PolynomialCurve& operator=(const ON_PolynomialCurve&); ON_PolynomialCurve& operator=(const ON_BezierCurve&); // Description: // Initializes fields and allocates the m_cv array. // Parameters: // dim - [in] dimension of the curve // bIsRational - [in] true if rational // order - [in] (>=2) order = degree+1 ON_BOOL32 Create( int dim, ON_BOOL32 bIsRational, int order ); // Description: // Deallocates the m_cv array and sets fields to zero. void Destroy(); // Description: // Evaluate a polynomial curve. // Parameters: // t - [in] evaluation parameter ( usually in Domain() ). // der_count - [in] (>=0) number of derivatives to evaluate // v_stride - [in] (>=Dimension()) stride to use for the v[] array // v - [out] array of length (der_count+1)*v_stride // curve(t) is returned in (v[0],...,v[m_dim-1]), // curve'(t) is retuned in (v[v_stride],...,v[v_stride+m_dim-1]), // curve"(t) is retuned in (v[2*v_stride],...,v[2*v_stride+m_dim-1]), // etc. // Returns: // false if unable to evaluate. ON_BOOL32 Evaluate( double t, int der_count, int v_stride, double* v ) const; // dimension of polynomial curve (1,2, or 3) int m_dim; // 1 if polynomial curve is rational, 0 if polynomial curve is not rational int m_is_rat; // order (=degree+1) of polynomial int m_order; // coefficients ( m_cv.Count() = order of monomial ) ON_4dPointArray m_cv; // domain of polynomial ON_Interval m_domain; }; class ON_CLASS ON_PolynomialSurface { public: ON_PolynomialSurface(); ON_PolynomialSurface( int, // dim, ON_BOOL32, // true if rational int, // "u" order int // "v" order ); ~ON_PolynomialSurface(); ON_PolynomialSurface(const ON_PolynomialSurface&); ON_PolynomialSurface(const ON_BezierSurface&); ON_PolynomialSurface& operator=(const ON_PolynomialSurface&); ON_PolynomialSurface& operator=(const ON_BezierSurface&); ON_BOOL32 Create( int, // dim, ON_BOOL32, // true if rational int, // "u" order int // "v" order ); void Destroy(); ON_BOOL32 Evaluate( // returns false if unable to evaluate double s, double t, // evaluation parameter int der_count, // number of derivatives (>=0) int v_stride, // array stride (>=Dimension()) double* v // array of length stride*(ndir+1)*(ndir+2)/2 ) const; int m_dim; // 1,2, or 3 int m_is_rat; // 1 if rational, 0 if not rational int m_order[2]; ON_4dPointArray m_cv; // coefficients ( m_C.Length() = m_order[0]*m_order[1] // coefficient of s^m*t^n = m_cv[m_order[1]*m+n] ON_Interval m_domain[2]; }; class ON_CLASS ON_BezierCurve { public: ON_BezierCurve(); // Description: // Creates a bezier with cv memory allocated. // Parameters: // dim - [in] (>0) dimension of bezier curve // bIsRational - [in] true for a rational bezier // order - [in] (>=2) order (=degree+1) of bezier curve ON_BezierCurve( int dim, ON_BOOL32 bIsRational, int order ); ~ON_BezierCurve(); ON_BezierCurve(const ON_BezierCurve&); ON_BezierCurve(const ON_PolynomialCurve&); ON_BezierCurve(const ON_2dPointArray&); // sets control points ON_BezierCurve(const ON_3dPointArray&); // sets control points ON_BezierCurve(const ON_4dPointArray&); // sets control points ON_BezierCurve& operator=(const ON_BezierCurve&); ON_BezierCurve& operator=(const ON_PolynomialCurve&); ON_BezierCurve& operator=(const ON_2dPointArray&); // sets control points ON_BezierCurve& operator=(const ON_3dPointArray&); // sets control points ON_BezierCurve& operator=(const ON_4dPointArray&); // sets control points bool IsValid() const; void Dump( ON_TextLog& ) const; // for debugging // Returns: // Dimension of bezier. int Dimension() const; // Description: // Creates a bezier with cv memory allocated. // Parameters: // dim - [in] (>0) dimension of bezier curve // bIsRational - [in] true for a rational bezier // order - [in] (>=2) order (=degree+1) of bezier curve // Returns: // true if successful. bool Create( int dim, ON_BOOL32 bIsRational, int order ); // Description: // Deallocates m_cv memory. void Destroy(); void EmergencyDestroy(); // call if memory used by ON_NurbsCurve becomes invalid // Description: // Loft a bezier curve through a list of points. // Parameters: // points - [in] an array of 2 or more points to interpolate // Returns: // true if successful // Remarks: // The result has order = points.Count() and the loft uses the // uniform parameterizaton curve( i/(points.Count()-1) ) = points[i]. bool Loft( const ON_3dPointArray& points ); // Description: // Loft a bezier curve through a list of points. // Parameters: // pt_dim - [in] dimension of points to interpolate // pt_count - [in] number of points (>=2) // pt_stride - [in] (>=pt_dim) pt[] array stride // pt - [in] array of points // t_stride - [in] (>=1) t[] array stride // t - [in] strictly increasing array of interpolation parameters // Returns: // true if successful // Remarks: // The result has order = points.Count() and the loft uses the // parameterizaton curve( t[i] ) = points[i]. bool Loft( int pt_dim, int pt_count, int pt_stride, const double* pt, int t_stride, const double* t ); // Description: // Gets bounding box. // Parameters: // box_min - [out] minimum corner of axis aligned bounding box // The box_min[] array must have size m_dim. // box_max - [out] maximum corner of axis aligned bounding box // The box_max[] array must have size m_dim. // bGrowBox - [in] if true, input box_min/box_max must be set // to valid bounding box corners and this box is enlarged to // be the union of the input box and the bezier's bounding // box. // Returns: // true if successful. bool GetBBox( // returns true if successful double* box_min, double* box_max, int bGrowBox = false ) const; // Description: // Gets bounding box. // Parameters: // bbox - [out] axis aligned bounding box returned here. // bGrowBox - [in] if true, input bbox must be a valid // bounding box and this box is enlarged to // be the union of the input box and the // bezier's bounding box. // Returns: // true if successful. bool GetBoundingBox( ON_BoundingBox& bbox, int bGrowBox = false ) const; // Description: // Gets bounding box. // Returns: // Axis aligned bounding box. ON_BoundingBox BoundingBox() const; /* Description: Get tight bounding box of the bezier. Parameters: tight_bbox - [in/out] tight bounding box bGrowBox -[in] (default=false) If true and the input tight_bbox is valid, then returned tight_bbox is the union of the input tight_bbox and the tight bounding box of the bezier curve. xform -[in] (default=NULL) If not NULL, the tight bounding box of the transformed bezier is calculated. The bezier curve is not modified. Returns: True if the returned tight_bbox is set to a valid bounding box. */ bool GetTightBoundingBox( ON_BoundingBox& tight_bbox, int bGrowBox = false, const ON_Xform* xform = 0 ) const; // Description: // Transform the bezier. // Parameters: // xform - [in] transformation to apply to bezier // Returns: // true if successful. false if bezier is invalid // and cannot be transformed. bool Transform( const ON_Xform& xform ); // Description: // Rotates the bezier curve about the specified axis. A positive // rotation angle results in a counter-clockwise rotation // about the axis (right hand rule). // Parameters: // sin_angle - [in] sine of rotation angle // cos_angle - [in] sine of rotation angle // rotation_axis - [in] direction of the axis of rotation // rotation_center - [in] point on the axis of rotation // Returns: // true if bezier curve successfully rotated // Remarks: // Uses ON_BezierCurve::Transform() function to calculate the result. bool Rotate( double sin_angle, double cos_angle, const ON_3dVector& rotation_axis, const ON_3dPoint& rotation_center ); // Description: // Rotates the bezier curve about the specified axis. A positive // rotation angle results in a counter-clockwise rotation // about the axis (right hand rule). // Parameters: // rotation_angle - [in] angle of rotation in radians // rotation_axis - [in] direction of the axis of rotation // rotation_center - [in] point on the axis of rotation // Returns: // true if bezier curve successfully rotated // Remarks: // Uses ON_BezierCurve::Transform() function to calculate the result. bool Rotate( double rotation_angle, const ON_3dVector& rotation_axis, const ON_3dPoint& rotation_center ); // Description: // Translates the bezier curve along the specified vector. // Parameters: // translation_vector - [in] translation vector // Returns: // true if bezier curve successfully translated // Remarks: // Uses ON_BezierCurve::Transform() function to calculate the result. bool Translate( const ON_3dVector& translation_vector ); // Description: // Scales the bezier curve by the specified facotor. The scale is // centered at the origin. // Parameters: // scale_factor - [in] scale factor // Returns: // true if bezier curve successfully scaled // Remarks: // Uses ON_BezierCurve::Transform() function to calculate the result. bool Scale( double scale_factor ); // Returns: // Domain of bezier (always [0,1]). ON_Interval Domain() const; // Description: // Reverses bezier by reversing the order // of the control points. bool Reverse(); // Description: // Evaluate point at a parameter. // Parameters: // t - [in] evaluation parameter // Returns: // Point (location of curve at the parameter t). ON_3dPoint PointAt( double t ) const; // Description: // Evaluate first derivative at a parameter. // Parameters: // t - [in] evaluation parameter // Returns: // First derivative of the curve at the parameter t. // Remarks: // No error handling. // See Also: // ON_Curve::Ev1Der ON_3dVector DerivativeAt( double t ) const; // Description: // Evaluate unit tangent vector at a parameter. // Parameters: // t - [in] evaluation parameter // Returns: // Unit tangent vector of the curve at the parameter t. // Remarks: // No error handling. // See Also: // ON_Curve::EvTangent ON_3dVector TangentAt( double t ) const; // Description: // Evaluate the curvature vector at a parameter. // Parameters: // t - [in] evaluation parameter // Returns: // curvature vector of the curve at the parameter t. // Remarks: // No error handling. // See Also: // ON_Curve::EvCurvature ON_3dVector CurvatureAt( double t ) const; // Description: // Evaluate point at a parameter with error checking. // Parameters: // t - [in] evaluation parameter // point - [out] value of curve at t // Returns: // false if unable to evaluate. bool EvPoint( double t, ON_3dPoint& point ) const; // Description: // Evaluate first derivative at a parameter with error checking. // Parameters: // t - [in] evaluation parameter // point - [out] value of curve at t // first_derivative - [out] value of first derivative at t // Returns: // false if unable to evaluate. bool Ev1Der( double t, ON_3dPoint& point, ON_3dVector& first_derivative ) const; // Description: // Evaluate second derivative at a parameter with error checking. // Parameters: // t - [in] evaluation parameter // point - [out] value of curve at t // first_derivative - [out] value of first derivative at t // second_derivative - [out] value of second derivative at t // Returns: // false if unable to evaluate. bool Ev2Der( double t, ON_3dPoint& point, ON_3dVector& first_derivative, ON_3dVector& second_derivative ) const; /* Description: Evaluate unit tangent at a parameter with error checking. Parameters: t - [in] evaluation parameter point - [out] value of curve at t tangent - [out] value of unit tangent Returns: false if unable to evaluate. See Also: ON_Curve::TangentAt ON_Curve::Ev1Der */ bool EvTangent( double t, ON_3dPoint& point, ON_3dVector& tangent ) const; /* Description: Evaluate unit tangent and curvature at a parameter with error checking. Parameters: t - [in] evaluation parameter point - [out] value of curve at t tangent - [out] value of unit tangent kappa - [out] value of curvature vector Returns: false if unable to evaluate. */ bool EvCurvature( double t, ON_3dPoint& point, ON_3dVector& tangent, ON_3dVector& kappa ) const; // Description: // Evaluate a bezier. // Parameters: // t - [in] evaluation parameter (usually 0 <= t <= 1) // der_count - [in] (>=0) number of derivatives to evaluate // v_stride - [in] (>=m_dim) stride to use for the v[] array // v - [out] array of length (der_count+1)*v_stride // bez(t) is returned in (v[0],...,v[m_dim-1]), // bez'(t) is retuned in (v[v_stride],...,v[v_stride+m_dim-1]), // bez"(t) is retuned in (v[2*v_stride],...,v[2*v_stride+m_dim-1]), // etc. // Returns: // true if successful bool Evaluate( double t, int der_count, int v_stride, double* v ) const; // Description: // Get ON_NurbsCurve form of a bezier. // Parameters: // nurbs_curve - [out] NURBS curve form of a bezier. // The domain is [0,1]. // Returns: // true if successful bool GetNurbForm( ON_NurbsCurve& nurbs_curve ) const; // Returns: // true if bezier is rational. bool IsRational() const; // Returns: // Number of doubles per control vertex. // (= IsRational() ? Dim()+1 : Dim()) int CVSize() const; // Returns: // Number of control vertices in the bezier. // This is always the same as the order of the bezier. int CVCount() const; // Returns: // Order of the bezier. (order=degree+1) int Order() const; // order = degree + 1 // Returns: // Degree of the bezier. (degree=order-1) int Degree() const; /* Description: Expert user function to get a pointer to control vertex memory. If you are not an expert user, please use ON_BezierCurve::GetCV( ON_3dPoint& ) or ON_BezierCurve::GetCV( ON_4dPoint& ). Parameters: cv_index - [in] (0 <= cv_index < m_order) Returns: Pointer to control vertex. Remarks: If the Bezier curve is rational, the format of the returned array is a homogeneos rational point with length m_dim+1. If the Bezier curve is not rational, the format of the returned array is a nonrational euclidean point with length m_dim. See Also ON_BezierCurve::CVStyle ON_BezierCurve::GetCV ON_BezierCurve::Weight */ double* CV( int cv_index ) const; /* Description: Returns the style of control vertices in the m_cv array. Returns: @untitled table ON::not_rational m_is_rat is false ON::homogeneous_rational m_is_rat is true */ ON::point_style CVStyle() const; // Parameters: // cv_index - [in] control vertex index (0<=i 0). If c != 1, then the returned bezier will be rational. Returns: true if successful. Remarks: The reparameterization is performed by composing the input Bezier with the function lambda: [0,1] -> [0,1] given by t -> c*t / ( (c-1)*t + 1 ) Note that lambda(0) = 0, lambda(1) = 1, lambda'(t) > 0, lambda'(0) = c and lambda'(1) = 1/c. If the input Bezier has control vertices {B_0, ..., B_d}, then the output Bezier has control vertices (B_0, ... c^i * B_i, ..., c^d * B_d). To derive this formula, simply compute the i-th Bernstein polynomial composed with lambda(). The inverse parameterization is given by 1/c. That is, the cumulative effect of the two calls Reparameterize(c) Reparameterize(1.0/c) is to leave the bezier unchanged. See Also: ON_Bezier::ScaleConrolPoints */ bool Reparameterize( double c ); // misspelled function name is obsolete ON_DEPRECATED bool Reparametrize(double); /* Description: Scale a rational Bezier's control vertices to set a weight to a specified value. Parameters: i - [in] (0 <= i < order) w - [in] w != 0.0 Returns: True if successful. The i-th control vertex will have weight w. Remarks: Each control point is multiplied by w/w0, where w0 is the input value of Weight(i). See Also: ON_Bezier::Reparameterize ON_Bezier::ChangeWeights */ bool ScaleConrolPoints( int i, double w ); /* Description: Use a combination of scaling and reparameterization to set two rational Bezier weights to specified values. Parameters: i0 - [in] control point index (0 <= i0 < order, i0 != i1) w0 - [in] Desired weight for i0-th control point i1 - [in] control point index (0 <= i1 < order, i0 != i1) w1 - [in] Desired weight for i1-th control point Returns: True if successful. The returned bezier has the same locus but probably has a different parameterization. Remarks: The i0-th cv will have weight w0 and the i1-rst cv will have weight w1. If v0 and v1 are the cv's input weights, then v0, v1, w0 and w1 must all be nonzero, and w0*v0 and w1*v1 must have the same sign. The equations s * r^i0 = w0/v0 s * r^i1 = w1/v1 determine the scaling and reparameterization necessary to change v0,v1 to w0,w1. If the input Bezier has control vertices (B_0, ..., B_d), then the output Bezier has control vertices (s*B_0, ... s*r^i * B_i, ..., s*r^d * B_d). See Also: ON_Bezier::Reparameterize ON_Bezier::ScaleConrolPoints */ bool ChangeWeights( int i0, double w0, int i1, double w1 ); ///////////////////////////////////////////////////////////////// // Implementation public: // NOTE: These members are left "public" so that expert users may efficiently // create bezier curves using the default constructor and borrow the // knot and CV arrays from their native NURBS representation. // No technical support will be provided for users who access these // members directly. If you can't get your stuff to work, then use // the constructor with the arguments and the SetKnot() and SetCV() // functions to fill in the arrays. // dimension of bezier (>=1) int m_dim; // 1 if bezier is rational, 0 if bezier is not rational int m_is_rat; // order = degree+1 int m_order; // Number of doubles per cv ( >= ((m_is_rat)?m_dim+1:m_dim) ) int m_cv_stride; // The i-th cv begins at cv[i*m_cv_stride]. double* m_cv; // Number of doubles in m_cv array. If m_cv_capacity is zero // and m_cv is not NULL, an expert user is managing the m_cv // memory. ~ON_BezierCurve will not deallocate m_cv unless // m_cv_capacity is greater than zero. int m_cv_capacity; #if 8 == ON_SIZEOF_POINTER // pad to a multiple of 8 bytes so custom allocators // will keep m_cv aligned and tail-padding reuse will // not be an issue. int m_reserved_ON_BezierCurve; #endif }; class ON_CLASS ON_BezierSurface { public: ON_BezierSurface(); ON_BezierSurface( int dim, int is_rat, int order0, int order1 ); ~ON_BezierSurface(); ON_BezierSurface(const ON_BezierSurface&); ON_BezierSurface(const ON_PolynomialSurface&); ON_BezierSurface& operator=(const ON_BezierSurface&); ON_BezierSurface& operator=(const ON_PolynomialSurface&); bool IsValid() const; void Dump( ON_TextLog& ) const; // for debugging int Dimension() const; bool Create( int dim, int is_rat, int order0, int order1 ); void Destroy(); void EmergencyDestroy(); // call if memory used by ON_NurbsCurve becomes invalid /* Description: Loft a bezier surface through a list of bezier curves. Parameters: curve_list - [in] list of curves that have the same degree. Returns: True if successful. */ bool Loft( const ON_ClassArray& curve_list ); /* Description: Loft a bezier surface through a list of bezier curves. Parameters: curve_count - [in] number of curves in curve_list curve_list - [in] array of pointers to curves that have the same degree. Returns: True if successful. */ bool Loft( int count, const ON_BezierCurve* const* curve_list ); bool GetBBox( // returns true if successful double*, // minimum double*, // maximum int bGrowBox = false // true means grow box ) const; bool GetBoundingBox( ON_BoundingBox& bbox, int bGrowBox ) const; ON_BoundingBox BoundingBox() const; bool Transform( const ON_Xform& ); // Description: // Rotates the bezier surface about the specified axis. A positive // rotation angle results in a counter-clockwise rotation // about the axis (right hand rule). // Parameters: // sin_angle - [in] sine of rotation angle // cos_angle - [in] sine of rotation angle // rotation_axis - [in] direction of the axis of rotation // rotation_center - [in] point on the axis of rotation // Returns: // true if bezier surface successfully rotated // Remarks: // Uses ON_BezierSurface::Transform() function to calculate the result. bool Rotate( double sin_angle, double cos_angle, const ON_3dVector& rotation_axis, const ON_3dPoint& rotation_center ); // Description: // Rotates the bezier surface about the specified axis. A positive // rotation angle results in a counter-clockwise rotation // about the axis (right hand rule). // Parameters: // rotation_angle - [in] angle of rotation in radians // rotation_axis - [in] direction of the axis of rotation // rotation_center - [in] point on the axis of rotation // Returns: // true if bezier surface successfully rotated // Remarks: // Uses ON_BezierSurface::Transform() function to calculate the result. bool Rotate( double rotation_angle, const ON_3dVector& rotation_axis, const ON_3dPoint& rotation_center ); // Description: // Translates the bezier surface along the specified vector. // Parameters: // translation_vector - [in] translation vector // Returns: // true if bezier surface successfully translated // Remarks: // Uses ON_BezierSurface::Transform() function to calculate the result. bool Translate( const ON_3dVector& translation_vector ); // Description: // Scales the bezier surface by the specified facotor. The scale is // centered at the origin. // Parameters: // scale_factor - [in] scale factor // Returns: // true if bezier surface successfully scaled // Remarks: // Uses ON_BezierSurface::Transform() function to calculate the result. bool Scale( double scale_factor ); ON_Interval Domain( int // 0 = "u" domain, 1 = "v" domain ) const; bool Reverse( int ); // reverse parameterizatrion // Domain changes from [a,b] to [-b,-a] bool Transpose(); // transpose surface parameterization (swap "s" and "t") bool Evaluate( // returns false if unable to evaluate double, double, // evaluation parameter int, // number of derivatives (>=0) int, // array stride (>=Dimension()) double* // array of length stride*(ndir+1)*(ndir+2)/2 ) const; ON_3dPoint PointAt(double s, double t) const; bool GetNurbForm( ON_NurbsSurface& ) const; bool IsRational() const; // true if NURBS curve is rational int CVSize() const; // number of doubles per control vertex // = IsRational() ? Dim()+1 : Dim() int Order( // order = degree + 1 int // dir ) const; int Degree( // degree = order - 1 int // dir ) const; /* Description: Expert user function to get a pointer to control vertex memory. If you are not an expert user, please use ON_BezierSurface::GetCV( ON_3dPoint& ) or ON_BezierSurface::GetCV( ON_4dPoint& ). Parameters: cv_index0 - [in] (0 <= cv_index0 < m_order[0]) cv_index1 - [in] (0 <= cv_index1 < m_order[1]) Returns: Pointer to control vertex. Remarks: If the Bezier surface is rational, the format of the returned array is a homogeneos rational point with length m_dim+1. If the Bezier surface is not rational, the format of the returned array is a nonrational euclidean point with length m_dim. See Also ON_BezierSurface::CVStyle ON_BezierSurface::GetCV ON_BezierSurface::Weight */ double* CV( int cv_index0, int cv_index1 ) const; /* Description: Returns the style of control vertices in the m_cv array. Returns: @untitled table ON::not_rational m_is_rat is false ON::homogeneous_rational m_is_rat is true */ ON::point_style CVStyle() const; double Weight( // get value of control vertex weight int,int // CV index ( >= 0 and < CVCount() ) ) const; bool SetWeight( // set value of control vertex weight int,int, // CV index ( >= 0 and < CVCount() ) double ); bool SetCV( // set a single control vertex int,int, // CV index ( >= 0 and < CVCount() ) ON::point_style, // style of input point const double* // value of control vertex ); bool SetCV( // set a single control vertex int,int, // CV index ( >= 0 and < CVCount() ) const ON_3dPoint& // value of control vertex // If NURBS is rational, weight // will be set to 1. ); bool SetCV( // set a single control vertex int,int, // CV index ( >= 0 and < CVCount() ) const ON_4dPoint& // value of control vertex // If NURBS is not rational, euclidean // location of homogeneous point will // be used. ); bool GetCV( // get a single control vertex int,int, // CV index ( >= 0 and < CVCount() ) ON::point_style, // style to use for output point double* // array of length >= CVSize() ) const; bool GetCV( // get a single control vertex int,int, // CV index ( >= 0 and < CVCount() ) ON_3dPoint& // gets euclidean cv when NURBS is rational ) const; bool GetCV( // get a single control vertex int,int, // CV index ( >= 0 and < CVCount() ) ON_4dPoint& // gets homogeneous cv ) const; bool ZeroCVs(); // zeros control vertices and, if rational, sets weights to 1 bool MakeRational(); bool MakeNonRational(); bool Split( int, // 0 split at "u"=t, 1= split at "v"=t double, // t = splitting parameter must 0 < t < 1 ON_BezierSurface&, // west/south side returned here (can pass *this) ON_BezierSurface& // east/north side returned here (can pass *this) ) const; bool Trim( int dir, const ON_Interval& domain ); // returns the isocurve. ON_BezierCurve* IsoCurve( int dir, // 0 first parameter varies and second parameter is constant // e.g., point on IsoCurve(0,c) at t is srf(t,c) // 1 first parameter is constant and second parameter varies // e.g., point on IsoCurve(1,c) at t is srf(c,t) double c, // value of constant parameter ON_BezierCurve* iso=NULL // When NULL result is constructed on the heap. ) const; bool IsSingular( // true if surface side is collapsed to a point int // side of parameter space to test // 0 = south, 1 = east, 2 = north, 3 = west ) const; ///////////////////////////////////////////////////////////////// // Tools for managing CV and knot memory bool ReserveCVCapacity( int // number of doubles to reserve ); ///////////////////////////////////////////////////////////////// // Implementation public: // NOTE: These members are left "public" so that expert users may efficiently // create bezier curves using the default constructor and borrow the // knot and CV arrays from their native NURBS representation. // No technical support will be provided for users who access these // members directly. If you can't get your stuff to work, then use // the constructor with the arguments and the SetKnot() and SetCV() // functions to fill in the arrays. int m_dim; // >= 1 int m_is_rat; // 0 = no, 1 = yes int m_order[2]; // order = degree+1 >= 2 int m_cv_stride[2]; double* m_cv; int m_cv_capacity; // if 0, then destructor does not free m_cv #if 8 == ON_SIZEOF_POINTER // pad to a multiple of 8 bytes so custom allocators // will keep m_cv aligned and tail-padding reuse will // not be an issue. int m_reserved_ON_BezierSurface; #endif }; class ON_CLASS ON_BezierCage { public: ON_BezierCage(); ON_BezierCage( int dim, bool is_rat, int order0, int order1, int order2 ); /* Description: Construct a bezier volume that maps the unit cube to a bounding box. Parameters: bbox - [in] target bounding box order0 - [in] order1 - [in] order2 - [in] */ ON_BezierCage( const ON_BoundingBox& bbox, int order0, int order1, int order2 ); /* Description: Construct a bezier volume that maps the unit cube to an eight sided box. Parameters: box_corners - [in] 8 points that define corners of the target volume. 7______________6 |\ |\ | \ | \ | \ _____________\ | 4 | 5 | | | | | | | | 3---|----------2 | \ | \ | \ |t \ | s \ | \ | \0_____________\1 r order0 - [in] order1 - [in] order2 - [in] */ ON_BezierCage( const ON_3dPoint* box_corners, int order0, int order1, int order2 ); ~ON_BezierCage(); ON_BezierCage(const ON_BezierCage& src); ON_BezierCage& operator=(const ON_BezierCage& src); /* Description: Tests class to make sure members are correctly initialized. Returns: True if the orders are all >= 2, dimension is positive, and the rest of the members have settings that are valid for the orders and dimension. */ bool IsValid() const; void Dump( ON_TextLog& text_log) const; /* Description: The dimension of the image of the bazier volume map. This is generally three, but can be any positive integer. Returns: Dimesion of the image space. */ int Dimension() const; /* Description: Creates a bezier volume with specified orders. Parameters: dim - [in] is_rat - [in] order0 - [in] order1 - [in] order2 - [in] Returns: True if input was valid and creation succeeded. */ bool Create( int dim, bool is_rat, int order0, int order1, int order2 ); /* Description: Create a Bezier volume with corners defined by a bounding box. Parameters: bbox - [in] target bounding box - the bezier will map the unit cube onto this bounding box. order0 - [in] order1 - [in] order2 - [in] */ bool Create( const ON_BoundingBox& bbox, int order0, int order1, int order2 ); /* Description: Create a bezier volume from a 3d box Parameters: box_corners - [in] 8 points that define corners of the volume 7______________6 |\ |\ | \ | \ | \ _____________\ | 4 | 5 | | | | | | | | 3---|----------2 | \ | \ | \ |t \ | s \ | \ | \0_____________\1 r */ bool Create( const ON_3dPoint* box_corners, int order0, int order1, int order2 ); /* Description: Frees the CV array and sets all members to zero. */ void Destroy(); /* Description: Sets all members to zero. Does not free the CV array even when m_cv is not NULL. Generally used when the CVs were allocated from a memory pool that no longer exists and the free done in ~ON_BezierCage would cause a crash. */ void EmergencyDestroy(); /* Description: Reads the definition of this class from an archive previously saved by ON_BezierVolue::Write. Parameters: archive - [in] target archive Returns: True if successful. */ bool Read(ON_BinaryArchive& archive); /* Description: Saves the definition of this class in serial binary form that can be read by ON_BezierVolue::Read. Parameters: archive - [in] target archive Returns: True if successful. */ bool Write(ON_BinaryArchive& archive) const; /* Description: Gets the axis aligned bounding box that contains the bezier's control points. The bezier volume maps the unit cube into this box. Parameters: boxmin - [in] array of Dimension() doubles boxmax - [in] array of Dimension() doubles bGrowBox = [in] if true and the input is a valid box then the input box is grown to include this object's bounding box. Returns: true if successful. */ bool GetBBox( double* boxmin, double* boxmax, int bGrowBox = false ) const; bool Transform( const ON_Xform& xform ); // Description: // Rotates the bezier surface about the specified axis. A positive // rotation angle results in a counter-clockwise rotation // about the axis (right hand rule). // Parameters: // sin_angle - [in] sine of rotation angle // cos_angle - [in] sine of rotation angle // rotation_axis - [in] direction of the axis of rotation // rotation_center - [in] point on the axis of rotation // Returns: // true if bezier surface successfully rotated // Remarks: // Uses ON_BezierCage::Transform() function to calculate the result. bool Rotate( double sin_angle, double cos_angle, const ON_3dVector& rotation_axis, const ON_3dPoint& rotation_center ); // Description: // Rotates the bezier surface about the specified axis. A positive // rotation angle results in a counter-clockwise rotation // about the axis (right hand rule). // Parameters: // rotation_angle - [in] angle of rotation in radians // rotation_axis - [in] direction of the axis of rotation // rotation_center - [in] point on the axis of rotation // Returns: // true if bezier surface successfully rotated // Remarks: // Uses ON_BezierCage::Transform() function to calculate the result. bool Rotate( double rotation_angle, const ON_3dVector& rotation_axis, const ON_3dPoint& rotation_center ); // Description: // Translates the bezier surface along the specified vector. // Parameters: // translation_vector - [in] translation vector // Returns: // true if bezier surface successfully translated // Remarks: // Uses ON_BezierCage::Transform() function to calculate the result. bool Translate( const ON_3dVector& translation_vector ); // Description: // Scales the bezier surface by the specified facotor. The scale is // centered at the origin. // Parameters: // scale_factor - [in] scale factor // Returns: // true if bezier surface successfully scaled // Remarks: // Uses ON_BezierCage::Transform() function to calculate the result. bool Scale( double scale_factor ); ON_Interval Domain( int // 0 = "u" domain, 1 = "v" domain, 2 = "w" domain ) const; // returns false if unable to evaluate bool Evaluate( double r, double s, double t, int der_count, int v_stride, double* v // array of length stride*(ndir+1)*(ndir+2)/2 ) const; /* Description: Evaluates bezer volume map. Parameters: rst - [in] Returns: Value of the bezier volume map at (r,s,t). */ ON_3dPoint PointAt( double r, double s, double t ) const; /* Description: Evaluates bezer volume map. Parameters: rst - [in] Returns: Value of the bezier volume map at (rst.x,rst.y,rst.z). */ ON_3dPoint PointAt( ON_3dPoint rst ) const; bool IsRational() const; // true if NURBS curve is rational bool IsSingular( // true if surface side is collapsed to a point int // side of parameter space to test // 0 = south, 1 = east, 2 = north, 3 = west ) const; int CVSize() const; // number of doubles per control vertex // = IsRational() ? Dim()+1 : Dim() int Order( // order = degree + 1 int // dir ) const; int Degree( // degree = order - 1 int // dir ) const; /* Description: Expert user function to get a pointer to control vertex memory. If you are not an expert user, please use ON_BezierCage::GetCV( ON_3dPoint& ) or ON_BezierCage::GetCV( ON_4dPoint& ). Parameters: cv_index0 - [in] (0 <= cv_index0 < m_order[0]) cv_index1 - [in] (0 <= cv_index1 < m_order[1]) Returns: Pointer to control vertex. Remarks: If the Bezier surface is rational, the format of the returned array is a homogeneos rational point with length m_dim+1. If the Bezier surface is not rational, the format of the returned array is a nonrational euclidean point with length m_dim. See Also ON_BezierCage::CVStyle ON_BezierCage::GetCV ON_BezierCage::Weight */ double* CV( int i, int j, int k ) const; /* Description: Returns the style of control vertices in the m_cv array. Returns: @untitled table ON::not_rational m_is_rat is false ON::homogeneous_rational m_is_rat is true */ ON::point_style CVStyle() const; double Weight( // get value of control vertex weight int i, int j, int k ) const; bool SetWeight( // set value of control vertex weight int i, int j, int k, double w ); bool SetCV( // set a single control vertex int i, int j, int k, ON::point_style, // style of input point const double* // value of control vertex ); // set a single control vertex // If NURBS is rational, weight // will be set to 1. bool SetCV( int i, int j, int k, const ON_3dPoint& point ); // set a single control vertex // value of control vertex // If NURBS is not rational, euclidean // location of homogeneous point will // be used. bool SetCV( int i, int j, int k, const ON_4dPoint& hpoint ); bool GetCV( // get a single control vertex int i, int j, int k, ON::point_style, // style to use for output point double* // array of length >= CVSize() ) const; bool GetCV( // get a single control vertex int i, int j, int k, ON_3dPoint& // gets euclidean cv when NURBS is rational ) const; bool GetCV( // get a single control vertex int i, int j, int k, ON_4dPoint& // gets homogeneous cv ) const; bool ZeroCVs(); // zeros control vertices and, if rational, sets weights to 1 bool MakeRational(); bool MakeNonRational(); ///////////////////////////////////////////////////////////////// // Tools for managing CV and knot memory /* Description: cv_capacity - [in] number of doubles to reserve */ bool ReserveCVCapacity( int cv_capacity ); ///////////////////////////////////////////////////////////////// // Implementation public: // NOTE: These members are left "public" so that expert users may efficiently // create bezier curves using the default constructor and borrow the // knot and CV arrays from their native NURBS representation. // No technical support will be provided for users who access these // members directly. If you can't get your stuff to work, then use // the constructor with the arguments and the SetKnot() and SetCV() // functions to fill in the arrays. int m_dim; bool m_is_rat; int m_order[3]; int m_cv_stride[3]; int m_cv_capacity; double* m_cv; }; class ON_CLASS ON_BezierCageMorph : public ON_SpaceMorph { public: ON_BezierCageMorph(); ~ON_BezierCageMorph(); /* Description: Create a Bezier volume. Parameters: P0 - [in] P1 - [in] P2 - [in] P3 - [in] P0,P1,P2,P3 defines a parallepiped in world space. The morph maps this parallepiped to the (0,1)x(0,1)x(0,1) unit cube and then applies the BezierCage map. ______________ |\ |\ | \ | \ | \P3____________\ | | | | | | | | | | | | P2---|---------- | \ | \ | \ |z \ | y \ | \ | \P0____________P1 x point_countX - [in] point_countY - [in] point_countZ - [in] Number of control points in the bezier volume map. The bezier volume in the returned morph is the identity map which can be modified as needed. Returns: True if resulting morph is valid. See Also: ON_BezierCage::SetBezierCage ON_BezierCage::SetXform */ bool Create( ON_3dPoint P0, ON_3dPoint P1, ON_3dPoint P2, ON_3dPoint P3, int point_countX, int point_countY, int point_countZ ); /* Description: Set the world to unit cube map. Parameters: world2unitcube - [in] Tranformation matrix that maps world coordinates to the unit cube (0,1)x(0,1)x(0,1). Returns True if current bezier volum and input transformation matrix are valid. In all cases, the morph's m_xyz2rst member is set. See Also: ON_BezierCage::Create ON_BezierCage::SetBezierCage */ bool SetXform( ON_Xform world2unitcube ); /* Description: Set the unit cube to world map. Parameters: world2unitcube - [in] Bezier volume map from the unit cube (0,1)x(0,1)x(0,1) to world space. Returns True if current transformation matrix and input bezier volume are valid. In all cases, the morph's m_rst2xyz member is set. See Also: ON_BezierCage::Create ON_BezierCage::SetXform */ bool SetBezierCage( ON_BezierCage& unitcube2world ); const ON_Xform& WorldToUnitCube() const; const ON_BezierCage& BezierCage() const; bool Read(ON_BinaryArchive& archive); bool Write(ON_BinaryArchive& archive) const; /* Description: Transforms the morph by transforming the bezier volume map. Parameters: xform - [in] Returns True if input is valid. */ bool Transform(const ON_Xform& xform); private: bool m_bValid; // transforms world (x,y,z) coordinate into // unit cube. ON_Xform m_xyz2rst; // function that maps unit cube into world ON_BezierCage m_rst2xyz; }; #if defined(ON_DLL_TEMPLATE) // This stuff is here because of a limitation in the way Microsoft // handles templates and DLLs. See Microsoft's knowledge base // article ID Q168958 for details. #pragma warning( push ) #pragma warning( disable : 4231 ) ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray; ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray; #pragma warning( pop ) #endif #endif