11
$\begingroup$

I would like to be able to access properties of the current scene such as render.fps, frame_start, and frame_end from within a python driver script. I have some data that is defined in terms of seconds, and I'd like the drivers consuming that data to work in two different scenes which have different frame rates.

edit: I tried using bpy.context.scene, but it turns out that is often wrong. Let me be specific: The driver is being evaluated to calculate the position of an object in scene "cave" and bpy.context.scene refers to scene "splash" . In a 1-scene .blend bpy.context.scene works fine. In a multi-scene .blend, bpy.context is not necessarily populated with what a reasonable person would consider 'the context of the driver'.

$\endgroup$

4 Answers 4

8
$\begingroup$

Inside script editor define your own function and register it for driver use:

import bpy

def driver_fce():
    scn = bpy.context.scene
    # You can use here:
    scn.frame_current
    scn.frame_start
    scn.frame_end
    scn.render.fps
    # etc..

    return 0    # some value

# Register it to driver namespace under name 'driver_fce':
bpy.app.driver_namespace['driver_fce'] = driver_fce

Use it like this:

enter image description here

Note that such drivers on node properties do not update correctly and its better to use frame change callback handler instead in that case.

$\endgroup$
3
  • 1
    $\begingroup$ I was originally using that technique in my driver, but when I added more scenes to the .blend file, the driver started malfunctioning because bpy.context.scene referred to a different scene. I eventually determined that bpy.context is NOT what a reasonable person would call "the context of the driver". $\endgroup$
    – Mutant Bob
    Commented Apr 10, 2015 at 15:52
  • $\begingroup$ Could update this answer in that scn can be passed as self for scene drivers. $\endgroup$
    – batFINGER
    Commented Aug 7, 2017 at 11:05
  • 1
    $\begingroup$ Don't use bpy.context from drivers, it may work when working with the viewport in simpler files, but it can break (or even crash Blender) when rendering. $\endgroup$
    – dr. Sybren
    Commented Feb 21, 2021 at 11:12
6
$\begingroup$

Via the depsgraph in driver locals()

Not completely sure how dodgy this is, but will ensure context scene

This is a bit dodgy, and having a Scene depsgraph variable is the best approach (see one of the other answers). Such driver variables allow Blender to know the dependencies, and evaluate things in the correct order. However, since it's not possible to add a "current scene" variable, the approach in this answer is probably still the best way to do this.

enter image description here

In blender 2.90+ the depsgraph is added to the driver locals as "depsgraph" along with the variables (release notes). So, you can use this as Python expression:

depsgraph.scene.render.fps

Related

How can I use a driver for multiple objects?

Use an object as a Driver variable

$\endgroup$
8
  • $\begingroup$ Attempting this gives me ``` File "<bpy driver>", line 1, in <module> File "/home/thoth/art/bridge-demo/driver.blend/Text", line 4, in x_for NameError: name 'depsgraph' is not defined ``` $\endgroup$
    – Mutant Bob
    Commented Feb 19, 2021 at 19:51
  • $\begingroup$ Is that with version 2.49b Bob? $\endgroup$
    – batFINGER
    Commented Feb 20, 2021 at 2:11
  • $\begingroup$ No, it is blender 2.8. I might have to edit this question to give the detailed example that failed, or ask a new question derived from this one. $\endgroup$
    – Mutant Bob
    Commented Feb 21, 2021 at 4:07
  • 1
    $\begingroup$ Lol didn't think so. May only be available since 2.9, hard to keep up, or recall when it popped up.. in locals() using method defined in blender.stackexchange.com/a/199299/15543 Other things to look into: use of legacy depsgraph? $\endgroup$
    – batFINGER
    Commented Feb 21, 2021 at 4:16
  • 2
    $\begingroup$ This is the right approach. Exactly the kind of thing I had in mind when I added this feature to Blender ;-) $\endgroup$
    – dr. Sybren
    Commented Feb 21, 2021 at 5:42
5
$\begingroup$

You can do this by setting the Variable type to Single Property, and the prop type to Scene. As ive done in this image.

If you want to do it in the python you can address the scene directly, rather than using context.

eg;

bpy.data.scenes['Scene'].render.fps

enter image description here

$\endgroup$
3
  • $\begingroup$ This will point to a specific scene..If you run this driver in different scene it will still point to 'Scene'.. $\endgroup$ Commented Apr 11, 2015 at 11:06
  • $\begingroup$ I believe this is what the OP asked for. $\endgroup$
    – wardrums
    Commented Apr 12, 2015 at 12:38
  • $\begingroup$ I want the driver to adapt to the properties of the scene it is in. If I evaluate the driver in the 60Hz scene, I need scene.render.fps==60. If I evaluate the driver in the 25Hz scene, I need scene.render.fps==25. $\endgroup$
    – Mutant Bob
    Commented Apr 12, 2015 at 15:20
1
$\begingroup$

you can find most of those information in the outliner, in the data-block, you just need to search a little bit sectionenter image description here

$\endgroup$
1
  • 4
    $\begingroup$ This doesn't really address the question. While it does have a bit to do with it, it would be appreciated if you would flesh out your answer to explain a bit more about how you would apply the things that you have suggested. Thanks $\endgroup$ Commented Sep 10, 2016 at 7:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .