SplineHelp Class Reference

#include <lib_splinehelp.h>

Detailed Description

Class for helping to deal with splines. Defines routines to get positions along splines from real-world units, non flipping/non gimbal locked matrices and vectors from splines.
Must be initialized before use. All values returned are in global space. The slow part is the InitSpline() routine; other access is pretty fast.

Note
Has to be created with Alloc() and destroyed with Free(). Use AutoAlloc to automate the allocation and destruction based on scope.

Private Member Functions

 SplineHelp ()
 
 ~SplineHelp ()
 

Alloc/Free

static SplineHelpAlloc ()
 
static void Free (SplineHelp *&node)
 

Init/Free Spline

Bool InitSplineEx (const BaseObject *op, Vector upvector=Vector(0.0), const BaseObject *rail=nullptr, Bool target_rail=true, Bool use_deformed_points=false, Bool force_update=false, Bool use_global_space=true)
 
void FreeSpline ()
 
Bool InitSpline (const BaseObject *op, SPLINEHELPFLAGS flags=SPLINEHELPFLAGS::GLOBALSPACE|SPLINEHELPFLAGS::CONTINUECURVE)
 
Bool InitSpline (const BaseObject *op, Vector upvector, SPLINEHELPFLAGS flags=SPLINEHELPFLAGS::GLOBALSPACE|SPLINEHELPFLAGS::CONTINUECURVE)
 
Bool InitSpline (const BaseObject *op, const BaseObject *rail, SPLINEHELPFLAGS flags=SPLINEHELPFLAGS::TARGETRAIL|SPLINEHELPFLAGS::GLOBALSPACE|SPLINEHELPFLAGS::CONTINUECURVE)
 

Count

Int32 GetSegmentCount () const
 
Int32 GetVertexCount (Int32 segment=NOTOK) const
 
Int32 GetPointCount () const
 

Operations

Float GetSplineLength () const
 
Float GetSegmentLength (Int32 segment) const
 
Matrix GetVertexMatrix (Int32 index) const
 
Float GetPointValue (Float offset, Int32 segment) const
 
Int32 GetPointIndex (Float offset, Int32 segment) const
 
Vector GetPosition (Float offset, Int32 segment=0, Bool smooth=true, Bool realoffset=false) const
 
Vector GetTangent (Float offset, Int32 segment=0, Bool smooth=true, Bool realoffset=false) const
 
Vector GetNormal (Float offset, Int32 segment=0, Bool smooth=true, Bool realoffset=false) const
 
Vector GetCrossNormal (Float offset, Int32 segment=0, Bool smooth=true, Bool realoffset=false) const
 
Float GetOffsetFromUnit (Float unitoffset, Int32 segment=0) const
 
Float GetOffsetFromReal (Float offset, Int32 segment=0) const
 
Matrix GetMatrix (Float offset, Int32 segment=0, Bool smooth=true, Bool realoffset=false) const
 
void GetLinePointSegment (Int32 index, Float *offset, Int32 *ind, Int32 *segment) const
 
void GetSplinePointSegment (Int32 index, Float *offset, Int32 *ind, Int32 *segment) const
 
void GlobalToLocal (Float offset, Float *off, Int32 *segment, Bool realoffset=false) const
 
Int32 SplineToLineIndex (Int32 index) const
 
Int32 LineToSplineIndex (Int32 index) const
 
Float GetSize (Float offset, Int32 segment=0, Bool smooth=true, Bool realoffset=false) const
 
Float GetVertexSize (Int32 index) const
 
Matrix GetVertexMatrix (Int32 segment, Int32 index) const
 

Miscellaneous

Bool CopyTo (SplineHelp *dest) const
 
Bool Exists () const
 
Bool IsClosed (Int32 segment=0) const
 
SPLINETYPE GetType () const
 
void SetOwner (BaseObject *op)
 
UInt32 GetDirty () const
 
Matrix GetPointMatrix (Int32 splineVertexIndex) const
 
LineObjectGetLineObject ()
 
SplineObjectGetSplineObjectCache ()
 

Constructor & Destructor Documentation

◆ SplineHelp()

SplineHelp ( )
private

◆ ~SplineHelp()

~SplineHelp ( )
private

Member Function Documentation

◆ Alloc()

static SplineHelp* Alloc ( )
static

Allocates a spline help. Destroy the allocated spline help with Free(). Use AutoAlloc to automate the allocation and destruction based on scope.

Returns
The allocated spline help, or nullptr if the allocation failed.

◆ Free()

static void Free ( SplineHelp *&  node)
static

Destructs spline help instances allocated with Alloc(). Use AutoAlloc to automate the allocation and destruction based on scope.

Parameters
[in]nodeThe spline help to destruct. If the pointer is nullptr nothing happens. The pointer is assigned nullptr afterwards.

◆ InitSplineEx()

Bool InitSplineEx ( const BaseObject op,
Vector  upvector = Vector(0.0),
const BaseObject rail = nullptr,
Bool  target_rail = true,
Bool  use_deformed_points = false,
Bool  force_update = false,
Bool  use_global_space = true 
)

Initializes the spline data. Deprecated since R17.

Warning
Must be called before any other access.
Parameters
[in]opThe spline object to use. The caller owns the pointed spline object.
[in]upvectorAn optional up-vector for the spline normals generation. This is only used at the start of splines/segments; this way it avoids gimbal lock if at all possible.
[in]railAn optional rail spline object for the spline normals generation. The caller owns the pointed spline object.
[in]target_railIf true the optional rail spline is not only used as up-vector but also as target.
This is used for instance in MoGraph's Rail options (Cloner, Spline effector, Spline Wrap etc.).
[in]use_deformed_pointsIf true uses the deformed point positions of the spline.
[in]force_updateIf true forces a full initialization.
The spline help class internally caches its own content. Thus it will be much faster if the same splines are used for initialization.
.
[in]use_global_spaceIf false the resulting matrices are in local space rather than in the spline objects' global space.
Returns
true if successful, otherwise false.

◆ FreeSpline()

void FreeSpline ( )

Frees the spline data. Recalling InitSpline() or calling Free() will automatically call this.

◆ GetSegmentCount()

Int32 GetSegmentCount ( ) const

Gets the number of segments in the spline.

Note
Unlike the way Cinema 4D handles segments where a segment count of 0 means there is either no segments or 1 segment, this returns 1 segment if there is 1 and 0 if there are 0.
Returns
The segment count.

◆ GetVertexCount()

Int32 GetVertexCount ( Int32  segment = NOTOK) const

Gets the number of vertices for a spline segment.

Parameters
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
Returns
The number of vertices.

◆ GetPointCount()

Int32 GetPointCount ( ) const

Retrieves the number of spline points.

Returns
The number of spline points.

◆ GetSplineLength()

Float GetSplineLength ( ) const

Retrieves the spline's real-world unit length including all segments.

Returns
The spline length.

◆ GetSegmentLength()

Float GetSegmentLength ( Int32  segment) const

Retrieves a specific segment's real-world unit length.

Parameters
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
Returns
The length of the specified segment.

◆ GetVertexMatrix() [1/2]

Matrix GetVertexMatrix ( Int32  index) const

Retrieves a full matrix for a specific point of the line.

Note
This is not the spline vertex, but instead the line object's vertex. (Calculated with LOD = 1.0.)
Parameters
[in]indexThe index of the line object vertex: 0 <= index < op->GetPointCount()
Returns
The coordinate system matrix at index.

◆ GetPointValue()

Float GetPointValue ( Float  offset,
Int32  segment 
) const

Converts a natural offset value to a real percentage offset value.

Note
The percentage uses the real-world units for its offset, so regardless of how the spline's points and interpolation is set, a gap of 2% on a 100m long spline will always be 2m whereas normally in spline natural space, a gap of 2% can vary a great deal depending on the spline's interpolation etc.
Parameters
[in]offsetThe offset given in spline space.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
Returns
The real-world percentage offset.

◆ GetPointIndex()

Int32 GetPointIndex ( Float  offset,
Int32  segment 
) const

Retrieves the nearest line point index to the given real offset.

Parameters
[in]offsetThe spline space offset.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
Returns
The nearest line object point index, rounded down.

◆ GetPosition()

Vector GetPosition ( Float  offset,
Int32  segment = 0,
Bool  smooth = true,
Bool  realoffset = false 
) const

Gets a position along the spline.

Parameters
[in]offsetThe spline offset.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
[in]smoothIf true the position is smoothed.
[in]realoffsetIf true uses uniform spline distribution.
Returns
The position given by offset in global space.

◆ GetTangent()

Vector GetTangent ( Float  offset,
Int32  segment = 0,
Bool  smooth = true,
Bool  realoffset = false 
) const

Gets a tangent vector for any point along the spline.

Parameters
[in]offsetThe spline offset.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
[in]smoothIf true the position is smoothed.
[in]realoffsetIf true uses uniform spline distribution.
Returns
The tangent given by offset in global space.

◆ GetNormal()

Vector GetNormal ( Float  offset,
Int32  segment = 0,
Bool  smooth = true,
Bool  realoffset = false 
) const

Gets a normal vector for any point along the spline.

Parameters
[in]offsetThe spline offset.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
[in]smoothIf true the position is smoothed.
[in]realoffsetIf true uses uniform spline distribution.
Returns
The normal given by offset in global space.

◆ GetCrossNormal()

Vector GetCrossNormal ( Float  offset,
Int32  segment = 0,
Bool  smooth = true,
Bool  realoffset = false 
) const

Gets a cross normal vector (i.e. perpendicular to the normal and the tangent) for any point along the spline.

Parameters
[in]offsetThe spline offset.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
[in]smoothIf true the position is smoothed.
[in]realoffsetIf true uses uniform spline distribution.
Returns
The cross normal given by offset in global space.

◆ GetOffsetFromUnit()

Float GetOffsetFromUnit ( Float  unitoffset,
Int32  segment = 0 
) const

Converts a percentage offset into a natural offset. Percentage offsets ignore spline interpolation etc and are always x% along the spline.

Parameters
[in]unitoffsetA percentage offset: 0 <= unitoffset <= 1.0.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
Returns
The natural offset.

◆ GetOffsetFromReal()

Float GetOffsetFromReal ( Float  offset,
Int32  segment = 0 
) const

Retrieves an offset from a real-world unit.
For example, if a spline is 50 units long, 25 would be 50% of the length, i.e. 0.5.

Parameters
[in]offsetThe real unit offset to convert.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
Returns
The offset in spline space.

◆ GetMatrix()

Matrix GetMatrix ( Float  offset,
Int32  segment = 0,
Bool  smooth = true,
Bool  realoffset = false 
) const

Retrieves a full matrix for any point along the spline, constructed as a local coordinate system at that point.
Optionally uses real-world percentage rather than spline natural space for the offset.

Parameters
[in]offsetThe spline offset.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
[in]smoothIf true the position is smoothed.
[in]realoffsetIf true uses uniform spline distribution.
Returns
The coordinate system matrix at offset.

◆ GetLinePointSegment()

void GetLinePointSegment ( Int32  index,
Float offset,
Int32 ind,
Int32 segment 
) const

Converts a global point index in a line (i.e. from 0 to the number of points in the line object) to a local set of values within a single segment returning the segment the point is in, the offset along the segment and the point index within the segment (0 to the segment point count).

Parameters
[in]indexThe line object vertex index: 0 <= index < op->GetPointCount() (Using LOD = 1.0 for the line object.)
[out]offsetAssigned the offset along the segment.
[out]indAssigned the point index within the segment.
[out]segmentAssigned the segment index.

◆ GetSplinePointSegment()

void GetSplinePointSegment ( Int32  index,
Float offset,
Int32 ind,
Int32 segment 
) const

Converts a global point index in (i.e. from 0 to the number of points in the spline) to a local set of values within a single segment returning the segment the point is in, the offset along the segment and the point index within the segment (0 0 to the segment point count).

Note
This is the same as GetLinePointSegment(), but uses the spline's set of indexes.
Parameters
[in]indexThe global spline point index: 0 <= index < op->GetPointCount()
[out]offsetAssigned the offset along the segment.
[out]indAssigned the point index within the segment.
[out]segmentAssigned the segment index.

◆ GlobalToLocal()

void GlobalToLocal ( Float  offset,
Float off,
Int32 segment,
Bool  realoffset = false 
) const

Turns a percentage along the whole spline to local segment info, offset along segment, the segment the point exists in.
Optionally uses a real % offset rather than the spline natural offset.

Parameters
[in]offsetThe percentage along the whole spline.
[out]offAssigned the offset along the segment.
[out]segmentAssigned the segment index.
[in]realoffsetIf true a real-world percentage is used, rather than the natural spline space.

◆ SplineToLineIndex()

Int32 SplineToLineIndex ( Int32  index) const

Converts a spline vertex index to its corresponding line object vertex index.

Parameters
[in]indexThe spline vertex index: 0 <= index < op->GetPointCount()
Returns
The line object vertex index: 0 <= index < op->GetPointCount()

◆ LineToSplineIndex()

Int32 LineToSplineIndex ( Int32  index) const

Converts a line object vertex index to its corresponding spline vertex index.

Parameters
[in]indexThe line object vertex index: 0 <= index < op->GetPointCount()
Returns
The spline vertex index: 0 <= index < op->GetPointCount()

◆ GetSize()

Float GetSize ( Float  offset,
Int32  segment = 0,
Bool  smooth = true,
Bool  realoffset = false 
) const

Gets the distance to an existing rail spline for any point along the spline.

Parameters
[in]offsetThe spline offset.
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
[in]smoothIf true the position is smoothed.
[in]realoffsetIf true uses uniform spline distribution.
Returns
The distance given by offset.

◆ GetVertexSize()

Float GetVertexSize ( Int32  index) const

Gets the distance to an existing rail spline for a spline vertex specified by index.

Parameters
[in]indexThe vertex index: 0 <= index < GetVertexCount()
Returns
The distance given by index.

◆ GetVertexMatrix() [2/2]

Matrix GetVertexMatrix ( Int32  segment,
Int32  index 
) const

Gets the matrix for a spline vertex specified by segment and index.

Parameters
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
[in]indexThe vertex index: 0 <= index < GetVertexCount()
Returns
The matrix given by segment and index.

◆ CopyTo()

Bool CopyTo ( SplineHelp dest) const

Copies the spline helper data to another SplineHelp.

Parameters
[in,out]destThe destination spline help. The caller owns the pointed spline help.
Returns
true if successful, otherwise false.

◆ Exists()

Bool Exists ( ) const

Checks if the spline helper contains data and has been initialized.

Returns
true if the spline helper is ready to use, otherwise false.

◆ IsClosed()

Bool IsClosed ( Int32  segment = 0) const

Checks if a spline segment is closed.

Parameters
[in]segmentThe segment index: 0 <= segment < GetSegmentCount()
Returns
true if the spline segment is closed, otherwise false.

◆ GetType()

SPLINETYPE GetType ( ) const

Retrieves the spline interpolation type.

Returns
The spline interpolation type: SPLINETYPE

◆ SetOwner()

void SetOwner ( BaseObject op)

Prevents recursion lock crashes when SplineHelp needs to create the cache of the passed spline.
This is the case if for instance the developer has no control over the placement of a spline object in relation to its node.
For instance prevents infinite recursion in an object generator linking to itself using link fields.
Example:

class MyBaseObject : public ObjectData
{
INSTANCEOF(MyBaseObject, ObjectData)
public:
virtual Bool Init(GeListNode* node, Bool isCloneInit)
{
if (!shelp)
return false;
shelp->SetOwnerstatic_cast<BaseObject*>(node); // Only needs to be set once so NodeData::Init is a good place
return true;
}
...
// In some other function
if (shelp->InitSpline(spline)) // etc.
...
};
#define INSTANCEOF(X, Y)
Definition: c4d_baselist.h:38
Definition: ge_autoptr.h:37
Definition: c4d_baseobject.h:248
Represents a C4DAtom that resides in a 4D list.
Definition: c4d_baselist.h:1844
Definition: c4d_objectdata.h:166
maxon::Bool Bool
Definition: ge_sys_math.h:55
struct _node node
Definition: node.h:10

It is also possible to call

shelp->SetOwner(thisobject);
shelp->InitSpline(spline);

ObjectData::GetVirtualObjects() rather than in ObjectData::Init(). SetOwner() is not very costly to call.

Warning
Must be called before InitSpline().
Parameters
[in]opThe object owning the current node data.
If called from within a tag plugin pass the tag's parent object:
shelp->SetOwner(tag->GetObject())
If called from within an object plugin use:
shelp->SetOwner((BaseObject*)node->Get())

◆ GetDirty()

UInt32 GetDirty ( ) const

Gets the dirty value for the SplineHelp which indicates how often the help has been updated with new values. i.e. how often the source spline has changed, and or the spline has been cleared.

Since
R17.032
Returns
The dirty checksum.

◆ GetPointMatrix()

Matrix GetPointMatrix ( Int32  splineVertexIndex) const

Gets the matrix for a spline vertex.

Since
R17.032
Parameters
[in]splineVertexIndexThe zero-based index of the spline vertex.
Returns
The resulting Matrix for that point along the spline.

◆ GetLineObject()

LineObject* GetLineObject ( )

Gets a LineObject from SplineHelp functions.

Warning
Call InitSpline() with SPLINEHELPFLAGS::RETAINLINEOBJECT for this method to return a line object.
Since
R17.032
Returns
The line object. nullptr if it fails or if the SplineHelp was not initialized with SPLINEHELPFLAGS::RETAINLINEOBJECT.

◆ GetSplineObjectCache()

SplineObject* GetSplineObjectCache ( )

Get the cached SplineObject. The SplineHelp owns the pointed SplineObject.

Note
Deformations are already computed on this SplineObject.
Warning
Call InitSpline() before.
Returns
The cache object. nullptr if it fails or if the SplineHelp was not initialized.

◆ InitSpline() [1/3]

Initializes the SplineHelp with the passed spline op, must be called before any other functions can be utilized.

Warning
Must be called before any other access.
Since
R17.032
Parameters
[in]opThe spline object to initialize from. The caller owns the pointed spline object.
[in]flagsThe optional flags used to control how the SplineHelp is setup: SPLINEHELPFLAGS
Returns
true if the SplineHelp was successfully initialized, otherwise false.

◆ InitSpline() [2/3]

Initializes the SplineHelp with the passed spline op, must be called before any other functions can be utilized.

Warning
Must be called before any other access.
Since
R17.032
Parameters
[in]opThe spline object to initialize from. The caller owns the pointed spline object.
[in]upvectorThe initial up-vector for the spline if no rail spline is passed.
[in]flagsThe optional flags used to control how the SplineHelp is setup: SPLINEHELPFLAGS
Returns
true if the SplineHelp was successfully initialized, otherwise false.

◆ InitSpline() [3/3]

Initializes the SplineHelp with the passed spline op, must be called before any other functions can be utilized.

Warning
Must be called before any other access.
Since
R17.032
Parameters
[in]opThe SplineObject to initialize from. The caller owns the pointed spline object.
[in]railThe rail spline. The caller owns the pointed spline object.
[in]flagsThe optional flags used to control how the SplineHelp is setup: SPLINEHELPFLAGS
Returns
true if the SplineHelp was successfully initialized, otherwise false.