3
$\begingroup$

Heavily Edited

I want to make a procedural animation loop seamlessly and, while iterating, I'd like to vary the total frame count for length (& varied fps renders) without having to manually update all properties every time I experiment with this. Simply: I want to plug in a value once into the playback editor or properties panel and have all involved properties reference this to run each experiment.

I can foresee a frustrating experience with the housekeeping because of the number of properties (not only those in the following example) referencing total frame length / end frame.

Is it possible to reference this w/ an expression / driver?

When I create a driver via expression on a Musgrave Texture "W" socket or Mix "Factor" socket it returns an "Invalid Python Expression" error because of 'frame_end' in the following B texture W socket:

A MusTexture W: #frame/60
B MusTexture W: #(frame-frame_end)/60

Mix Factor: frame/frame_end

The first image below shows the end frame expression which works (600 is the end frame), however I have to input this manually into every expression which is becoming cumbersome and frustrating (from distraction). Can I automate this?

Thank you for your time and understanding.

Please reference both Markus von Broady's and Quellenform's answers for full understanding of the answer

Edit: Added detail of current Texture B socket code, 600 is current end frame.

Detail of Socket Code

$\endgroup$
4
  • $\begingroup$ Hello and welcome to Blender.SE! Take a look at the nodes Scene Time and Math. These two nodes in combination should do what you want. $\endgroup$
    – quellenform
    May 10, 2023 at 23:15
  • $\begingroup$ Thank you for the comment, but I'm not sure if I was clear about what I'm looking for. I'd like to find a way to code the input value of the total frame count to streamline input. Since we can use FRAME, I'd like to know the name of the string for the end frame as endFrame returns an error and disables the driver for that socket when used. Neither Scene Time nor Math nodes pages in the manual expound on what strings can be used for frames in node sockets. Perhaps I can add another image to clarify. $\endgroup$
    – sevens
    May 11, 2023 at 0:36
  • $\begingroup$ These two questions together answer yours I think: blender.stackexchange.com/questions/27889/…, blender.stackexchange.com/questions/51530/… $\endgroup$
    – Valalala
    May 11, 2023 at 5:07
  • $\begingroup$ Thank you for the comment. This feels like it is getting me closer, but I'm struggling to understand exactly what to do. I'm not familiar with the language. I've tried to run this script to add an expression to the driver, but line 3 fails syntax: 1import bpy 2 3def frame_end: 4 """returns total frames""" 5 return bpy.context.scene.frame.end 6 7# Add function to driver_namespace. 8bpy.app.driver_namespace['frame_end'] = frame_end but I'm just guessing at what to plug in where. $\endgroup$
    – sevens
    May 11, 2023 at 7:07

3 Answers 3

3
$\begingroup$

As I mentioned in the comments at the beginning, you can solve this with a few nodes.

At least I don't see any reason why an (unsafe & slow) Python expression should be used here.

As Markus from Broady correctly showed, you just copy "Frame End" as a driver into an input field.

To stay flexible, and that's what he meant in his comment, you do the rest with a few nodes.

If that's too much trouble for you, just put the nodes into a node group.

And if you want to make certain parameters flexible, put them on the Group Input of your node group so that they can be set individually at any time and you can use the node group as many times as you want in your setup.

Like this:

enter image description here


(Blender 3.2+)

$\endgroup$
2
  • $\begingroup$ Thank you for your answer/patience. Tested without execution, but the value is updating! I'm sorry for my impatience: this--in combination with the insight from @Markus von Broady--was the answer. While it was not the answer I was initially looking for, it appears to be a much superior alternative, if I understand the warnings from Blender and all of your comments about avoiding unnecessary Python expressions correctly. I was looking for the wrong answer. I'll update this one answered. Thank you, this stretched the limits of my knowledge a little and that's the greatest gift. $\endgroup$
    – sevens
    May 12, 2023 at 17:00
  • 1
    $\begingroup$ @sevens You're welcome! The rule of thumb in the case of geometry nodes is actually always: Do what you can do with nodes, and use Python/Drivers ONLY where it cannot be avoided or where the nodes are really not sufficient. $\endgroup$
    – quellenform
    May 12, 2023 at 17:22
3
$\begingroup$

Just use

bpy.context.scene.frame_end

instead of frame_end

Further explanation here: https://docs.blender.org/manual/en/latest/animation/drivers/drivers_panel.html#expressions

that's how my driver looks like: enter image description here

$\endgroup$
9
  • $\begingroup$ I am pretty sure that won't work on its own. Unless I am missing something, you have to add a function to the driver namespace which then calls bpy.context.scene.frame_end. The link does explain how to do that, but I think that information should be in the answer itself. $\endgroup$
    – Valalala
    May 11, 2023 at 4:58
  • $\begingroup$ @Valalala: just try it out instead of writing wrong comments - and little hint from me: i tried it out - then i wrote the answer. $\endgroup$
    – Chris
    May 11, 2023 at 7:08
  • $\begingroup$ i am not sure what you mean with "list". But you can simply delete your driver and add a new one and use the command i used in my answer as scripted expression. I can provide a blend file if that helps you $\endgroup$
    – Chris
    May 11, 2023 at 7:14
  • $\begingroup$ of course you could also user driver_namespace as Valalala pointed out, but it isn't necessary. And since you said you have less experience with python, my solution might be easier to understand and use for you $\endgroup$
    – Chris
    May 11, 2023 at 7:16
  • $\begingroup$ Thanks for the comment, Chris. Is there a way to get only the frame_end value as an expression that can drive (i.e. as @Valalala suggests via namespace)? I'd like to use it for a few different operations and I'm not sure this will save time vs manual input as I'll have to set up multiple drivers for each operation. OTOH I'm hitting a wall so after sleep I might be fresh to understand drivers better. This must be the answer, but I think I need a new question/direction. Will update in the morning after trial. (Am 100% blank slate w/ coding/Python if not apparent, but willing to learn.) $\endgroup$
    – sevens
    May 11, 2023 at 7:32
3
$\begingroup$

As a general rule, you can right-click your source of choice, and from menu pick "Copy as a New Driver". Then you can right-click the value to be controlled by the driver, and choose "Paste Driver". Now editing the driver will allow you to inspect how to target the source, or just modify the driver to be a scripted expression and modify the expression to your needs.

$\endgroup$
7
  • $\begingroup$ True, thank you for the response and info, however these instances of “end frame” occur almost exclusively in different equations, so copying would not solve the problem in this case. $\endgroup$
    – sevens
    May 11, 2023 at 22:41
  • $\begingroup$ @sevens how so? I don't understand. $\endgroup$ May 11, 2023 at 22:49
  • $\begingroup$ In the code in the problem posted, Musgrave texture node B must subtract from frame to return a negative, the mixer node it feeds must divides frame by it. This is just an example from many instances of requiring this value: I’m looking for a specific solution to reference frame_end through expression/driver/code. Neither frame-end nor bpy.context… (@Chris solution) work in a driver for this value for me. Errors (see above). Manually punching in end frame values for all these properties is onerous and prone to data entry errors. $\endgroup$
    – sevens
    May 12, 2023 at 2:19
  • $\begingroup$ @sevens in the GIF I posted, you don't have to modify the driver, you can have a simple value node be set to the frame_end. Then you can pass this value further to use in math nodes. If the problem is modifying all your existing drivers, then the only solution would be some Python script that iterates over all drivers and automatizes adding a new variable and modifying the expressions. $\endgroup$ May 12, 2023 at 8:35
  • $\begingroup$ I agree, don't do calculations inside of drivers. They're awfully slow. Use the driver to drive a Value node, and do your maths with math nodes $\endgroup$
    – Gorgious
    May 12, 2023 at 16:30

You must log in to answer this question.

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