adp001 opened this issue on Apr 04, 2021 ยท 3 posts
adp001 posted Sun, 04 April 2021 at 11:56 PM
from __future__ import division, print_function
try:
import poser
except ImportError:
from PoserLibs import POSER_FAKE as poser
if sys.version_info.major > 2:
basestring = str
map = lambda a, b: [a(_b) for _b in b]
SCENE = poser.Scene()
def node_exist(stree, ntype, name):
for node in stree.Nodes(): # type: poser.ShaderNodeType
if node.Type() == ntype and node.Name() == name:
return node
return None
def get_or_create_node(stree, ntype, name):
node = node_exist(stree, ntype, name)
if not node:
node = stree.CreateNode(ntype)
node.SetName(name)
return node
def copy_input(source_input, target_input):
assert isinstance(source_input, poser.ShaderNodeInputType)
assert isinstance(target_input, poser.ShaderNodeInputType)
target_input.SetName(source_input.Name())
if source_input.CanBeAnimated():
target_input.SetAnimated(source_input.Animated())
v = source_input.Value()
t = source_input.Type()
if t == poser.kNodeInputCodeCOLOR:
target_input.SetColor(*v)
elif t == poser.kNodeInputCodeSTRING:
target_input.SetString(v)
elif t == poser.kNodeInputCodeFLOAT:
target_input.SetFloat(v)
return target_input
def copy_node(source_node, target_node, target_tree):
assert isinstance(source_node, poser.ShaderNodeType)
assert isinstance(target_node, poser.ShaderNodeType)
assert isinstance(target_tree, poser.ShaderTreeType)
for inp_idx, node_input in enumerate(source_node.Inputs()):
copy_input(node_input, target_node.Input(inp_idx))
in_node = node_input.InNode()
if isinstance(in_node, poser.ShaderNodeType):
new_node = get_or_create_node(target_tree, in_node.Type(), in_node.Name())
copy_node(in_node, new_node, target_tree)
target_inp = target_node.Input(inp_idx)
target_tree.AttachTreeNodes(target_node, target_inp.Name(), new_node)
target_node.SetName(source_node.Name())
target_node.SetInputsCollapsed(source_node.InputsCollapsed())
target_node.SetLocation(*source_node.Location())
target_node.SetPreviewCollapsed(source_node.PreviewCollapsed())
def copy_shadertree(source_tree, target_tree):
assert isinstance(source_tree, poser.ShaderTreeType)
assert isinstance(target_tree, poser.ShaderTreeType)
for source_node in source_tree.Nodes(): # type: poser.ShaderNodeType
target_node = get_or_create_node(target_tree, source_node.Type(), source_node.Name())
copy_node(source_node, target_node, target_tree)
def copy_material(source_material, target_material, clean=True):
assert isinstance(source_material, poser.MaterialType)
assert isinstance(target_material, poser.MaterialType)
target_layer_names = [l.Name() for l in target_material.Layers()]
for source_idx, source_layer in enumerate(source_material.Layers()):
if source_layer.Name() not in target_layer_names:
target_material.CreateLayer(source_layer.Name())
target_layer_names = [l.Name() for l in target_material.Layers()]
target_idx = target_layer_names.index(source_layer.Name())
source_tree = source_material.LayerShaderTree(source_idx)
target_tree = target_material.LayerShaderTree(target_idx)
if clean:
for node in target_tree.Nodes():
if not node.Type() in "PoserSurface CyclesSurface":
node.Delete()
copy_shadertree(source_tree, target_tree)
def copy_material_to_actor(source_material, target_actor):
assert isinstance(source_material, poser.MaterialType)
assert isinstance(target_actor, poser.ActorType)
if not source_material.Name() in [m.Name() for m in target_actor.Materials()]:
target_actor.Geometry().AddMaterialName(source_material.Name())
copy_material(source_material, target_actor.Material(source_material.Name()))
def copy_materials(source_poserobj, target_poserobj):
if isinstance(source_poserobj, poser.FigureType):
source_poserobj = source_poserobj.RootActor()
if isinstance(target_poserobj, poser.FigureType):
target_poserobj = source_poserobj.RootActor() # type: poser.ActorType
for material in source_poserobj.Materials():
copy_material_to_actor(material, target_poserobj)
adp001 posted Mon, 05 April 2021 at 12:02 AM
Copy nodes from one existing material to another existing material:
copy_material(material_A, material_B)
Copy an existing materials to any actor. Material is created if it does not exist already:
copy_material_to_actor(existing_material, target_actor)
Copy a set of materials from one poser object (actor or figure) to another object (actor or figure):
copy_materials(source, target)
adp001 posted Mon, 05 April 2021 at 1:03 AM
Update: Set the correct render engine in Shadertree.
def copy_material(source_material, target_material, clean=True):
assert isinstance(source_material, poser.MaterialType)
assert isinstance(target_material, poser.MaterialType)
target_layer_names = [l.Name() for l in target_material.Layers()]
for source_idx, source_layer in enumerate(source_material.Layers()):
if source_layer.Name() not in target_layer_names:
target_material.CreateLayer(source_layer.Name())
target_layer_names = [l.Name() for l in target_material.Layers()]
target_idx = target_layer_names.index(source_layer.Name())
source_tree = source_material.LayerShaderTree(source_idx)
target_tree = target_material.LayerShaderTree(target_idx)
if clean:
for node in target_tree.Nodes():
if not node.Type() in "PoserSurface CyclesSurface":
node.Delete()
copy_shadertree(source_tree, target_tree)
for renderengine in (poser.kRenderEngineCodeFIREFLY,
poser.kRenderEngineCodeSUPERFLY,
poser.kRenderEngineCodePOSER4):
root_node = source_tree.RendererRootNode(renderengine)
if root_node:
troot = target_tree.NodeByInternalName(root_node.InternalName())
target_tree.SetRendererRootNode(renderengine, troot)