Freehand 3d drawing (after Rhonda Forever)

Field arrives with a 3d drawing system ready to code for — the documentation starts here: BasicDrawing — and continues through DrawingFLines, DrawingFLinesProperties, DrawingFLinesEditing, ThreeDPLines. One of the cool things about Field's drawing system is that you can draw by editing code or you can edit the resulting splines with the mouse.

But to actually draw a line in the first place — to actually create material to edit — you once needed to write code. Well, no longer.

Inspired, poked and basically blindsided by the Rhonda Forever project, we've rushed to polish Field's freehand drawing tool — at least the point where it can make the video on the right here. (As usual, if you go fullscreen and turn scaling off you can probably read the code in the text editor).

Even at this early state the two projects make a really interesting comparison (and you really ought to go download and track the Rhonda betas) — Rhonda does one thing, a simple thing, very well; Field aims to be all things to all, code-writing, people. So, while it seems that many of the features that their user community are clamoring for are already there in Field — line styles, plugins to other tools, geometry manipulation — you are going to have to be willing to write a few lines of code yourself.

__Finally, to actually use this feature you'll need the most recent build of Field, more recent than beta 9 (since beta 9 doesn't have this functionality enabled)).

To download the code that's talked about here, see this tutorial.

How to draw in 3d in Field

As usual you need two things to get started — a box to write code in and a little bit of code.

The box you need you get from the right click menu — you are looking for a 3d spline drawer. The code you need to get started looks like this:

from field.core.plugins.drawing.tweak import Freehand3dUtils

utils = Freehand3dUtils(_self)

_self.lines.clear()

if (_self.rawSplineData):
    for r in _self.rawSplineData:
        ll = FLine().append(utils.projectAtZeroPoint(r))
        ll.color=Color4(0,0,0,0.7)
        ll.derived=1 #comment this out to make lines editable
        _self.lines.add(ll)
     
_self.tweaks()

And to see something on the screen, press and hold '3' to use the 3d drawing tool. Now with the left mouse button you can draw. command-left-mouse rotates the camera (command-middle pans and command-right scales). You can also use 'wasd' on the keyboard to control the camera as well; right clicking gets you a menu where you can select 'undo' and 'clear everything'.

The central conceit of Field's 3d drawing tool (and Rhonda Forever) is that you are simply drawing on a plane perpendicular to the camera — when you enter "drawing mode" (by holding space) the parts of your drawing that are "behind" this plane are grayed out and the places where your previous markings intersect this plane are given red dots. Thus, if you draw on the red dots your drawing meets perfectly with your previous lines. Elsewhere you'll be drawing above or below your previous material. Thus the whole interaction becomes about moving the camera and drawing.

Under the hood

Ok. So what is that code doing and how? The freehand 'tool' — the thing you get when you press and hold space — does all of the drawing: the mouse down, mouse drag and mouse up event handling. Once a gesture is complete it does two things:

  • it takes the drawing information from the gesture and adds it to a property _self.rawSplineData. This property becomes a list of all of the things that you have drawn. Like everything else in Field you can explore this data-structure using CompletionAndInspection.

  • Next the freehand tool executes all of the code in the box. In our case that code is responsible for taking the 2d drawing information from _self.rawSplineData.

So, let's look at the code in the box. Some of it will be familiar from the drawing documentation_self.lines.clear(), _self.lines.add(...), and _self.tweaks() are the lines of code you need to: clear all of the lines that are being drawn in this box, add a line to this box, and enable the box to support mouse based editing.

The remaining line of code actually does the projection out onto the camera: ll = PLine(utils.projectAtZeroPoint(r)).

And that's it. Should we decide we want the lines to be red we add:

ll(color=Color4(1,0,0,1)) #this is opaque red

Should we decide that we want the lines to draw some kind of spinning-motion-trail-like-thing we'd add:

for n in range(0, 10):
    ll = ll.copy()
    ll(color=Color4(1,0,0,0.3/(n+1))) #fading out red
    ll += rotation(0.2) #rotate a little around z
    _self.lines.add(ll) #and draw this as well

And if we decide that we want to add a copy of the line, but mirrored around the y axis:

ll = ll.copy()
ll.visitPositions(lambda x,y : Vector2(-x,y)) # transform x to -x
_self.lines.add(ll)

And so on — once you've called utils.projectAtZeroPoint( ... ) you've got a FLine, all of the FLine documentation applies.

Status & Bugs

What's fun about this 'feature' is that it lets us very quickly shake out the remaining holes in our 3d PLine support — if you find that operations on lines that have depth have unexpected results it's probably because the operation is ignoring the z coordinate. Report the operations that you find lacking and we'll upgrade them. If this really does get people excited then we're happy to prioritize a refresh of the whole mouse-based editing UI and some better docs.

Finally, to actually use this feature you'll need the most recent build of Field, more recent than beta 9 (since beta 9 doesn't have this functionality enabled). You can either build Field from source or download a special binary release here. If you are looking for stability, wait a moment for beta 10.

A more philosophical note

We've always thought that we had a lot more to say about drawing in 3d (from the research being conducted for our ongoing artworks and our previous works) than this addition to Field, but we've never been able to get it into a state that's usable by people outside our group. Perhaps we are starting from the wrong end — the Rhonda Forever project has made us realize the demand for completely straightforward 3d sketching. We'd also like to believe that "straightforward 3d sketching" plus code should be more interesting and useful than just straightforward 3d sketching alone.

Why is this? Well, the gigantic "feature list" that the Rhonda dev team are accreting on their vibrant forums is testimony to one thing — that polished one-task tools are today are a hard position to defend (all the more so if they are closed source). There's a moral, open-sourcey, dimension to this question, but also a practical one: as soon as you have something good, people want to add their stuff to it. It early days yet, and Rhonda are continuing to release new versions — its going to be fascinating to see their next moves.

Field tries to go the other way. Ultimately there's no reason why my idea of how to set a line color and yours need be the same; no reason why my idea of how to mirror a piece of geometry and yours need be the same; no reason why my idea of a file format and yours need be the same. And while some things are hard to code and hard to design and hard to fit together there is certainly no reason why "users" should wait passively while "developers" develop the line-color-choosing "feature". Our thought: the interface of all possible features to suit all possible desires in this particular domain expands too rapidly, and as it does so it evaporates. What's left — the vapor — is a code-based interface.

We (that's OpenEnded Group) actually believe this; we're willing to say it out loud, and we're willing to write code and release it to back our hypothesis up. Releasing tools out into the world is one thing, but it's maybe even more important to discuss what and how tools should be.