Drawing a spline in the viewport

by .

In this article we show a handy function for drawing a spline in the viewport.

How it works

When generating a spline internally in your expression tag or generator object, and you want to display it in the viewport (without e.g. returning it in BaseObject::GetVirtualObjects()), you might try to use BaseDraw::DrawObject(). Surprisingly, if you pass the SplineObject to this function, nothing will be drawn. That’s because DrawObject() does not work with splines, instead a LineObject must be used. Here is how it works.

the function

Bool DrawSplineObject(SplineObject* spline, const Vector& col, BaseDraw* bd, BaseDrawHelp* bh, const Matrix& drawmatrix, DRAWOBJECT drawobject = DRAWOBJECT_0, DRAWPASS drawpass = DRAWPASS_OBJECT)
{
  if (!spline || spline->GetType() != Ospline || !bd || !bh) return false;

  // Get LineObject from spline
  LineObject *line = spline->GetLineObject(NULL, (Float) 2.0, NULL);
  if (!line) return false;

  // Force object color
  ObjectColorProperties cprop;
  cprop.usecolor = ID_BASEOBJECT_USECOLOR_ALWAYS;
  cprop.color = col;
  line->SetColorProperties(&cprop);

  // Set new draw matrix, store current
  Matrix tmpmatrix = bh->GetMg();
  bh->SetMg(drawmatrix);

  // Draw the LineObject
  bd->DrawObject(bh, line, drawobject, drawpass);

  // Set original draw matrix
  bh->SetMg(tmpmatrix);

  // Don't forget to free the LineObject
  LineObject::Free(line);

  return true;
}

Usage

As an example, here’s how to use DrawSplineObject() in the Draw() function of an ObjectData, using the Objects drawpass:

DRAWRESULT ExampleObject::Draw(BaseObject* op, DRAWPASS drawpass, BaseDraw* bd, BaseDrawHelp* bh)
{
  if (drawpass != DRAWPASS_OBJECT)
    return DRAWRESULT_SKIP;

  BaseContainer bc;
  BaseObject* spline = GenerateSplinePrimitive(node->GetDocument(), Osplinestar, bc, 1.0, NULL);
  if (!spline)
    return DRAWRESULT_ERROR;

  if (!DrawSplineObject(ToSpline(spline), Vector(RCO 1.0), bd, bh))
    return DRAWRESULT_ERROR;

  return DRAWRESULT_OK;
}

Comments on the code

Matrix tmpmatrix

We have to store the original draw matrix and set it back after we’re done drawing. Otherwise, we would risk screwing up everything that will be drawn after our spline.

GenerateSplinePrimitive()

This function is used for demonstration purposes. Of course, you can use any spline, as long as it’s a real SplineObject. Just passing the pointer to a primitive object won’t do the trick (call GetRealSpline() on primitives/generators).

Advertisements