Possible with built-in nodes, at least in a basic way?

I imagine:

1. Draw to the viewer with (for example) the mouse on the 2D plane like posted here
2. Rotate the scene with a draggable camera (and/or animate rotation of a perspective camera, like here)
3. Then (most importantly), draw to the current viewer 2D plane, rotate camera, keep drawing, rotate, etc.

(Pretty sure @GeorgeToledo pursued this concept with some super interesting 3D sculpting stuff in QC (and for other devs?) as well. I suppose this is related to some of the VR/AR tools coming down the road, too.)

cwright made an awesome qtz called draw in space that does this, in response to this post at kineme.net. This was achieved with the following javascript:

``````var result = new Object();

function matrixMult(matrix, point)
{
var temp = new Array();
temp[0] = matrix[0][0] * point[0] + matrix[0][1] * point[1] + matrix[0][2] * point[2];
temp[1] = matrix[1][0] * point[0] + matrix[1][1] * point[1] + matrix[1][2] * point[2];
temp[2] = matrix[2][0] * point[0] + matrix[2][1] * point[1] + matrix[2][2] * point[2];
point[0] = temp[0];
point[1] = temp[1];
point[2] = temp[2];
}

function transformPoint(point, xTheta, yTheta, zTheta)
{
sinX = Math.sin(xTheta);
cosX = Math.cos(xTheta);
sinY = Math.sin(yTheta);
cosY = Math.cos(yTheta);
sinZ = Math.sin(zTheta);
cosZ = Math.cos(zTheta);

// todo:  do the math, and get this right
//[[cosY*cosZ, cosX*-sinZ, sinY],
//[sinX*sinY*cosZ+cosX*sinZ, sinX*sinY*-sinZ+cosX*cosZ, -sinX*cosY],
//[cosX*-sinY*cosZ+sinX*sinZ, cosX*sinY*sinZ+sinX*cosZ, cosX*cosY]];
var matrix;

matrix =
[[cosZ,-sinZ,0],
[sinZ,cosZ,0],
[0,0,1]];
matrixMult(matrix, point);
matrix =
[[cosY,0,sinY],
[0,1,0],
[-sinY,0,cosY]];
matrixMult(matrix, point);
matrix =
[[1,0,0],
[0,cosX,-sinX],
[0,sinX,cosX]];
matrixMult(matrix, point);
}

function (__structure points) main (__number inputX, __number inputY, __boolean draw, __boolean reset, __number xTheta, __number yTheta, __number zTheta)
{
if(reset || result.points == undefined)
result.points = new Array;
if(draw)
{
var point = new Array;
point[0] = inputX;
point[1] = inputY;
point[2] = 0;
transformPoint(point, xTheta*Math.PI/180, yTheta*Math.PI/180, zTheta*Math.PI/180);
result.points.push(point);
}

return result;
}
``````

## Moderator note:

, converted from Question to Discussion

### Progress, still an unsolved

Progress, still an unsolved problem: the `Draggable Camera` stays active all the time, is there a way to disable it while drawing with the mouse?

In this comp I can draw to the 2D viewer plane, then I can drag the camera view, then I can draw again, but when I switch back to the camera again it jumps to the current transform value, because the camera is always active.

Instead of spacebar, could you use one of the modifier keys (Command, Option, Control, Shift) on `Make Draggable Camera'? That would simplify things.

### Yep, that helps. Thanks,

Yep, that helps. Thanks, Jaymie. Still issues, but I think they can be solved.

### Ok, here's the first success.

Ok, here's the first bit of success, working except for one issue: when rendering, any drawn line disappears the moment the mouse button is released. Closing/reopening the viewer might fix it, or closing/reopening the comp usually does get it to work. Also, it takes a good bit of time for the viewer to open after hitting render.

Left mouse button draws, command button allows rotating the camera, right button to clear.

### Link to DrawInSpace0 above is

Link to DrawInSpace0 above is updated.

Seems this comp should work fine, but the problem persists: when the viewer launches, it's 50/50 whether drawn lines will stay on the screen like they are supposed to. Show events looks good to me. I don't know what I can do to troubleshoot this. Is this a bug?

Besides this problem, which I realize now really threw me off when building it, I am super happy with this comp, so much cool Vuo potential!

### Looks like there's a race

Looks like there's a race between the `Left Mouse Button : Released` and `Left Button to Draw : Drag Ended` to reach the `Enqueue` node. The triggers fire at nearly the same time. When Drag Ended wins the race, the line is drawn as expected. When Released wins the race, the line gets cleared before it can be drawn.

### Hmm, it seems you're saying

Hmm, it seems you're saying all I'd need to do is replace Released with Drag Ended to clear the `Enqueue`, but that's not working....

### I was beginning to suspect as

I was beginning to suspect something like that. I'll see if I can figure out what to do. Thank you!

### Still fresh but looking good

Still fresh but looking good so far -- looks like using a `Spin Off Event` from Drag Ended gets the events to land in the right order. Great!

### One more fix, link updated to

One more fix to "DrawInSpace_fixed.vuo", updated. Thanks again, Jaymie!

### This is pretty cool. @jersmi!

This is pretty cool. jersmi! Thanks for sharing. Surprising how few patches, a testament to Vuo's compositional power.

### Thanks! I should post to the

Thanks! I should post to the composition gallery....

### New chapter -- I'd like to

Could anyone help translate these formulas into Vuo? https://mathworld.wolfram.com/ParallelCurves.html

This is the start of something to get Draw in Space working to draw more artistically shaped lines using triangle strips, "calligraphic" strokes etc. The attached comp stroke gets the current and next points and uses `Normalize Point` * difference to generate the stroke width. (Test comp uses `Make Random List` together with `Make Points along Spline` to generate arbitrary curve points (Set Seed is published to change up the test curve). To see the filled stroke you'll need bss's `Make Triangle Strip Object' node from the Node Gallery.)

Other terms: "curve offset", "parallel curve" on Wikipedia, "equidistant curve" on math overflow.com). This image from mathoverflow.com is like tools in Adobe Illustrator for stroke offset, with rounded cap (caps would be awesome, of course....):

Another CG term that makes sense is "skeletal strokes", a technical term from CG world that goes back decades (related to beziér curves, etc.), which also suggests shaping the geometry in combination with texturing (like vector graphics software -- brush strokes either from vector shapes or textures). Amounts to using an arbitrary curve as a skeleton around which one generates interesting offsets. Indicated by the quality/quantity of publications on these concepts, the good news is that the problem was solved long ago.

The current Draw in Space uses line strips with points to compensate for the gaps in the lines. Any way to have more expressive drawing needs to encompass the concepts above. So the plan has been to use Triangle Strips (and grateful to Bodysoulspirit for submitting that node).

(Another point of reference, an early interactive web art piece -- I still remember discovering Golan Levin's piece, Yellowtail, for the first time, with its moving calligraphic lines, still lovely. Now you can buy it as an iPhone app for \$0.99 USD).

### Another keyword term: spline

Another keyword term, on the 3D side: spline mesh, tools for extrusion, one an article here for "procedural racetracks": http://blog.meltinglogic.com/2013/12/how-to-generate-procedural-racetracks/

Edit: In order to generate a 2D parallel curve, looks like I'll first need to generate splines and control points mathematically, i.e., without the help of `Make Points along Spline`, then generate the other points for the parallel curve. Looking at these:

Ok, progress. Babe in the woods, like most things GL related, playing catch up with the math to do anything cool. I do think what I have here is becoming a nice next chapter for the "draw in space" composition -- customized meshes. Of course GL artists have been all over custom meshes for a while, a lot of cool stuff out there.

Questions about shading: I am using the bss triangle strip and triangle fan nodes from the node library for this. Super grateful for those, but they are not set up for texturing beyond unlit color. I am wondering a couple things: one, could I simply edit Bodysoulspirit's node in a text editor to add the appropriate stuff to support texture coordinates, then save it as a new node? If so, where could I find the code to insert (for a wannabe coder willing to try)?

And two, even if this is possible, is it going to be a total pain to try and map brush stroke textures to the triangle strip meshes, especially ones being drawn with the mouse, i.e., not pre-calculated to set and forget the texture mappings? Are there things I can do to help the cause?

Or maybe I just need to focus on manipulating the geometry for now....

Edit: one more q, are there any tools for inserting/forcing a shader (or lighting, anything) onto the mesh? Not having any luck, maybe I'm missing something.

Problems I need to solve at present:

• Sharp curves -- the folders at sharp corners are a known classic issue, I knew the math for this method would not solve it coming in, baby steps. Is there a 3D object tool in Vuo that can clean any of that up? (Wanted to try `Union 3D Object` but it is crashing the comp loader with the bss custom nodes).
• Round "end caps" using triangle fans work, but it shows how the first and last points on the line where they connect need another point to make the transition from line to cap more seamless.

Working so far:

End cap issue:

Sharp curve issue:

Another example:

### Also, looking to turn parts

Problem -- doesn't work to turn the pictured section for "rounded caps" into a subcomp, no output, why? (I want to turn parts of the comp into subcomps so I can try/continue it in the Draw in Space comp.)

A section I tried to turn into a subcomp:

The subcomp (simplified trying to get it to work):

### How do you have the

How do you have the subcomposition hooked up in its parent composition? If I connect cables to both input ports, it seems to work…

I don't know if it's the look you're going for, but a totally different approach would be to use `Dilate Image` or `Cartoon Image` to draw a thick rounded stroke. DilateDrawParallel.vuo CartoonDrawParallel.vuo

### Thank you, Jaymie! Pretty

Thank you, Jaymie! Pretty sure I did not fire an event to both ports -- the why's of events/ports can still confuse me, unfortunately.

I appreciate those comps using dilate and cartoon draw very much, cool to see those. That could spark a nice final approach, hmm. Of course there we're talking about creating/shading pixels whereas I've been trying to (first) wrangle the geometry to be able to (eventually) apply transformations/effects to a triangle strip mesh (2D/3D twist/turn/bulge, etc.) using the Draw in Space approach. (Also the approach using an image "brush" + feedback as well.) All good stuff!

### The parabox nodes added a

The parabox nodes added a little flexibility to what you could do with a 2D thing like that, because it was possible to write to frag depth in a fine grained way so that the lines could cull against forward rendered objects, like 3D models or whatever. And you could distort the underlying grid with vertex shader, do some normal mapping effects, etc.

### Good point, and I see how

Good point, and I see how expressing interest in 2D creates this line of thought. I guess I've been expecting at some point to modulate z-depth in some manner, gently or otherwise, at least with the Draw in Space model. Mentioning paradox nodes being able to do some culling operations, some things might fail with current tools, not sure yet.

2D here for me is in some ways just coming to grips with how to control mesh generation. A 2D offset curve has some specific problems, shape curves and what not, thought it worthy to sort out then see where to go next. The idea has been to capitalize on how Draw in Space draws to the 2D screen space, then on mouse up (or whatever), when the mesh is "released" to travel into 3D space there's a second opportunity to trigger a (one-shot?) "animation" for the mesh -- for example, draw a flat/2D thing then on mouse up it might warp and twist in 3D as it turns within the sphere space.

(sigh)

### Sigh? Another great example,

Sigh? Another great example, totally appreciate all the variations on the ribbon.... when I have time I'll try to start dropping some of these into Draw in Space, with its limitations.

### Well, “sigh” mainly because

Well, “sigh” mainly because of that little gap in the texture :-) …I think it may be unavoidable with the basic method.

(edit: oh no, I just realized that since my post was after yours it could be misconstrued as a sigh about your post. Far from it!!! Sorry for any mix up of intent caused by that.)

You can adjust the amount of mouse positions in the queue that are then use to create start and end points. It can get rid of that gap but it will create some other side effects.

Maybe there is a really obvious way to get rid of that gap that hasn’t crossed my mind yet, since I just got that basic thing going.

### I couldn’t figure out a way

I couldn’t figure out a way to control face culling of the layers. I noticed there was a way to convert it to an object in the parabox node set…worth considering having either/or be part of the functionality of the layer engine.

That’s the reason for two quad queues.

If a layer point order is backwards x or y, I would expect to see the image flip, not for there to be nothing. If seeing nothing is the default…maybe there is a way to enable rear face rendering that I just don’t see in the node list at the moment.

Another thing…I get turned around with certain objects not having a zero. So, that stuff can be worth double checking in my compositions.

### Disabling multisampling gets

Disabling multisampling gets rid of the gaps between quads, except once in a blue moon.

Now, the whole line weight on the vertical strokes is something I have some ideas about but haven't put much attention towards yet. I was never super concerned because it gives it a kind of calligraphy look that I usually find desirable.

### Ah, multisampling. Well, I

Ah, multisampling. Well, I guess if multisampling is desired, could use this fix I put together with X offset/overlap.

Also here -- not working -- is the method I have for 2D offset. Not sure what to do with this at present. This quad method really shows the problems. Maybe could try to have current+next quad share an edge? Yeah, I like the calligraphy look, too, it's the go to primary tool in the arsenal. Classic QC javascript mouse ribbon.