Forum: Poser Python Scripting


Subject: Scripted Shader Node Animation

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


adp001 posted Mon, 09 May 2022 at 3:53 PM

This version can handle RGB inputs:


from __future__ import print_function
# should work with P11 and P12

try:
    import poser
except ImportError:
    import POSER_FAKE as poser

scene = poser.Scene()
character = scene.CurrentFigure()
actor = character.Actor("Body")
materials = actor.Materials()

# I prefer to leave the names as defined in the material (upper-/lowercase). But
# I'm using a set to prevent duplicates.
main = {"SkinLimbs", "SkinTorso", "Iris", "Fingernails", "Teeth", "Gums", "Tongue"}

for (material, zone) in [(mat, mat.Name()) for mat in actor.Materials() if mat.Name() in main]:
    print(material.Name())
    nodes = material.ShaderTree().Nodes()
    for node in [n for n in nodes if "||" in n.Name()]:  # type: poser.ShaderNodeType
        # Split the string at position "||". Spaces are simply ignored ("label || 1_2_3"
        # is just as valid as "label||1_2_3").
        label, p, numberstring = node.Name().partition("||")
        numberlist = [int(n) for n in (numberstring.strip().split("_") if numberstring else[])]
        for number in numberlist:
            # Indexnumber ok?
            if number < node.NumInputs():
                # animatable?
                if hasattr(node.Input(number), "SetAnimated"):
                    node.Input(number).SetAnimated(1)
                else:
                    raise AttributeError("Input is not animatable")
            else:
                raise IndexError("Input number does not exist")
        scene.DrawAll()

        for number in numberlist:
            inp = node.Input(number)  # type: poser.ShaderNodeInputType
            r_parm, g_parm, b_parm = inp.Parameters()
            if all(inp.Parameters()):
                for pre, parameter in zip("RGB", inp.Parameters()):
                    identifier = "%s_%s_%s_%s" % (zone, label.strip(), inp.Name(), pre)
                    parameter.SetInternalName(identifier)
                    parameter.SetName(identifier)
                    print("...", identifier)
            else:
                identifier = "%s_%s_%s" % (zone, label.strip(), inp.Name())
                r_parm.SetInternalName(identifier)
                r_parm.SetName(identifier)
                print("...", identifier)