Interface to Alias NURBS curves geometry.
#include <AlCurve.h>
class AlCurve : public AlObject
AlCurve();
virtual ~AlCurve();
virtual statusCode deleteObject();
virtual AlObject* copyWrapper() const;
statusCode create( int, curveFormType, int, const double[], int, const double[][4], const int[]);
statusCode create( int, curveFormType, const double[], int, const double[][4]);
statusCode createLine( const double[3], const double[3] );
statusCode createArc( const double[3], const double[3], const double[3], boolean );
statusCode createArc( double *, double *, double *, double,double, double, int=3, boolean=TRUE );
statusCode createConic( double, double, double, double, double, double, const double[3], const double[3] );
statusCode createParabola( const double[3], const double[3], const double[3], const double[3] );
statusCode createEllipse( const double[3], const double[3], const double[3], const double[3], const double[3] );
statusCode createHyperbola( const double[3], const double[3], const double[3], const double[3], const double[3] );
statusCode createPoint( const double[3] );
virtual AlObjectType type() const;
AlCurveNode* curveNode() const;
curveFormType form() const;
int degree() const;
int numberOfSpans() const;
int numberOfCVs() const;
AlCurveCV* firstCV() const;
AlCurveCV* getCV( int ) const;
AlAttributes* firstAttribute() const;
statusCode CVsWorldPosition( double[][4], int[] ) const;
statusCode CVsAffectedPosition( const AlTM&, double[][4], int[] ) const;
statusCode CVsUnaffectedPosition( double[][4], int[] ) const;
statusCode setCVsUnaffectedPosition( const double[][4] );
statusCode length( double& len, boolean worldCoords = TRUE, double tolerance=0.001 );
statusCode eval(double, boolean, double P[3] = NULL, double dP[3] = NULL ) const;
statusCode eval( double dist, double P[3], double &t, boolean worldCoordinates = TRUE, double tolerance = 0.001) const;
int numberOfKnots() const;
statusCode knotVector( double[] ) const;
statusCode setKnotVector( const double[] );
int numberOfCVsInclMultiples() const;
statusCode CVsWorldPositionInclMultiples( double[][4] )const;
statusCode CVsAffectedPositionInclMultiples( const AlTM&, double[][4] ) const;
statusCode CVsUnaffectedPositionInclMultiples( double[][4] ) const;
statusCode setCVsUnaffectedPositionInclMultiples( const double[][4] );
int realNumberOfKnots() const;
statusCode realKnotVector( double[] ) const;
statusCode setRealKnotVector( const double[] );
boolean isDisplayModeSet( AlDisplayModeType ) const;
statusCode setDisplayMode( AlDisplayModeType, boolean );
statusCode applyIteratorToCVs( AlIterator*, int& );
statusCode doUpdates( boolean newState = TRUE );
statusCode periodicToNonPeriodic() const;
statusCode normal(double [3]) const;
statusCode insert( double param );
statusCode append( double pos[4], AlPointType type );
statusCode reverseCurve();
statusCode extendCurve( double , double [4] );
statusCode incrementDegree();
statusCode adjustEndSpan( double );
statusCode trimCurve( double, double );
AlCurve is the interface to the geometric data of Alias’ NURBS curve objects. To create a curve, first instantiate and create an AlCurve and then instantiate and create an AlCurveNode.
For more information on how to create the curve geometry, see the description for the create() method.
A curve form can be one of three types: periodic, closed or open. If a curve is "kPeriodic", it is tangent continuous at all points on the curve and its endpoints are coincident. If a curve is "kClosed", it is not periodic but its endpoints are coincident. If the curve is neither closed nor periodic, it is considered to be "kOpen".
There are two ways to delete an AlCurve. If the AlCurve destructor is called, the attached AlCurveNode is deleted. If the AlCurveNode destructor is called, the attached AlCurve is deleted.
You should always create a curve node for a curve. If you create a curve with no curve node, the curve is not added to the universe. If you should lose the pointer to the curve, it will become lost memory.
There is one limitation to this class: you cannot add or remove individual curve control points (except by changing multiplicity).
Curves are made of curve control points (or CVs) which you can traverse as a list by using AlCurve::firstCV() plus the AlCurveCV methods. You can also pack the curve information into an array using methods in this class.
An AlCurveCV object can actually represent multiple CVs, depending on the AlCurveCVs multiplicity and periodicity. Notice that in this class there are two sets of methods - some "InclMultiples" and some not (namely "numberOfCVs", "CVsWorldPosition", "CVsUnaffectedPosition", etc). The set of methods without multiplicity lets you get all curve CV’s where a curve CV can have multiplicity of 1, 2 or 3. The set of methods "InclMultiples" lets you get ALL curve CVs including multiples due to a multiplicity > 1 and due to periodicity.
If you create a curve in the interactive Alias package with 4 CVs and change the multiplicity of the second CV to 2 (using the "multiplicity" menu item in the Curve Tools menu), then:
If you create a curve in the interactive Alias package with 4 CVs and "close" the curve (using the "close" menu item in the Object Tools menu), you create a periodic curve. Then:
curveFormType AlCurve::form() const
When a curve is periodic it means that its endpoints are coincident and that the curve is tangent continuous at the point where its endpoints touch. "kPeriodic" is returned in this case. "kClosed" is returned if the curve is not periodic, but if its endpoints are coincident. If a curve is neither "kPeriodic" nor "kClosed" then "kOpen" is returned. (Note: If you use the "close" menu item in the interactive Alias package, you actually make a curve periodic.)
statusCode AlCurve::CVsWorldPosition( double CVList[][4], int multiplicity[] ) const
Returns the CVs in the given CV array and the multiplicity of each CV in the multiplicity vector. The first dimension of the CV array must be numberOfCVs(). The length of the multiplicity vector must also be numberOfCVs(). The multiplicity vector returned by this function is the same as the one returned by CVsUnaffectedPosition().
statusCode AlCurve::CVsAffectedPosition( const AlTM& tm, double CVList[][4], int multiplicity[] ) const
Returns the CVs in the given CV array and the multiplicity of each CV in the multiplicity vector. The first dimension of the CV array must be numberOfCVs(). The length of the multiplicity vector must also be numberOfCVs(). The multiplicity vector returned by this function is the same as the one returned by CVsUnaffectedPosition().
statusCode AlCurve::CVsUnaffectedPosition( double CVList[][4],int multiplicity[] ) const
Returns the CVs in the given CV array and the multiplicity of each CV in the multiplicity vector. The first dimension of the CV array must be numberOfCVs(). The length of the multiplicity vector must also be numberOfCVs(). The multiplicity vector returned by this function is the same as the one returned by CVsWorldPosition().
statusCode AlCurve::setCVsUnaffectedPosition( const double CVList[][4] )
statusCode AlCurve::eval(double t, boolean worldCoordinates, double P[3], double dP[3] ) const
statusCode AlCurve::eval( double dist, double P[3], double &t, boolean worldCoordinates, double tolerance ) const
Determines 3D coordinates of a point at a given distance from the start of a curve. Error tolerance must be greater than zero.
statusCode AlCurve::setKnotVector( const double knotVector[] )
int AlCurve::numberOfCVsInclMultiples() const
Returns the number of CVs, including multiples. For more information on what this value means, see the AlCurve class documentation. -1 is returned if the curve is not valid.
statusCode AlCurve::CVsWorldPositionInclMultiples( double CVList[][4] ) const
statusCode AlCurve::CVsAffectedPositionInclMultiples( const AlTM& tm, double CVList[][4] ) const
Returns the world positions of all CVs in this curve, including multiples. The first dimension of the given CVList must be of length numberOfCVsInclMultiples().
Note that the positions returned are [ x y z w ] and not [ w*x w*y w*z w ].
statusCode AlCurve::CVsUnaffectedPositionInclMultiples( double CVList[][4] ) const
statusCode AlCurve::setCVsUnaffectedPositionInclMultiples( const double CVList[][4] )
Sets the unaffected positions of all CVs in this curve, including multiples. The first dimension of the given CVList must be of length numberOfCVsInclMultiples(). You cannot give multiples different values. For example, if you have an open curve where numOfCVs() is 6 and numOfCVsInclMultiples() is 7 because the 2nd point has a multiplicity of 2, then the 2nd and 3rd quadruple in your CVList should be the same. What really happens is that the 3rd point is given the same value as the 2nd point. (What you give as the 3rd point is ignored). For more information see the examples in the class description.
boolean AlCurve::isDisplayModeSet( AlDisplayModeType mode ) const
statusCode AlCurve::setDisplayMode( AlDisplayModeType mode, boolean on_or_off)
For the given display mode, if the flag on_or_off is TRUE then the display mode for the surface is set, otherwise it is unset.
The only valid AlDisplayModeTypes for an AlCurve are:
kDisplayGeomHull
kDisplayGeomEditPoints
kDisplayGeomKeyPoints
kDisplayGeomCVs
statusCode AlCurve::create( int deg, curveFormType form, int numKnots, const double knotVector[], int numControlPts, const double controlPoint[][4], const int multiplicity[])
Creates the geometric data that represents this curve.
Briefly, Alias curves are represented by an array of knots and an array of control points. (For a detailed understanding of NURBs curves, see the book "An Introduction to Splines for use in Computer Graphics and Geometric Modeling" by Bartels, Beatty and Barsky, also known as "The Killer B’s".)
The number of spans in a curve is determined by the degree of the curve and the number of control points: namely, there are ’numControlPts - deg’ spans. Knot values are associated with the ends of each span. Therefore, ’numKnots’ must be equal to ’number of spans + 1’.
The expert will notice that ’numKnots’ = ’number of spans + 1’ does not give us enough knots to specify all the basis functions properly. (The correct number of knots required, according to the Killer B’s are numSpans + 2*degree + 1). However since Alias piles knots up at the extreme ends of an open nurbs curve (in order to force the curve to touch each end control point) this method does not require that the user specify the redundant knot values. For example, if the knot vector for a three span open curve contained the knot values [0 1 2 3], the real knot vector would be [0 0 0 0 1 2 3 3 3 3]. In the case of a periodic curve the values of the knots can be determined implicitly from the knots values provided and again don’t need to be provided explicitly. For example, if the knot vector for a four span periodic curve contained the knot values [-1 1 2 5 10], the real knot vector would be [-10 -9 -6 -1 1 2 5 10 12 13 16].
If this object was previously referencing some other curve, and this call succeeds, this object will reference the new curve.
For more information on multiplicity, see the AlCurve description.
When you create a curve, you must ensure the following:
< deg - the degree of the curve
< form - kOpen, kClosed or kPeriodic
< numKnots - the number of knots in the knotVector
< knotVector - the sequence of knot values. Must be of length numKnots.
< numControlPts - the number of points in controlPoint
< controlPoint - the array of control points. Must have size of numControlPts * 4.
< multiplicity - the multiplicity values. Must be of length numControlPts. Assumed to be an array of 1’s if NULL.
sSuccess - data created
sInsufficientMemory - ran out of memory
sInvalidArgument - there are many ways to fail with this return code
sFailure - data could not be created
statusCode AlCurve::create( int deg, curveFormType form, const double knotVector[], int numControlPts, const double controlPoint[][4] )
Creates the geometric data that represents this curve according to the standard Killer B’s representation.
Note this method’s differences from the other create method. This method assumes that the size of the number of knots passed in the knot vector is always numControlPts + deg + 1 (or numSpans + 2*deg + 1, if you prefer, where numSpans = numControlPts - deg). That is, the redundant end knots must be specified.
This method assumes that if this object was previously referencing some other curve, and this call succeeds, this object will reference the new curve.
For more information on multiplicity, see the AlCurve description.
When you create a curve, you must ensure the following:
< deg - the degree of the curve
< form - kOpen, kClosed or kPeriodic
< knotVector - the sequence of knot values. Must be of length numControlPts + deg + 1.
< numControlPts - the number of points in controlPoint
< controlPoint - the array of control points. Must have size of numControlPts * 4.
sSuccess - data created
sInsufficientMemory - ran out of memory
sInvalidArgument - there are many ways we can fail with this return code
For i = 0 to 2*deg-1 (n = numberSpans)
T[i+1] - T[i] = T[i+n+1] - T[i+n]
sFailure - data could not be created
Note: The number of knots = number of control points + degree + 1. The size of the knot vector is not passed into this method so if you don’t specify the array correctly, the method can read past the end of the knot vector.
statusCode AlCurve::createLine( const double start[3], const double end[3] )
Creates a straight line using attributes. This method is simpler than the previous create method, requiring you only to specify the beginning and end of the curve. To modify the curve you should retrieve its attributes with the firstAttribute() method and use AlAttribute methods to modify it. Modifying the CVs directly will cause the attributes to be deleted.
statusCode AlCurve::createArc( const double start[3], const double end[3], const double other[3], boolean circle )
Creates a circular arc using attributes. This method is simpler than the previous create method, requiring you only to specify three points on the curve and whether the curve should be closed to form a circle. To modify the curve you should retrieve its attributes with the firstAttribute() method and use AlAttribute methods to modify it. Modifying the CVs directly will cause the attributes to be deleted.
statusCode AlCurve::createArc( double *C, double *N, double *P, double r, double a0, double a1, int dim, boolean make_cubic )
C center
N normal to plane of arc (if 3D)
P point with zero angle
r radius
a0, a1 initial and final angles (in radians)
dim dimension 2 or 3
make_cubic if true, raise degree to 3
Note:
If dim = 2, N is ignored.
Point P with zero angle must not be at C.
Returns NULL if arc has no length
3D:
a0 < a1 and a1-a0 <= 2*PI.
Returns a full circle if a1-a0 > 2*PI.
To build a arc in the other direction, reverse N.
2D:
|a1-a0| <= 2*PI.
If a0 < a1 arc is counter clockwise else arc is clockwise.
Returns a full circle if |a1-a0| > 2*PI.
statusCode AlCurve::createConic( double c_a, double c_b, double c_c, double c_d, double c_e, double c_f, const double start[3], const double end[3] )
Creates a conic arc using attributes. This method is simpler than the previous create method, requiring users only to specify the coefficients of the conic and the beginning and end of the curve. The start and end points must lie on the conic.
The conic is described by the equation:
A * X^2 + B * X * Y + C * Y^2 + D * X + E * Y + F = 0
The conic will be created in the XY plane.
It is not possible to modify a conic curve through its attributes.
statusCode AlCurve::createParabola( const double vertex[3], const double focus[3], const double start[3], const double end[3] )
Creates a parabolic arc using attributes. This method is simpler than the previous create method, requiring users only to specify the vertex and focus of the parabola and the beginning and end of the curve. The start and end points must lie on the parabola. The parabola will be created in the XY plane. It is not possible to modify a parabolic curve through its attributes.
statusCode AlCurve::createEllipse( const double center[3], const double major_axis[3], const double minor_axis[3], const double start[3], const double end[3] )
Creates an elliptical arc using attributes. This method is simpler than the previous create method, requiring users only to specify the center, major axis, and minor axis of the ellipse and the beginning and end of the curve. The start and end points must lie on the ellipse and be specified in a counterclockwise order to indicate the arc. The axes must be perpendicular to each other. When creating an elliptical arc, the axes MUST be specified in the XY plane. It is not possible to modify an elliptical curve through its attributes. It is not possible to create a closed curve with this method, hence it will always fail for AlFaces.
statusCode AlCurve::createHyperbola( const double center[3], const double major_axis[3], const double minor_axis[3], const double start[3], const double end[3] )
Creates a hyperbolic arc using attributes. This method is simpler than the previous create method, requiring users only to specify the center, major axis, and minor axis of the hyperbola and the beginning and end of the curve. The start and end points must lie on the ellipse and be specified in a counterclockwise order to indicate the arc. The axes must be perpendicular to each other. The hyperbola will be created in the XY plane. It is not possible to modify a hyperbolic curve through its attributes.
statusCode AlCurve::setRealKnotVector( const double knotVector[] )
statusCode AlCurve::length(double& len , boolean worldCoordinates, double tolerance )
statusCode AlCurve::periodicToNonPeriodic( ) const
If a curve is periodic, converts it to a non-periodic curve (closed curve) by giving it multiple end knots.
Note: This method modifies the curve. It will not succeed for an AlCurve that exists in the AlUniverse; that is, it must not have a parent AlCurveNode.
statusCode AlCurve::normal( double normal[3] ) const
Tests if bspline is planar and returns normal. This method finds the first three points that are not co-linear, constructs a normal and tests if the bspline lies in the plane. If the bspline is planar and closed the normal is returned with a clockwise orientation looking down on the plane, and the normal pointing towards you. If the bspline is a line or all the points are co-linear, a unique normal can not be defined.
statusCode AlCurve::applyIteratorToCVs( AlIterator* iter, int &rc )
Applies the given iterator to all the CVs in this class. See the documentation for AlIterator.
statusCode AlCurve::extendCurve(double knot , double newPos[4])
statusCode AlCurve::trimCurve( double param0, double param1 )
Trims the curve at the specified parameters. param0 and param1 are the min and max points. This routine fails if param0 and param1 are the same or if param0 is greater than param1.