Forum Moderators: Staff
Poser Python Scripting F.A.Q (Last Updated: 2024 Dec 02 3:16 pm)
But now. Meanwhile I am back home (6 hours train ride from Munich to Cologne).I visited my sister who lives at the Tegernsee. Have unfortunately since yesterday not found the time to enter here faster.
Actually I find the problem of being able to move a prop or figure near another object with one click useful and quite interesting when it comes to solving it.
@Hartybart: Thanks for the descriptive comments. However, I have something to note about the first comment in theloop() function.
You wrote: "Check we have the correct actor selected, before starting the loop."
But actually it should say: Check if we have another actor and, if so, break the loop.
Ok, thanks - I try to keep track of the suggested changes, and then re-post the entire tested script when enough changes have accrued. I've also proof-read some of my comments and made minor fixes there.
Learn the Secrets of Poser 11 and Line-art Filters.
I can imagine a dialog box that asks me if I want to switch to a overhead "Bird's Eye" zoomed-out view of the scene, and if I do then the script does that for me. Use case: user has a big complex battle scene and cannot see in the Viewport where the destination actor is. They then realise they need to back out of the current script, switch-zoom-frame for a wider view, and re-run the script.
Or the choice could be done via a drop-down of other actors in the scene, and the user would select the destination actor by name. But that gets away from the ease of just clicking on the destination actor, which I think is what most users would want.
Another thing I can imagine is a three-choice dialog: "Do you have a small, medium or BIG mover actor?" If the user selects BIG then the destination location offsets are changed from 0.2 to 1.2.
Learn the Secrets of Poser 11 and Line-art Filters.
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()
Took me a while, but I'm starting to see land.
I'm hooked on user interface tinkering. It's hard to believe that wxPython can't make dialogs look the same in different versions and machines. The problem is that wxPython tries to leave the design of the controls to the system. So it happens that an interface looks like this on one system and completely different on another. In addition, wxPython works differently under P11 than under P12.
I have now built a part of the controls "discrete". As you can see, the radio buttons and the check controls are still original. But they will be added as well. The actual programming is done with Python 3.9 under Linux and then tested with Python 2.7 under Poser 11 in Windows (running in a virtual machine). This should ensure that it all works with P12 and not just Windows.
The controls for entering offsets are interesting. They can be compared to the controls in Blender. However, I added a few more things:If you change the values with the mouse (as with the standard Poser dials), and hold down Shift and/or Ctrl at the same time, the "scale factor" changes ("sensitivity" is what it's called in Poser). And the right mouse button shows a drop-down list with the last ten values ("History"), from which you can select one.
About the functionality: I think I've finished that.It works as I want it to work (which doesn't mean that others would prefer it to work differently). Since the logic is quite simple, it can be easily changed if needed.
I just have to clean it up a bit (there are some debug prints in there and some other stuff I don't need anymore) and then I'll post the whole thing. As a ZIP, because there are several files - and a lot of code, just for the UI.
I have to stop for the weekend. But if you want to try how it works, just download the ZIP, extract it to a folder and start "Snap2Object.py". Should run with P11 and P12.
https://adp.spdns.org/Snap2Object.zip
Any feedback is welcome. Also any ideas how to proceed with it. Any errors? What makes sens to add or change?
HartyBart posted at 1:54PM Sat, 31 July 2021 - #4423398
I can imagine a dialog box that asks me if I want to switch to a overhead "Bird's Eye" zoomed-out view of the scene, and if I do then the script does that for me. Use case: user has a big complex battle scene and cannot see in the Viewport where the destination actor is. They then realise they need to back out of the current script, switch-zoom-frame for a wider view, and re-run the script.
This shouldn't be a problem anymore, because the script can be part of Posers UI (drag the script window somewhere into Posers UI). The "Activate" Button can be switched on and off (becomes red if active).
Or the choice could be done via a drop-down of other actors in the scene, and the user would select the destination actor by name. But that gets away from the ease of just clicking on the destination actor, which I think is what most users would want.
Drop-down is there. If active and something other then "Current Actor" is selected, this actor is moved to the next clicked actor/figure.
Another thing I can imagine is a three-choice dialog: "Do you have a small, medium or BIG mover actor?" If the user selects BIG then the destination location offsets are changed from 0.2 to 1.2.
The offset dials can be dragged with the mouse even if the active button is red (the script is active). And because the inputs have a history (right mouse click), you can easily switch between up to ten positions.
Hi, did you ever get this working in poser12?
I aim to update it about once a month. Oh, and it's free!
This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.
The following was kindly posted by adp001 for a new user a few days ago, and slightly extended by me. It is working and adp001 suggested I post it here for further comments and development. As you may know, Ockham's vital Snap mover script used Tkinter for looping, and thus was not for Mac users of Poser. The script below is a working demo of the same, but using WX rather than Tkinter. Thus it can (should) work for Mac users, providing them with a vital addition to Poser 11 and possibly also 12.
Learn the Secrets of Poser 11 and Line-art Filters.