Creating a Spline

Below is a section of code from the Circle plug-in. This plug-in is derived from class SimpleSpline. This code demonstrates the key methods used in building a shape. The method SimpleSpline::BuildShape() is called to build the shape at the specified time and store the results in ashape.

BuildShape()

voidCircleObject::BuildShape(TimeValue t, BezierShape& ashape)
{
   // Start the validity interval at forever and whittle it down.
   ivalid = FOREVER;
   floatradius;
   pblock->GetValue(PB_RADIUS, t, radius, ivalid);
   LimitValue( radius, MIN_RADIUS, MAX_RADIUS );
   ashape.NewShape();

The first thing to notice is the call to NewShape(). This ensures the shape is flushed out and emptied.

   // Get parameters from SimpleSpline and place them in the BezierShape
   intsteps;
   BOOLoptimize,adaptive;
   ipblock->GetValue(IPB_STEPS, t, steps, ivalid);
   ipblock->GetValue(IPB_OPTIMIZE, t, optimize, ivalid);
   ipblock->GetValue(IPB_ADAPTIVE, t, adaptive, ivalid);
   ashape.steps = adaptive ? -1 : steps;
   ashape.optimize = optimize;
   MakeCircle(ashape,radius);

Then this method calls MakeCircle(). See the code for this method below.

   ashape.UpdateSels(); // Make sure it readies the selection set info

After MakeCircle() has returned, another important call is made. This is UpdateSels(). This should be called when you are done adding all the polygons to the shape. This method updates the selection set information maintained by the shape. It is vital to call this before you are done.

   ashape.InvalidateGeomCache();
}

Finally we clear any caches from the shape.

MakeCircle()

staticvoidMakeCircle(BezierShape& ashape, float radius)
{
   floatvector = CIRCLE_VECTOR_LENGTH * radius;
   Spline3D *spline = ashape.NewSpline();

First create a new spline. This is done by calling the NewSpline() method on the shape. The shape adds a polygon to itself and returns a pointer to it.

   for(int ix=0; ix<4; ++ix)
   {
     float angle = 6.2831853f * (float)ix / 4.0f;
     float sinfac = (float)sin(angle), cosfac = (float)cos(angle);
     Point3 p(cosfac * radius, sinfac * radius, 0.0f);
     Point3 rotvec = Point3(sinfac * vector, -cosfac * vector, 0.0f);
     spline->AddKnot(SplineKnot(
                KTYPE_BEZIER,
                LTYPE_CURVE,
                p,
                p + rotvec,
                p - rotvec ));
   }

Next points or knots are added to the spline by calling AddKnot(). This allows you to add different types of knots and line segments.

   spline->SetClosed();

After adding four knots, the SetClosed() method is called to make sure it's a closed circle.

   spline->ComputeBezPoints();
}

Next, the ComputeBezPoints() call is made. The spline has a cached set of bezier points inside it. This needs to be called if you change the points of the spline. This methods updates the information internal to the spline.

See Also