Pythonian way to add parameter groups? And put dials in those groups ?



  • You can click the right-pointing triangle at the top right of any actor's parameters tab to get the 'Create New Group' (see annotated screenshot below), but is there a way to do this using Python ? (I can't find anything in the PP2014 PoserPython Reference to fit the bill)

    On a related note, actor.CreateValueParameter() can be used to create a dial in any actor (contrary to what the manual says), but it always puts them in a group entitled 'Other'. Is there any way to specify a different group ?

    0_1525531473174_python.jpg

    P.S. Query related to this thread https://forum.smithmicro.com/topic/3804/freazypose-a-free-poserpython-script-to-add-easypose-controls-to-a-figure/9


  • Poser Team

    The only way I have found to do what you are after is to have the script write a pose file, then call that pose file with the grouping info in it. Sort of a round about way of doing thou....



  • @3dcheapskate yep @shvrdavid suggested solution is the only thing I've found to work reliably, at least until SMS add actor.CreateParameterGroup(groupName) functionality to the Poser Python API. At least the loaded pose file can explicitly insert subgroups in the correct place within the group hierarchy, rather than just tacking them on the end.



  • Thanks, hadn't thought of that even though I've used writing/loading a temporary pose file in the past, specifically to correctly parent a prop so it's deleted/saved with the figure as per the workaround found here https://www.renderosity.com/mod/forumpro/?thread_id=2877159 .

    This is the what I used for that specific instance, Antony Appleyard's code more or less verbatim:

    def parentprop(ac,par):
        scn = poser.Scene()
        if ac.IsProp():
            scn.SelectActor(ac)
            propin=ac.InternalName()
            propen=ac.Name()
            parin=par.InternalName()
            paren=par.Name()
            sTmp = os.path.join('Runtime','Libraries','Pose','3DCheapskate','SmartPlus','TempPose.pz2')
            poserpath=os.path.split(poser.AppLocation())
            fileaddr =  os.path.join(poserpath[0],sTmp)
            pose=open(fileaddr,"w")
            pose.write("{\n\tactor $CURRENT\n\t{\n\t\tsmartparent "+parin+"\n\t}\n}\n")
            pose.close()
            scn.LoadLibraryPose(fileaddr)
        else:
            print "FAILED:", propin," is not a prop"
    

    So I guess something similar to that should do the trick.



  • Quick test of a manually created PZ2 file in PP2014. First I manually added a new parameter to the figure using the "Create new Master Parameter" from the UI pop-up menu. This created a new parameter "Master 1" and puts it in a new group "Other". Saved the CR2, viewed it in an editor, and created this pose file:

    # This works as long as the "Master 1" dial  exists in the actor - it creates the new group and moves the dial into it
    {		
    	actor $CURRENT
    	{
    		channels
    			{
    			groups
    				{
    				groupNode NEWGROUP
    					{
    					parmNode Master 1
    					}
    				}
    			}
    	}
    }
    

    Applied this pose to the same actor and it seems to successfully move the "Master 1"dial from the "Other" group to a new "NEWGROUP" group.

    So I'm thinking that I'll use actor.CreateValueParameter() which will create the dial I want but in the wrong "Other" group, then write/load a pose file to create a new group and move the dial I just created into that. But that leaves a possibly empty "Other" group...

    P.S. I tried including a new parameter in the pose file but this didn't seem to work - the new group was added but no new dial. Didn't really expect that to work though, but worth a try !

    # Does NOT work - creates the new group but not the new dial
    {		
    	actor $CURRENT
    	{
    		channels
    			{
    			groups
    				{
    				groupNode NEWGROUP
    					{
    					parmNode FRED
    					}
    				}
    			valueParm FRED
    			{
    			name Master 1
    			initValue 0
    			hidden 0
    			enabled 1
    			forceLimits 0
    			min -100000
    			max 100000
    			trackingScale 0.004
    			keys
    				{
    				static  0
    				k  0  0
    				}
    			interpStyleLocked 0
    			}
    			}
    	}
    }
    


  • @3dcheapskate I can't think of a way to emulate the group deletion available in the UI with a pose file. You have the option to toggle the collapsed state of the unused "Other" group, but that will always get recreated if you choose "Show hidden parameters" from the UI, as that's where the normally hidden joint parameters like origin get put by default. In which case, you could probably just resign yourself to ignoring "Other", whereas some other parameter group would just be misleading, if it existed but hosted no parameters.

    Sorry, I can think of a way, but it requires SMS to implement all the missing features in the Poser Python API. ;-) So, no current workaround, unless you want a script which will save a scene, parse it for empty parameter groups and delete them, and then reload the modified scene...



  • Okay, it works - code similar to the following:

    	if not curact.Parameter("FirstNewDial"):
    		curact.CreateValueParameter("FirstNewDial")
    	if not curact.Parameter("SecondNewDial"):
    		curact.CreateValueParameter("SecondNewDial")
    	# ...etc...
    	sTmp = os.path.join('Runtime','Libraries','Pose','3DCheapskate','SmartPlus','TempPose.pz2')
            poserpath=os.path.split(poser.AppLocation())
            fileaddr =  os.path.join(poserpath[0],sTmp)
    	pose=open(fileaddr,"w")
    	txttowrite="{\n\tactor $CURRENT\n\t{\n\t\tchannels\n\t\t\t{\n\t\t\tgroups\n\t\t\t\t{\n\t\t\t\tgroupNode "+"NewGroupName"
    	txttowrite=txttowrite+"\n\t\t\t\t\t{\n\t\t\t\t\tparmNode "+"FirstNewDial"
    	txttowrite=txttowrite+"\n\t\t\t\t\tparmNode "+"SecondNewDial"
    	# ...etc...
    	txttowrite=txttowrite+"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t}\n}\n"
    	pose.write(txttowrite)
    	pose.close()
    	scn.LoadLibraryPose(fileaddr)
    

    creates a temporary file like this:

    {
    	actor $CURRENT
    	{
    		channels
    			{
    			groups
    				{
    				groupNode NewGroupName
    					{
    					parmNode FirstNewDial
    					parmNode SecondNewDial
    					# ...etc...
    					}
    				}
    			}
    	}
    }
    

    and the new parameter dials end up in the correct group.
    And the "Other" group isn't created, so that's not a concern any more.
    (Tested in PP2014)



  • @3dcheapskate yes, that's good. It's also worthwhile to note that your code works because group creation (for new valueParms) and visibility is only realised when the current actor's parameters are visible in the parameters palette. Many times, I've noted that some actors which load in from a figure CR2 file and have no groups defined in the file, yet do have parameters (if the figure was created before groups existed, for instance), subsequently have had their groups created when I inspect the figure saved back to the library, yet others didn't. The key to which did or did not, was whether I had selected that actor when the parameters palette was open, thus forcing the creation of an "Other" group or a "Morphs" group in the case of newly created targetGeom morph parameters.

    So an obvious step to prevent spurious "Other" group creation would be to temporarily close the Parameter palette (not recommended), or, instead, ensure that the actor you are creating the parameter and groups on, is not the currently selected actor in the scene, before creating the valueParameters, since they do default to the "Other" group.



  • @3dcheapskate Oh, wait... I've thought of a possibility for deleting groups, which I haven't tested yet, so it may be a phurphy. I wonder if loading a pose file which just has:

    {
    actor $CURRENT
        {
        channels
            {
            groups
                {
                }
            }
        }
    }
    

    would actually delete all the existing groups? Or maybe it just does nothing. [Waiting for a render to finish so I can test this]



  • No. Scratch that. It may have worked once, or during the loading of a figure on a previous version of Poser, but it does absolutely nothing on PPro 11.1.0.34764


Log in to reply
 

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