Forum: Poser Python Scripting


Subject: Scripted Shader Node Animation

Iuvenis_Scriptor opened this issue on May 08, 2022 ยท 19 posts


Iuvenis_Scriptor posted Sun, 08 May 2022 at 11:41 PM

I've been trying to write a fairly simple script that goes through various materials, identifies certain nodes based on a signature in their external names, animate certain inputs in that node based on index numbers provided by tags in their external names, and renames the resulting parameters.  I've rearranged things to avoid animating any inputs to custom-built compound nodes as at least a temporary solution to this apparent problem, but I'm still getting a NoneType error when the script tries to rename the new dial.  The first time I tested it, it actually seemed to work!  But upon further testing, it seems to work only sporadically.  I haven't yet been able to replicate the complete success of that first test, but most times, no dials seem to be created, and sometimes a few of the dials but definitely not all seem to be created before it gets stuck, apparently failing to find the very parameter it should've just created.  According to the print-outs, it's clearly finding the right nodes and inputs with no problem, but it can't seem to make up it's mind over whether it can animate them or not.  At least once, I've noticed a white key symbol in front of a targeted input but no corresponding dial in the parameters palette.

I use a node tagging system where the external name of a node I want to animate is tagged with signals to the script.  For example, for a node named "Testing || 1_2," the " || " says "Animate me!" and the numbers following it say, "Specifically inputs 1 and 2."  I have tweaked the script since that first test, but never in a way that should affect the core loop.  I've only tried to restrict the materials it applies to and/or load a PZ2 after everything else is done.  I'm working in Poser 12.0.757.  I've tried splitting the loop in two, just animating everything all at once in one loop and renaming the dials in a completely separate loop afterwards.  That did not help.  My code looks like this.


import poser
scene = poser.Scene()
character = scene.CurrentFigure()
actor = character.Actor("Body")
materials = actor.Materials()
main = ["SkinHead","SkinLimbs","SkinTorso","Iris","Fingernails","Teeth","Gums","Tongue"]
for material in materials:
    zone = material.Name()
    if zone in main:
        tree = material.ShaderTree()
        nodes = tree.Nodes()
        print(zone)
        for node in nodes:
            name = node.InternalName()
            label = node.Name()
            print("\t"+label)
            if " || " in label:
                numbers = label[label.find(" || ")+4:len(label)+1].split("_")
                for number in numbers:
                    index = int(number)
                    input = node.Input(index)
                    print("\t\t"+input.InternalName())
                    input.SetAnimated(1)
                    parameter = input.Parameters()[0]
                    identifier = zone+"_"+label[0:label.find(" || ")]+"_"+input.Name()
                    parameter.SetInternalName(identifier)
                    parameter.SetName(identifier)
                    print("\t\t"+identifier)


Thanks in advance for any tips on what I'm doing wrong!  I'll keep tinkering and researching.