JacquesLucke / animation_nodes

Node based visual scripting system designed for motion graphics in Blender.
Other
2.29k stars 342 forks source link

make new curve data sockets and curve data nodes #132

Closed og76 closed 9 years ago

og76 commented 9 years ago

In respect to what you said on the forum, to create issue here for all this curve data type and sockets , I did.

Here's a variant on how this could look, imitating the mesh nodes more or less https://drive.google.com/file/d/0BzzAoBwXO8dsZ29QMm00X2VzY1U/view?usp=sharing these are only the input ones, I have to also "mirror" them to the set-data/output kind with two notes:

  1. there is an index input and single item output in the indigo nodes that is not to be there I used it instead of get element ..
  2. there is a draw handels/ show handels thing in the last one. that is about a trick that I used in a blend with that pseudo hooks, to see the handels but it's not needed here, and may confuse people as they are not to edit ..
JacquesLucke commented 9 years ago

that looks good so far. I mean reading the data is always quite a bit easier than writing... I'm not sure but maybe we need a custom way to store curve data as I did with the mesh data. The problem is that a curve has way more properties than a mesh.

Can you make a mockup for creating new curve data and how to set it onto an object? You don't have to write code, just how the nodes could look like.

Let's say a node wants to create a new spline. It can't because it always needs Blender Curve object. So we have to work around that. The last node should be a "Set Curve Data on Object" node, which removes all splines from the object and sets the newly generated splines... maybe

Of course we can also have a node that sets a location for a bezier point based on the spline and point index.. (maybe for mesh nodes as well)

I hope it is a bit clear what I want to say. I'm just saying some thoughts that come to my mind, it's not very organised...

og76 commented 9 years ago

I gave a thought to making and did not settle for 1 way yet. Frankly, I do not consider reading settled. The more I look, the more I change my mind. I'll look more...

Like this: Mesh is uniform. Here we have more than 1 spline, several types of points on each etc. I tried to look at 1 spline as the equivalent of the mesh data (most modifiers etc only consider the first spline ..), but that's wrong. It's more like loose parts. Or: For example each point has 2 to 6 parameters, 1-3 vec + 1 type (interpolation) + tilt and radius I'm biased if the tilt and radius should not go for a geometry node, as the curve is one line vs the generated mesh around is geometry (bevel, objects, even mesh that is using it to deform..) Or: Do I need to read handels for auto type? not for creating another mesh and if you set them a bit wrong they become free type. but I do need them read if to create aligned or free but starting from that. (btw, aligned is crazy to work with handels ..)

and so on

bonus

JacquesLucke commented 9 years ago

Hmm, yes I think you understood the problem...... This will take some time to design and implement...

og76 commented 9 years ago

I just looked into the branch curve sockets. (I find it harder to follow this branch vs guy so I don't know how these update) the spline sample node and spline evaluation node: -are using this "parameter" that follows an nonuniform (interpolated) division. In comparison to the uniform division that follow path constraint is using (from curve animation props "frames") -are not taking into account the u resolution in curve props, where the constraint/modifiers do I had this issue from the very beginning, on the forum

now, question is: -is this not updated yet or there was no tackling the issue? -is there a way to get a consistent uniform parameter? not sure if the new algorithm plays any role here -what is the point of sample spline? being interpolated is more of an alternative to U resolution prop. (I don't see a use in further creating spline nodes, as the U reso is a prop to be set in the object created..)

yes, I expected sample to go uniform, as for a point array I can use spline length and eval ..

https://drive.google.com/file/d/0BzzAoBwXO8dsX3VVYzN2bThIMW8/view?usp=sharing

JacquesLucke commented 9 years ago

getting samples with equal distances is quite a bit harder from the mathematical pov. But you're right this definitly a needed feature. I will search for a algorithm that can calculate that.

the sample spline node is not very useful on its own. It may become useful if other nodes uses the this data later. I developed it mainly for testing reasons. but I see no reason to remove it

JacquesLucke commented 9 years ago

hm looks like there is no mathematical way to calculate it. http://math.stackexchange.com/questions/15896/find-points-along-a-b%C3%A9zier-curve-that-are-equal-distance-from-one-another

og76 commented 9 years ago
  1. The ideal case (and consistent one) would be to use the blender calculation. The very way it's there in the curve property/path animation tab, as it is used by constraints and modifiers. (In the blend above play frames)

It is better than a very accurate math way, to have a consistent parameter allover the place.

Afaik by using data.use_path ,the curve is available as translation path, divided by that data.path_duration for use with data.eval_time. Can we evaluate that without the use o the respective slider or constraints? Excuse me if it's a silly question, I'm just thinking of using something that is there already.

  1. don't remove that node. I was commenting on the use while not being uniform and all
og76 commented 9 years ago

this one is making even / fixed distances on the curve tested and appears also dependent on the U resolution (like B modifiers do? ..) http://blenderartists.org/forum/showthread.php?361347-Add-On-Arrange-objects-along-a-curve

JacquesLucke commented 9 years ago

looks like he uses this function: http://www.blender.org/api/blender_python_api_2_74_5/mathutils.geometry.html#mathutils.geometry.interpolate_bezier

will test this now.... from the api it doesn't look suiteable unfortunally, but let me test it first [edit]ok will have to look deeper into his code.

JacquesLucke commented 9 years ago

https://github.com/JacquesLucke/animation_nodes/commit/635179266852b0731d5a6bfb1e4705efcd6a52e3

I've got something working. It doesn't fullfill all needs but it's a good start I think

og76 commented 9 years ago

just let me know if I can test somehow

+this one is quite something, though uses it's own curves for modeling and I gather it's not py. http://blenderartists.org/forum/showthread.php?366107-MiraTools But you might just get an idea for how auto handles are going. In mira tools, in edit mode, check the handles and have that curve guide... well speculating.

+btw, in loft, bezier interpolation with factor is great, but instead of linear alternative, would it be nice to have the usual interpolation socket. default to linear, but you know, may plug custom in there .. :wink:

og76 commented 9 years ago

fwiw, this is the way I test. https://drive.google.com/file/d/0BzzAoBwXO8dsWjZSWkhvcEIySm8/view?usp=sharing (expecting to have the empty001 closer to empty with constraint )

just dld and tried the above eval node + curve.py, but not sure how to compare with previous

JacquesLucke commented 9 years ago

loft with interpolation

Hm I just tested it with a custom interpolation but doesn't seem to make much sense here...

og76 commented 9 years ago

aha. I thought the interpolation, will also give this z smoothing. I was seeing the little custom curve as the bezier with controls... but I see it's more an interpolation of the linear factor. Doesn't make sense indeed.

JacquesLucke commented 9 years ago

should I leave it remove it again?

og76 commented 9 years ago

the initial way makes sense, bezier with factor + plain linear. I'd say remove it cause it's misleading.

JacquesLucke commented 9 years ago

okay, thanks for the feedback

JacquesLucke commented 9 years ago

Hm I'm thinking about removing the 'Curve' socket, because it is just a list of splines. If we leave both it can become very irritating. What do you think?

og76 commented 9 years ago

I think is a good idea, now that you have spline and spline list, that is exactly how it should work. Oh, and the dark indigo/purple color was too close to floats anyway :)

I was thinking that you are looking for a container for more complete data than that, like "mesh data". I think of that as how much I need some props, or how many of them, to further construct a bezier data, in the mirror, output node. So I have explored respective props per object level (and not per spline, though as object.data. ...) like bevel etc. Are those related, contained here? Needed?

So far, from my exploration, it seams they are not necessary, and we may consider it extra props, eventually grouped as geometry, animation path etc like in B. Or they can be exposed in the bezier object node as extra sockets, pretty much like the text output does.

The only props that matter are in the Active spline tab in the curve data, but they are at the spline level. -cyclic, resolution, tilt and radius +for nurbs there is more here like cyclic, endpoint order etc

So I say go for it, it makes sense.

ps. I consider these as eventually working for nurbs too, without the need for different sockets, or different nodes. Only at the point level that is different

See this blend https://drive.google.com/file/d/0BzzAoBwXO8dsVDN6ZWJoYy1HWlk/view?usp=sharing for it contains bezier and nurbs splines in the same obj (!), the only thing changin is the active spline tab.

JacquesLucke commented 9 years ago

Ok I'm going to delete the curve socket now. these other properties like bevel etc can be set with a node like the text output node.

Yes I'm already discussing this with guy. We definitly want to support other curve types, not only Bezier. You're right that there are many things they have in common. We're just not yet sure how to deal with the differences. One approach would be to have a base socket type that can contain different kinds of curves. And then some other socket types for the different curve types..... then there is also the question with lists. Should we have lists for all different curve types or just for the base type? It can become quite confusing to users when the curves are sometimes the same and sometimes differently..

JacquesLucke commented 9 years ago

I hope I forgot nothing in this last commit..

og76 commented 9 years ago

About how to support different types of splines:

On priciple, follow the technical blender way. Not the ui/ux stuff. For AN the direction is more in respect to data structures than blender ux stuff. As I see it. The example I gave above is exactly about this, that the objects called Bezier Curve or Path or Nurbs curve, are an artificial (or convenience) thing. The objects really are the same, down to the spline level. And Path is really just nurbs. Blender using only the first spline in the object for whatever is another example of an artificial ux thing.

In the end, blender does same operations with bezier or nurbs, in terms of modifier/constraints etc. Only the "spline evaluation" is probably different.

I'd say that:

  1. Administratively, nodes and sockets 1.1 There should be only 1 curve obj node, output list of splines, all splines of both kinds (maybe some other common props) You may at most have 2 checks to filter out only bezier / only nurbs, but this complicates things a lot. And really there is no chance people will use those combined types object as above example.

1.2 There should be only 1 spline socket / spline info node for all types! With maybe a type socket (string sock really) to tell you what it is, if it matters. And the math evaluation of it to change accordingly (if bezier, if nurbs) In the object with many spline types above, it's hard to say what index is the bezier or the nurbs, in the end I don't see an issue having a loft with bezier and nurbs in it, as only the formula to describe/approximate the spline is different.

Exactly like the active spline tab in props, that changes according to what spline type is selected in edit mode, I should not have 2 different nodes and search myself. I'd say it's less error prone too.

1.3 the output should go again for same curve points socket, even if the bez vs nurbs point have very different props. Ideally, the point info node would be the same, changing according to the input data type.

Well, I know you use sockets to tell what type that is and maybe is more efficient, but in this particular case, Id say it's one list of splines, any kind one spline info that output according to type one point node that changes according to type

  1. possible issues The only issue here is not when using this info for geometry or loft or whatever, but in reverse, for the output nodes, and even there, only at the point level. There could be a problem if someone tries do plug points of different types into creating a spline. So there, we could have a node like mesh compose [(vertex+poly i) vs (polygons)] with the choice nurbs or bezier, meaning the node will only consider the appropriate point type inputs. (Pretty much as today, the curve obj node only lists the bezier splines in the multi object above, thus my list today having only 2 elements.)

please add to issues list, as you may have a more in depth image of this

How do you see these inner conversions vs separate nodes? How is the ux efficiency vs technical efficiency here?

ps. I plead for simpler use, as today people have issue with vertex, vertices, vertex locationS, vertex location .. and that's not something you can change really. But here, it's not the same.

JacquesLucke commented 9 years ago

Thanks for this in-depth answer. I think I will most thinks as you said them. The good thing is that most of the time we have way less points in a curve than in a mesh, so the performance cannot be bad here in every case.

I will write here when I have further questions. What you said so far was really helpful. :)

og76 commented 9 years ago

glad to help. at least I give something back.

As for performance, the only thing I get to date is the less nodes I have in a tree, the better speed. Like, having most of a tree setup in a script node works way better than a noodle soup.

og76 commented 9 years ago

fwiw, I had quite some problems with the latest curve sockets branch. I dlded again now and see that you already removed lots of curve nodes.

Well, the inputs and loft revolve ones seamed ok. The outputs, however did not work right, if at all

! It was also messing with something else, cause I loaded some files from forum with scrips (for tracing partc with curves and the one like find close verts) and they were not working anymore. It's all back to normal now for these 2 scripts, just thought worth mentioning.

JacquesLucke commented 9 years ago

yes. Please don't the use the newest version. It's very unstable and incomplete currently. I remevod some nodes because it is easier then to make deeper changes. But bringing them back won't be a time comsuming task until the main code design is ready. I'll tell you then

JacquesLucke commented 9 years ago

Do you want to test the new spline nodes a bit?

og76 commented 9 years ago

Tested this and that: +most work ok for now +Matrix node output is more compact, great (Don't do it with the input) +I gather for now we play without handles, except for append point ... ok. +The smooth is handy. Should call smooth bezier, not to think of mesh smooth.

on the dark side:

extra:

+++: flower power! (smoothness) there is a bit of a problem with a loop here but I cannot test now: spline loft flowers https://drive.google.com/file/d/0BzzAoBwXO8dsc2dtelh1LWZKLW8/view?usp=sharing I try to use the new list in the pink loop to no result, so I had to use get elem

JacquesLucke commented 9 years ago

Ahh the length. Of course yes. I forgot this! Thanks

The behaviour of the loft node (with the create list node) is intended. You just cannot perform this operation with splines which don't have any points.

Hmm the bevel start and end works here... make sure your curve has a bevel + it is not cyclic

The problem with converting meshes to world space is that there are way more points (most of the time) and it takes some more time to convert them than with curves. But I guess you're right, I should make a checkbox for that in the object mesh info node. But I will make it off by default for performance reasons.

I was also surprised that entering edit mode works with curves. They are somehow stored differently than meshes. If I do the same with a mesh object it will crash. Therefor I made sure that the node sets the mode to object mode automatically. I think this is due to the performance as well. Storing a curve is much more memory efficient than a mesh.

I also don't really like this. I had some problems to implement this node because:

Hm I see there is something that doesn't work as it should. I will look at this file more detailed tomorrow.

Thanks for that much feedback!

JacquesLucke commented 9 years ago

about the length. instead of putting it in the spline evaluator (which doesn't seem like a good idea because it has nothing to do with the parameter) I can make a spline info node which will also include the "Get Spline Points" node.

og76 commented 9 years ago

I thought about spline points too, but evaluator seamed more like an info. You get the length and play with it, with the parameter. But on spline info it's consistent with mesh nodes. I don't know...

og76 commented 9 years ago

just had the latest socket branch: spline area seams ok, I'll test more for other areas

I still think the Curve length belongs to evaluate node and not the spline info: -the spline info has data to compose/decompose the spline by points etc, length is of no use there -the evaluator would have length and the parameter to define partial length (no discussion now that is uniform or not)

JacquesLucke commented 9 years ago

The idea of a partial length is good. So when you use '1' as parameter you have the full length. This seems to be the best solution here

The uniform distribution of points along a spline is still a problem... Also there are two types:

  1. Distribute a given amount of points
  2. Distribute n points with a given distance
og76 commented 9 years ago

I think the uniform parameter has nothing to do with distribution of points. That is a trick to be done using a loop just like grid array or any other math. Using parameter in that calc. The parameter should just evaluate the curve at a certain percent. Or 0-1 factor

I think the parameter is best to imitate the blender formulas. That are at least 3 for now: bevel spline eval

These I tested with bevel and return different proportions. I'm not sure if current parameter (bezier) fits with any of those. The resolution (default) is linear and also consider the u reso setting.

ps: And "Mapping" is a very appropriate word there...

JacquesLucke commented 9 years ago

I have some better code for uniform mapping now. But I'm not sure when it is useful to use the segments option... I will leave this out for now

og76 commented 9 years ago

Sorry, the Spline variant is the uniform one, giving results like path constraint and such...

I have not used the segments, have no idea of usage

JacquesLucke commented 9 years ago

Yes, basically this works now. I'm only thinking about performance stuff (it's not online yet)

Just made a small experiment. One spline is generated with a script and the other can be controlled in the 3d viewport: sinus spline

og76 commented 9 years ago

(socket branch) I kinda narrowed the earlier loop issue like this: https://drive.google.com/file/d/0BzzAoBwXO8dsRWE3eFV4MnRCOFU/view?usp=sharing

plug the get length or debug as indicated and it works! unplug and it doesn't I'll try to simplify further ...

also capture to make sure it's not just my version funny loops

ps: nice uniform parameter. If you would use a circle that could be a skirt, like this it's just a drape

JacquesLucke commented 9 years ago

Looks like there is an issue with copied data in your node setup. Always when an output socket is connected to more than one other input copies will be created from the output. If you aren't aware of this it can be a bit bizarre sometimes but this actually is very important. Otherwise things like this wouldn't work: auto copy creation

Unfortunally the system isn't very smart yet so maybe there are sometimes more copies than really needed. eg: not needed copy Here are three lists in the end but only two are actually needed

JacquesLucke commented 9 years ago

ahh just found the reall issue I guess. W8 it has something to do with this copy stuff

og76 commented 9 years ago

good to know. so for each debug I increase the data/memory in my tree? hmm the setup is weird cause it basically uses a loop as instancer for respective splines ...

JacquesLucke commented 9 years ago

technically yes. Most of the time this is negligible. But if you have a really long list (I tested it a few days ago with a list with more than 5 mio items) a single debug node can added 10 seconds because it copied the whole list. there are two ways to work around that in the future:

  1. Give the debug node an optional output so that you can integrate it in your node chain.
  2. Give nodes a new custom property that tells the internal execution system wether a copy is needed here or not. I prefer the second method because there are also other nodes were the same applies (eg list length node)

you have one spline object in the beginning. Then you append this exact objects multiple times to the list. The unusual thing here is that every item in this list references the same object. So in fact you transform the same spline 5 times in the second loop. You can even see the result in the viewport: spline copy mistake When you disable the update and go into edit mode you can see that everything else worked. There also are faces (move vertices to see it).

But when you connect the debug node to the list beforehand a new copy is created for each individual spline. So they don't reference the same object anymore.

Is this a bit clear?

I don't consider that as a bug, ... it's just a bit unusual... Looks like we will need a node for something like this later.

og76 commented 9 years ago

It's clear. Just unexpected. Especially 2 behaviors depending on a debug or so.. I tried with other data. Expected behavior would be to move the original 5 times if you consider spline like an object (container of data) ... I was treating it like a vector list or such, not instance.

Yes, sort of an instancer for other data would do...

og76 commented 9 years ago

(I hope I'm not bugging you too much, wip and all) testing the new parameter and samples strange empty 001 is already at the end while parameter is 0.989... parameter 98

JacquesLucke commented 9 years ago

can you maybe give me the file? I know that my method doesn't have the exact same result as the one used by blender. I guess we won't have this but it should be close enouph. The position computed by Blender isn't perfect as well. This is due to the fact that this calculation is always an approximation

I'm also thinking about the Length output again. .... I think that it is better to have it in the spline info node,.... again. It just doesn't really fit in the evaluation node because it's something totally different..

og76 commented 9 years ago

https://drive.google.com/file/d/0BzzAoBwXO8dsVVRNZ1hoakFhUm8/view?usp=sharing https://drive.google.com/file/d/0BzzAoBwXO8dsWF91UW9ENXcxZUU/view?usp=sharing

Sorry for the image above, it's misleading. The problem has less to do with blender comparison but with sort of precision issue.

JacquesLucke commented 9 years ago

both problems should be fixed now. Tell me if I'm wrong

og76 commented 9 years ago

tested evaluate parameter 700frames, segments 700, segments start and end 700 frame divisions etc works great :+1:

More than that, the comparison to path constraint, is almost perfect, if u crank up the u reso to 64 (the constraints depend on that, parameter not). But even in default 12 is decently small . parameter ok guess u can see the small gap till the end for 699/700frame :+1:

ps: why do you say that length sock has no place in evaluate node?

JacquesLucke commented 9 years ago

Yes that looks good hehe

Hm I think it isn't clear what the Length socket shall output. The length of the curve from the start to the given parameter? Then the default parameter should be 1.0 because otherwise this outputs 0.0 what can be quite confusing. Also when we want to support this partial length feature, we should have a 'Start Parameter' and 'End Parameter' input (I know you can do it with simple subtraction, but it would be more efficient and clearer to the user)

og76 commented 9 years ago

Ah, now I see what you say. I was thinking only of total length, and said play with parameter in the sense that you can do your math after. ok.

I think a total length should always be available. Add an extra socket for partial length, if the case. If you have it in 2 nodes as total in info and partial in eval it will be also confusing. Some variants:

  1. Rename to "Total Length" to be clear
  2. only one length (fixed value, just some alternatives for parameter usage): 1.1 have only "Total Length". Like now. Let people do the math. Is good for the brain .. 1.2 only "Total Length", but allow negative values for end to start. (May need a bool allowNegativeParameter if u wanna clamp it 0..1 instead -1..1) 1.3 only "Total Length" + Boolean "parameter from end" (better alternative for above) ok, 2 and 3 go for reverse little math
  3. length + partial socks (fixed and partial, separated) 2.1 have a "Total Length" and a "Partial Length" where the partial show 0 -> parameter just an alternative to 0-1 >> 0-length 2.2 "Total Length" and a "Partial Length" that allows negative values, so 0-param and 1--param (from end) May need a bool allowNegativeParameter if u wanna clamp it 0..1 instead -1..1 2.3 "Total Length" and a "Partial Length" + Boolean "parameter from end"
  4. start and end parameters. results in "Total Length" and a "Partial Length". Clear. But it also means 2 sets of vectors for start and end. Really? You do hide the socket now for obj info and such, so it may work like that, default showing only start... wait, end? err, hmm.

I do consider this total length as a great achievement already. I wonder if we really need all this trouble for partial. The total length could be enough for now.