2
$\begingroup$

I need to create a script to define certain math functions. This script will not directly modify or create any objects. I will simply use them with the XYZ Math surface and/or the Z Math surface. Among other functions, I need a sgn() function (why on Earth it isn't part of python I cannot fathom) and an a^b function that can handle non-integer b for negative a.

Creating these functions isn't a problem. I already have, for use with drivers, and I know I need to register them there by

bpy.app.driver_namespace['<functionname>'] = <functionname>

But how and where do I register them to be able to use them. My guess would be

bpy.app.foo['<functionname>'] = <functionname>

But what should I substitute for foo here?

This is simply amazing. I've googled for days about this, and the answer is nowhere to be found. Everything is about modifying meshes and creating classes to extend blender's functionality with new addons.. I have no need for that. I may at a later time, but I don't know. Is there really no way to implement a standalone mathematical function and register it in a way that it's available to all aspects of the program?

$\endgroup$
2
  • $\begingroup$ Thanks, David, for that edit. That's almost exactly as what I wanted to appear, but somehow the <functionname> got lost. Don't know if I missed it during cut'n paste of if SE removed it. $\endgroup$
    – user7952
    Commented Nov 12, 2014 at 0:23
  • $\begingroup$ Some clarifications. The functions I gave as examples, are JUST examples, that may be usable as oneliners in e.g. the A parameter for the XYZ Math surface object. But what about more complex functions, say a function that calls itself iteratively? $\endgroup$
    – user7952
    Commented Nov 12, 2014 at 11:15

1 Answer 1

0
$\begingroup$

You first example line bpy.app.driver_namespace['<functionname>'] = <functionname> registers the function within the driver namespace and makes it available as <functionname> within any driver expressions.

From other areas of blender you can access it with it's full data path - bpy.app.driver_namespace['<functionname>'](3) calls that function passing a value of 3.

But that isn't the issue you have with the math object creation -

The XYZ math surface object allows you to enter an arbitrary string to define the surface of the object. As this also allows any python to be run it implements a security feature that prevents any functions not listed in it's safe_list from being run.

To get around this you need to do two steps, add your functions as a module and then import them into the addon and add the names to the safe list. Or you can adjust the usage of the safe list to allow any functions. You may want to duplicate the addon and adjust it so you have your own custom addon that suites your needs. You may also find it easier to define the calculations used and just input a few variables.

For a sign function in a on-line script you can use 1 if x>0 else 0

For a^b I don't see an issue -2**3.5 returns -11.31370849898476

$\endgroup$
5
  • $\begingroup$ The issue isn't calculating the values. The issue is defining names for them. And the second works when a is negative. I want a function that gracefully handles both positive and negative a. Something like if a < 0: retval = -(math.fabs(a)**b) else: retval = a**b return retval $\endgroup$
    – user7952
    Commented Nov 12, 2014 at 11:01
  • $\begingroup$ @sambler I use squircles, and they involve the square root of (co)sines. I handle this by creating a quarter squircle, in the x>=0, y>=0 quadrant, then mirror it over the x and y axes. The problem, that made me ask this question, is that I need to create three squircles, all with prime numbers of vertices. This could, of course, be solved by (slightly correcting) your oneliners, but it lead me to think one or two steps beyond that; the need for mor complex functions, that can't be expressed as oneliners. And what you're saying is that a new addon would be needed to accomplish that? $\endgroup$
    – user7952
    Commented Nov 12, 2014 at 15:02
  • $\begingroup$ I managed to solve my current need with the help of your oneliners, and because of that I marked your answer as the accepted one. Thanks. If you, or any reader, could point me to a good tutorial on scripting for Blender, I'd be very greatful. All those I've found more or less require good knowledge about Python. My programming skills are a bit rusty but moderately advanced, and mainly C and C++ and some VERY rusty Pascal knowledge. What little Python I know is rudimentary at best, and it's something I've learnt since discovering Blender about a year ago. $\endgroup$
    – user7952
    Commented Nov 12, 2014 at 17:04
  • $\begingroup$ The main point is that for security reasons only a particular set of functions can be used, to expand that list the addon needs to be modified. Any python tutorial can get you familiar with the language, the official one is here, python3 specific tutorials are best. blendercookie has several most are free. For blender specific info the api reference is the best resource. Also use the auto-complete in blenders python console. $\endgroup$
    – sambler
    Commented Nov 12, 2014 at 21:40
  • $\begingroup$ I just returned to this my very first question here, and I just spotted a little mistake in your answer. -2**3.5 does indeed return -11.31370849898476. However, what that does is calculate 2**3.5 then negating it, and (-2)**3.5 returns a complex number. The first one is what I wanted to achieve, but doing it in a script with a variable whose sign can be either + or - is trickier, and that's what I needed a sign function for, like this sgn(a)*(fabs(a)**b)). $\endgroup$
    – user7952
    Commented Feb 26, 2015 at 22:48

You must log in to answer this question.