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