Forum: Poser Python Scripting


Subject: Snap for Macs - in development

HartyBart opened this issue on Jul 16, 2021 ยท 12 posts


adp001 posted Thu, 22 July 2021 at 11:41 AM

I will do a popup dialog tomorrow.

Meanwhile I tried another method of doing the "snap".

import wx

SCENE = poser.Scene()
actor_iname = SCENE.CurrentActor().InternalName()
offsets = (0, -.2, 0)
msg = wx.BusyInfo("Select Target Actor")


def add_ar(a, b):
    if isinstance(b, (int, float)):
        return [v + b for v in a]
    return [av + bv for av, bv in zip(a, b)]


def mul_ar(a, b):
    if isinstance(b, (int, float)):
        return [v * b for v in a]
    return [av * bv for av, bv in zip(a, b)]


def set_coords(actor, coords=None):
    codes = poser.kParmCodeXTRAN, poser.kParmCodeYTRAN, poser.kParmCodeZTRAN
    if coords is None:
        coords = 0, 0, 0
    for code, v in zip(codes, coords):
        actor.ParameterByCode(code).SetValue(v)


def get_firstactor(obj):
    """Return the first movable actor of a figure, usually the hip"""
    if isinstance(obj, poser.FigureType):
        root = obj.RootActor()
    elif isinstance(obj, poser.ActorType) and obj.IsBodyPart():
        root = obj.ItsFigure().RootActor()
    else:
        return obj
    li = [a for a in root.Children() if a.IsBodyPart()]
    return li[0] if li else obj


def theloop():
    global msg
    if SCENE.CurrentActor().InternalName() != actor_iname:
        del msg

        actor_B = SCENE.CurrentActor()  # Selected target actor.
        if actor_B.InternalName() == actor_iname:
            return  # Actor to move and target actor are the same. Just break the loop.

        if actor_B.IsBodyPart():
            actor_B = get_firstactor(actor_B)
            coords = add_ar(actor_B.WorldDisplacement(), actor_B.Origin())
        else:
            coords = actor_B.WorldDisplacement()

        actor_A = SCENE.ActorByInternalName(actor_iname)  # Actor to move.
        if actor_A.IsBodyPart():
            actor_A = actor_A.ItsFigure().RootActor()
            hip = get_firstactor(actor_A)
            set_coords(actor_A)  # zero body
            set_coords(hip)  # zero hip
            coords = add_ar(coords, mul_ar(hip.Origin(), -1))
        else:
            coords = add_ar(coords, mul_ar(actor_A.Origin(), -1))

        coords = add_ar(coords, offsets)
        for code, v in zip((poser.kParmCodeXTRAN, poser.kParmCodeYTRAN, poser.kParmCodeZTRAN), coords):
            actor_A.ParameterByCode(code).SetValue(v)
        SCENE.SelectActor(actor_A)
        SCENE.DrawAll()
    else:
        wx.CallLater(300, theloop)


theloop()