4
$\begingroup$

I need to allow the user to create their own transfer function y = f(x)

(I will then use this transfer function to warp the scene)

Currently I'm using a mathematical formula:

y = exp( 1/(x^2 + 1) )

But it doesn't allow a (non-mathematical) artist to shape the curve, and it is awkward even for a mathematician to turn an arbitrary shape into a mathematical formula.

Ideally I would like the user to be able to draw the curve freehand, or maybe in the same manner as constructing curves in Blender.

In fact, can I get away with using Blender's existing curve tool? Say I create a new scene, I suppose I can then create a curve that is constrained to the xy axis. But then how could I get y = f(x) from a Python script?

And also, is there some 2D curve tool, that might allow the curve to be designed from within some panel?

Is there any solution path I'm missing?

$\endgroup$
3
$\begingroup$

After a bit of investigation it seems you can't use Graph Editor for "standalone" FCurves. However, you can link them to any object and name them as you like. I used the default Cube in example below, but it might be as well an empty mesh.

Below script uses Cube as object that "holds" your curves within its animation_data.action. It creates them if they do not exist, and if they exists current one is picked.

import bpy

placeholder = bpy.context.scene.objects["Cube"]
if not placeholder.animation_data:
    placeholder.animation_data_create()
if not placeholder.animation_data.action:
    placeholder.animation_data.action = bpy.data.actions.get("curves") or bpy.data.actions.new("curves")
action = placeholder.animation_data.action

print(placeholder)
name = 'my_curve'

fcurves = action.fcurves
for f in fcurves:
    if f.data_path == name:
        break
else:
    f = action.fcurves.new( name )
    f.select = True
    f.keyframe_points.insert( 0, 0 )
    f.keyframe_points.insert( 100, 10 )

Then you have get to edit curve you can add points by duplicating existing ones using shift-d.

enter image description here

After shaping it you can use FCurve.evaluate() (API docs - bpy.types.FCurve). For example like this:

for i in range(100):
    print(i, f.evaluate(i))
$\endgroup$
  • $\begingroup$ I just had a look at FCurve wiki.blender.org/index.php/Doc:2.6/Manual/Animation/Editors/… -- they seem to be tied to time on the x-axis (frames). Is there any way I can choose my own x-axis e.g. theta from -pi/2 to +pi/2 ? $\endgroup$ – P i Apr 8 '14 at 15:35
  • $\begingroup$ Again, will have to confirm when I will get my hands on Blender, but I don't think you are restricted in any way as far as x-axis is concerned. By default, yes, it is treated that input value is current frame. However as you're going to call evaluate() yourself you shouldn't be concerned about that (as long as you're not planning to plug it as some property). P.S. I am no expert in Blender Python scripting, just guessing from what I know (and it is not that much). $\endgroup$ – elmo Apr 8 '14 at 15:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.