Forum: Poser Python Scripting


Subject: How to change texture of a node from Shader tree?

maur_2005 opened this issue on Jan 09, 2020 ยท 5 posts


maur_2005 posted Thu, 09 January 2020 at 10:31 AM

Hi folks,I'm trying to change the texture of a node in the Shader Tree but I'm having trouble, maybe someone can help me This is my code:

NewPathString = ""
NewTextureString = ""

scene = Poser.Scene()
actor = poser.Scene().CurrentActor()

for mat in actor.Materials():
     Tree = mat.ShaderTree()
    
    for node in tree.Nodes:
          if targetNodeName = node.Name()
               node.Material(mat.Name()).SetTextureMapFileName(NewTextureString)

adp001 posted Thu, 09 January 2020 at 11:11 AM

You can set a Texturemap with SetTextureMapFileName to a material as base-texture. But not to a Node.

All Nodes follow the same rules. They have Inputs and Outputs where something can connect to (even values or textures). Inputs and outputs are arranged as lists. See "PoserPython Methods Manual" in your Poser directory.

Normally you have to search or determine the index of an input/output. But fortunately "Image_Source" is the first entry in the node "Image_Map".

< Node >.Inputs()[0].InNode().SetString(< Path >)

Manual says to "SetString": ** SetString** Explanation Set the string value. In this version of Poser, this is the path of a texture or movie file. Arguments Enter the path name for the desired texture or movie file.




maur_2005 posted Thu, 09 January 2020 at 12:48 PM

Thanks adp001, I will try to do that...

The problem is that I don't know exactly which node the texture is in, sometimes that node is called "Image_Map_1" other times "Image_Map_2" or something like that

shaderTree.jpg


adp001 posted Thu, 09 January 2020 at 3:16 PM

Sure, you need to know something about the image you want to change. A path or filename will do if it is unique.

Here is a sample-search:

try:
    # I need to do this to make my editor happy
    import poser
except ImportError:
    poser = None

import re

def find_image(node, name="Image_Source", value="myImage.*"):
    if node is None:
        return None

    if node.Type() == poser.kNodeTypeCodeIMAGEMAP:
        test = re.compile(value)

        for inp in node.Inputs():
            v = inp.Value()
            if isinstance(v, basestring) and test.search(v):
                return node
            result = find_image(inp.InNode())
            if result is not None:
                return result
    return None


sc = poser.Scene()
        
for mat in sc.CurrentFigure().Materials():
    for shadernode in mat.ShaderTree().Nodes():
        # change value to what should be part of the 
        # path you search for
        node = find_image(shadernode, value="Mask")
        if node is not None:
            print node.Name()
            print node.InputByInternalName("Image_Source").Value()


This should give you an idea how to solve your problem.




maur_2005 posted Wed, 05 February 2020 at 8:15 AM

Thank you adp001, that was very useful