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()