0

Drawing a spline in the viewport

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).

Frank Willeke

worked with computers since more than 20 years | got hooked on computer graphics back on the AMIGA | started programming at the age of 13 | relesed some successful plugins for cinema 4d | started working for maxon computer gmbh in 2009 | now contributing to cinema 4d as a senior developer

making electronic music since 1993 | playing the electric guitar since 1995 age of 14 | first live gigs in 1997 | playing the bass guitar 2005 | playing keyboards and synths since 2012

experimenting with photography since 2003

Leave a Reply

Your email address will not be published. Required fields are marked *