Forum: Poser Python Scripting


Subject: How to mirror a light

sergio777 opened this issue on Sep 18, 2021 ยท 13 posts


adp001 posted Sun, 19 September 2021 at 12:51 AM

from __future__ import print_function, division

import sys
if sys.version_info.major > 2:
    # Python 3 (Poser 12 and above)
    basestring = str

SCENE = poser.Scene()
P_ROTS = poser.kParmCodeXROT, poser.kParmCodeYROT, poser.kParmCodeZROT
P_TRANS = poser.kParmCodeXTRAN, poser.kParmCodeYTRAN, poser.kParmCodeZTRAN


def copy_light(obj):
    """
    Create a new light object and copy as many attributes as possible from
    the old light to the new one. Attention: Maybe not all attributes are reachable
    via Python!
    """
    assert obj.IsLight()
    new_light = SCENE.CreateLight()

    for attr in dir(poser.ActorType):
        if attr.startswith("Set") and any((_p in attr for _p in
                                           ("Ambient", "Light", "Display", "Atmosphere",
                                            "Shading", "Shadow", "Visible", "RayTrace"))):
            getattr(new_light, attr)(getattr(obj, attr[3:])())

    for new_parm in new_light.Parameters():
        old_parm = obj.Parameter(new_parm.Name())
        if not old_parm:
            continue

        for p in dir(poser.ParmType):
            # Copy all attribute values of parameter we have a "Set.." function for.
            if p.startswith("Set"):
                # Try to get the value by shorten the attribute name
                # (by removing "Set").
                try:
                    value = getattr(old_parm, p[3:])()
                    # Because lights has a different parameter set
                    # than other parameters this may fail without consequences.
                except poser.error:
                    pass
                except AttributeError:
                    pass
                else:
                    # Set the value.
                    getattr(new_parm, p)(value)

    return new_light


def copy_mirrored_light(obj, trans="XYZ", rot="XYZ"):
    if isinstance(trans, basestring):
        trans = [(ord(c) - ord("X")) for c in trans.upper()]
    assert isinstance(trans, (list, tuple))
    if isinstance(rot, basestring):
        rot = [(ord(c) - ord("X")) for c in rot.upper()]
    assert isinstance(rot, (list, tuple))

    new_light = copy_light(obj)
    for idx, code in enumerate(P_TRANS):
        if idx in trans:
            p = new_light.ParameterByCode(code)
            p.SetValue(-p.Value())

    for idx, code in enumerate(P_ROTS):
        if idx in rot:
            p = new_light.ParameterByCode(code)
            v = p.Value() % 360
            p.SetValue(180-v)
    return new_light


light = copy_mirrored_light(SCENE.Actor("Light 1"), trans="X", rot="XYZ")