Zeroing a figure in PoserPython ?



  • Something like this seems the straightforwardest way...

    for act in fig.Actors()
    for parm in act.Parameters()
    # then something like: if internal name is xRot/yRot/zRot set it to zero, otherwise ignore it

    ...but am I missing something ?

    (P.S. THE FORUM SOFTWARE REMOVED THE TABS FROM THE CODE BLOCK)



  • This seems to work:

    # Zero the figure
    for act in fig.Actors():
    	for parm in act.Parameters():
    		if parm.InternalName()[1:5]=="tran" or parm.InternalName()[1:4]=="rot":
    			parm.SetValue(0.0)
    

    (hmm... interesting - when I pasted that it showed correctly in the right hand pane, and in the post itself)

    If all figures use the internal names 'xrot', 'yrot', 'zrot', xtran', 'ytran', and 'ztran' then I'm okay (until I come across a morph with internal name 'grotty' or suchlike), but I have a sneaking suspicion that a couple of figures at least don't...

    But now I'm wondering exactly what sort of zeroing I'm trying to do. Do I want to also ensure that all scale values are zeroed (i.e. set to 100% - so 'zeroed' probably isn't the right word).

    I think my real question is:

    When we talk about 'zeroing a figure' (in preparation for e.g. loading an item of dynamic clothing) what exactly do we mean?

    • Zero rotations (as per Joint Editor > Zero Rotations), yes?
    • Zero BODY translations, yes?
    • Zero Hip (and other body part translations) ?
    • Set all scalings to 100% ?
    • Set all morphs to 0 ?
    • etc...
    • Do we have to disable IK chains as part of the process ?

  • Poser Ambassadors

    For determining which parameters to zero, I'd use an explicit set of parameter internal names. I don't know if figures exist where they are not the standard ones, but certainly other parameters can accidentally be picked up by your substring matcher.

    Here I store the parameters that should be zeroed in a Python "set" which does very fast membership tests. if x in mySet: ...

    import poser
    
    def zeroFigure(fig = None):
    	if fig is None:
    		fig = poser.Scene().CurrentFigure()
    		if fig is None:
    			return
    	zeroParms = set(['xTran', 'yTran', 'zTran', 'xRotate', 'yRotate', 'zRotate'])
    	for a in fig.Actors():
    		if a.IsBodyPart():
    			for p in a.Parameters():
    				if p.InternalName() in zeroParms:
    					p.SetValue(0.0)
    	poser.Scene().DrawAll()
    
    
    zeroFigure()
    

    My meager testing of this function seems to work regardless of IK settings.

    If you want it to set scales to 1.0, I'd make another set of oneParms = set( 'xScale', ... etc.) and use that to test for setting value to 1.0.

    As to what you want to set, I guess that depends on what you're trying to do and or what you call the function. "Reset Morphs" would, IMO, be expected to leave rotations unchanged while "Reset Rotations" would, IMO, be expected to leave morphs unchanged, etc.

    To fully prepare to load dynamic clothing, you would need to not set rotations to zero, but rather to the "zero pose" which may or may not be literally 0.0 everywhere. In general, I don't know how you'd know that, though.


  • Poser Ambassadors

    The Poser menu item "Figure / Zero Figure" seems to reset morph dials, too.


  • Poser Ambassadors

    poser.ProcessCommand(1602)



  • @Snarlygribbly said in Zeroing a figure in PoserPython ?:

    poser.ProcessCommand(1602)

    Interesting, and useful to know!

    I did a google search for 'poser.ProcessCommand' and found a fair number of threads. Apparently that 1602 and other menu item codes can be found in an XML file /Runtime/ui/Poser.xrc (see gadgetgirl/eclark's comments)

    Also saw a statement somewhere that 'poser.ProcessCommand' was 'undocumented and unsupported by SM' (forgot to note the URL of that reference).

    Also found a 2014 comment from Netherworks (in relation to problems running Reality, Advanced Library Manager, and DSON together) that "...Technically, some methods like "ProcessCommand", which directly accesses Poser's menu commands, are causing crashes or instability."

    Since I've been having a few weird crashes (probably related to my own badly written PoserPython inadvertantly interacting with other scripts/plugins I use) I think it'd be tempting fate to use this call... :)



  • @bagginsbill said in Zeroing a figure in PoserPython ?:

    For determining which parameters to zero, I'd use an explicit set of parameter internal names. I don't know if figures exist where they are not the standard ones, but certainly other parameters can accidentally be picked up by your substring matcher.

    The only non-standard bit of the x/y/z rotation/translation internal names I've spotted is that DAZ figures use all lowercase while Poser figures use intercapping, so adding both versions to the set (or doing a case-insensitive check) should be fine.

    @bagginsbill said in Zeroing a figure in PoserPython ?:

    To fully prepare to load dynamic clothing, you would need to not set rotations to zero, but rather to the "zero pose" which may or may not be literally 0.0 everywhere. In general, I don't know how you'd know that, though.

    Ah yes, I think that initial "zero pose" (with legs/arms bent in the 'preferred' direction for the IK, iirc?) was nagging my subconcious.

    The 'zero' I'm actually after is to position a smartprop in the figure's hand. Till now I've always used the Figure > Zero Figure from the Poser menu which zeroes all joint rotations (just double-checked), and my props all work fine. So I think I'm okay on that.



  • poser.ProcessCommand(1602) seems to work fine (I know I said I'd give it a miss, but I had to try it)

    I had to expand the set in bagginsbill's code to this...

    set(['xTran', 'yTran', 'zTran', 'xRotate', 'yRotate', 'zRotate', 'xtran', 'ytran', 'ztran', 'xrot', 'yrot', 'zrot'])

    ...to get it to work with Michael3. Works fine with a few other random independent figures I tried.


  • Poser Ambassadors

    @3dcheapskate The ProcessCommand() method is documented (page 42 of my version of the PoserPython manual), albeit inadequately (the IDs of the menu commands are not listed). I have not personally experienced any instability resulting from its use but I also trust Netherworks as he knows his stuff :)

    The Poser.xrc file is indeed the source of the IDs. There are many useful things you can do using this method. It's also neat to be able to do a lot of stuff with just one line of code. It also has the benefit of future compatibility - if ever it becomes necessary to zero more parameters then it will be built into the menu command and your own code will automatically benefit from that. Of course, that can also work against you if compatibility with the actions of the menu command is not your intention.



  • Ah yes, it's in the PP2014 PoserPython Manual, but not in the Poser 9 one (which is probably where I looked). Maybe my own mind concocted the 'undocumented' bit when it failed to find it in the Poser 9 manual? But I'm fairly sure* that I read a statement somewhere that ProcessCommand() was unsupported by SM...

    Maybe that's all changed anyway - the fact that it's in the PP2014 manual without any such statement would seem to support that view. And maybe the crash/instability problem got resolved?

    Anyway, I now have two methods of doing what I was after, both better than my original. :)

    *(But then I'm also fairly sure that the moon is made of cheese... ;o)



  • I've never worked with Python, but doesn't it have some kind of UpperCase method? So:

    set(['XTRAN', 'YTRAN', 'ZTRAN', 'XROTATE', ...

    Then:
    if UpperCase(p.InternalName()) in zeroParms: ...

    Something like that?



  • Well spotted - I guess that'd be the upper() and/or lower() methods/functions/thingumajigsthat I found after googling "python uppercase".

    A definite :facepalm: to self for missing that! ;o)

    (I like to think of this stage as 'fine-tuning' my code - it sounds better than 'fixing the stupid mistakes'! LOL )



Looks like your connection to Graphics Forum was lost, please wait while we try to reconnect.