Sat, Feb 8, 3:06 PM CST

Renderosity Forums / Poser Python Scripting



Welcome to the Poser Python Scripting Forum

Forum Moderators: Staff

Poser Python Scripting F.A.Q (Last Updated: 2025 Feb 05 6:41 am)

We now have a ProPack Section in the Poser FreeStuff.
Check out the new Poser Python Wish List thread. If you have an idea for a script, jot it down and maybe someone can write it. If you're looking to write a script, check out this thread for useful suggestions.

Also, check out the official Python site for interpreters, sample code, applications, cool links and debuggers. This is THE central site for Python.

You can now attach text files to your posts to pass around scripts. Just attach the script as a txt file like you would a jpg or gif. Since the forum will use a random name for the file in the link, you should give instructions on what the file name should be and where to install it. Its a good idea to usually put that info right in the script file as well.

Checkout the Renderosity MarketPlace - Your source for digital art content!



Subject: Creating text files and knowing which directory to put them in - How?


Ajax ( ) posted Mon, 18 August 2003 at 7:58 AM · edited Sat, 08 February 2025 at 3:01 PM

I'm working on a script to save certain types of poses. I can't figure out how to make sure the pose gets saved in a valid pose directory. Ideally I'd like to let the user decide which pose directory to put it in. Does anybody know a way of finding out which pose directory was last used and whether it still exists? Alternatively, does anybody know a way to enumerate the pose directories and then offer the user a choice of which one they'd like to save to?


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


ockham ( ) posted Mon, 18 August 2003 at 10:30 AM

The glob.glob (nice name, eh?) will let you find directories. Something like this: import glob import os GoodPoseDirs = [] ChildFind = "runtime/Libraries/Pose/*" ChildFindNorm = os.path.normpath(ChildFind) ChildList = glob.glob(ChildFindNorm) for OnePossDir in ChildList: ~if os.path.isdir(OnePossDir): ~~GoodPoseDir.append(OnePossDir) You should be able to find the last-accessed directory by using os.path.getatime(). I haven't used this one, but the Python documentation gives good detail. This function gives the time since last access, so you would run through GoodPoseDir using os.path.getatime to find the one with the shortest interval since last use. You could also copy GoodPoseDir into a TKinter listbox for user selection.

My python page
My ShareCG freebies


ockham ( ) posted Mon, 18 August 2003 at 2:53 PM

After a bit of experimentation, I think the getatime() function doesn't work properly on Windows. It may be giving time of creation instead of time of last access...

My python page
My ShareCG freebies


Ajax ( ) posted Mon, 18 August 2003 at 7:58 PM

Thanks Ockham! That's great. Just what I needed to know. When I stopped working on the script last night, it was starting to look OK, but there's still a fair bit of debugging to do. The GUI works, anyway. I've been using a mixture of your LightPanel and Lourdes' morph pose script to work out the right approach. I notice that the list of lights in your light panel has a hidden scrollbar behind it and the scrollbar isn't bound to the list. Did you get a scrolling list working after that?


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


ockham ( ) posted Mon, 18 August 2003 at 11:24 PM

Yes, I fixed that somewhere along the line. If you DL the file now, you'll see that I made the scrollbar work....

My python page
My ShareCG freebies


Ajax ( ) posted Mon, 18 August 2003 at 11:52 PM

Cool. That will save me hunting around for doco on how the TK scrollbars work :-)


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


Ajax ( ) posted Tue, 19 August 2003 at 5:55 AM

Well, I finally got my script to save poses. There's just one catch. It seems that the .Value method for parameters doesn't return the actual dial setting. Instead, it returns a value equivalent to what the dial setting WOULD be if it included all of the ERC influences upon that dial. For example, if I have two morphs and they are both set to zero but they are controlled by a full body morph valueParm that is set to 2, them my script will store the FBM dial's setting as 2 and will also store the settings of each of the two morphs as 2 (despite the fact that they are actually set to 0, the .Value method returns 2 for each of them). The pose will then result in the morphs having an effective setting of 4 each, since the FBM gets set to 2 and so do both of the morphs. This is phenomenally dissapointing. I can see the value in having a method that returns the effective dial setting rather than the actual one, but where the hell is the method that returns the actual dial setting? And I just KNOW curious isn't about to fix the problem any time soon. Hell, I might as well ask them yet again to make the program save poses that include ERC for all the good it will do. (banging head on keyboard in frustration - can't those guys get ANYTHING right when it comes to valueParms? mutter mutter mutter)


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


ockham ( ) posted Tue, 19 August 2003 at 11:21 AM

Welcome to the Curses Club! This is an odd one, and I don't recall noticing it before. I'll take a look and see what's going on. Sometimes, though, these CL weirdities turn out to be logically inevitable; that is, the alternatives would be even worse. That's especially likely in the realm of ERC and crosstalk, where so much of the real action uses Poser functions in unintended ways.

My python page
My ShareCG freebies


ockham ( ) posted Tue, 19 August 2003 at 11:47 AM

Okay, I tried it. Now I see what you mean. The Value() method gives the actual current setting of the parm, not the visible dial setting. This does seem to make sense in the way I mentioned. For the sake of controlling animation, Python needs to know where things actually stand, not the dial settings. One possible solution: Memorize the figure to hold the original settings. Force all valueParms to 0. The slave parms should then hold their "unaffected" values. Record them for your pose file. Reset the figure. This will miss a "master" that wasn't set up as a valueParm, but those are fairly rare.

My python page
My ShareCG freebies


ockham ( ) posted Tue, 19 August 2003 at 2:48 PM

Another random thought, probably too complicated for your immediate purpose but worth pondering for other things..... It should be possible to parse out an existing ERC chain by the same active method. Preserve all initial parm values for the entire figure in an array. Go through the figure, giving each parm a tickle. (Add .01 or so.) After each such increment, run through all the rest of the parms and see who changed and by how much. This will spot all slaves of one master, and their deltaAddDelta scale values. Put the figure back to original between tickles.

My python page
My ShareCG freebies


Ajax ( ) posted Tue, 19 August 2003 at 5:39 PM

Those are good ideas. You've got me thinking. I'll have to do something slightly different to that first method because valueParms are often slaves of other valueParms. Can we access what's stored in a parameter's memorised setting? (what you get when you do a "memorise figure" then read from for a "restore figure"). I'm thinking I could read from those and store, overwrite them with a memorise figure method if there is one, read from the new values to write the pose, then set the memorised values back how they were. While I can see that having Value report effective values rather than visible setting for some things would be useful under some circumstances, I can imagine this isn't the only time where it gets in the way. For a start, Value and SetValue aren't doing the same thing. SetValue sets the actual dial setting while Value reads the effective dial setting. If you tried a script meant to reset dials based on their current setting, you'd be screwed. For example, a sript that's meant to halve parameter settings would look at a dial set to 1 with a master set to 20 (slave's effecive value = 21) and would then reset the slave to 10.5 instead of 0.5 while correctly setting the master to 10, giving you an effective value of 20.5 in the slave instead of the desired effective value of 10.5. That sort of thing could give you some real screw ups. I reckon they need two methods - one to read the dial setting and one to read the effecive value of the parameter.


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


ockham ( ) posted Tue, 19 August 2003 at 6:33 PM

A couple of forest-vs-trees questions occur to me at this point. I don't know your overall goal, but I wonder if a record of a pose really needs the dial settings? Or does it need the actual settings of each joint? Also: Because ERC is hierarchical, you could create an "as-if" valueParm without knowing the real setup. Start from the parms on Body; move them and see what happens elsewhere. The result would be sort of like reducing an equation. The original (which you couldn't see from the viewpoint of Python) might have been: Left Arm = Chest * 0.4 Chest = Body * 0.7 When you move the dial on Body by 1, you'd see Left Arm move by 0.28, and you could write that as a single ERC. (Left Arm = Body * 0.28) without losing any real action. You could then run down through the hierarchy and repeat. The final result might look different from the original setup, but its net result would be the same.

My python page
My ShareCG freebies


Ajax ( ) posted Tue, 19 August 2003 at 7:57 PM

The memorise idea I had won't work because it seems that Poser Python doesn't have an methods for querying memorised values - just for restoring whole actors or figures. My aim is to provide an alternative to the usual pose saving interface that offers more options, including the ability to save poses which are ERC based. Currently in Poser, you can get a nice ERC based pose (such as a fully body morph or an EasyPose pose), but you can't save it. Poser completely ignores the valueParms and writes a pose that just sets all of your rotation dials to whatever setting they would have if ERC relationships were ignored and doesn't set the valueParm dials at all. This is useless and means that in general you can't save poses for EasyPose figures and you can't save FBM poses etc. I want to give users a way to save a pose exactly as they see it in their document window - but also allow them to leave out bits they don't want. For example, I've got checkboxes to let users decide whether or not to include translations or rotations of the Body, so they can make poses that do or don't position the figure in the universe. If they want, they can make a pose that will put the figure in a particular location without changing its posed body parts at all. I'll also let them decide whether they want scale dial settings to go to the file - so after you've morphed and scaled your figure to your ideal figure shape you can save a pose with just morph and scale information to recreate that figure shape any time you want. Ideally, I'd like the user to be able to save the pose exactly as it is, so if you have an FBM setting you want saved, say the FBM dial is set to 1 and all of its slave morphs are set to 0, it should be saved as a zero setting for each slave morph and a settting of 1 for the FBM dial. However, I guess an acceptable workaround would be to save each of the slave dial settings as 1 and not save the FBM, or save the FBM as 0. I'm not entirely happy with that approach, but it will do for the first version. In the longer term I'd like the user to be able to save a pose that will set all of the dials to exactly what they are shown to be in the user interface. The problem with the example you've given is that the equations aren't quite right. We should have: let a suffix of "P" designate the effective Parameter value as returned by Value() let a suffix of "D" designate the visible dial setting (which is what the pose will set) BodyP = BodyD ChestP = ChestD + (BodyP * 0.7) LeftArmP = LeftArmD + (ChestP * 0.4) Therefore LeftArmP = LeftArmD + (ChestD * 0.4) + (BodyD * 0.28) So you see there's no way to shortcut - you have to know every relationship in the chain :-(


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


Ajax ( ) posted Tue, 19 August 2003 at 7:59 PM

Just to clarify, the visible dial settings (...D) shown in those equations are the ones the user sees prior to saving the Pose. The note about it being what the pose will set is just there to point out that poses set visible dials, not parameter values - so being able to duplicate dial settings is important.


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


ockham ( ) posted Tue, 19 August 2003 at 9:41 PM

I see what you're after. The lack of reciprocity in Value/SetValue may be pretty much unsolvable, at least within the pure Python world. There is a CreateValueParm method, but that doesn't make a true ERC; it's mainly meant to be used in connection with the ParmCallback stuff. A script can set up a Callback and a visible dial on Body or elsewhere, then the script goes away and leaves the Callback in control. This can do much more than the normal Poser ERC; the visible dial can control body parts through any kind of math function, or even control something outside of Poser. But it's ephemeral by nature; it doesn't leave a nice record of the relationship.

My python page
My ShareCG freebies


Ajax ( ) posted Fri, 22 August 2003 at 7:46 AM

Hey ockham, I'm trying to work out how to implement the "tickling" approach you suggested, which looks like the best solution. I need to store two numbers (a parameter's value and an adjustment value that will be added to it) indexed by actor and parameter. From what little I know of Python, a dictionary looks like the tool I need, but I can't quite see how to handle the double index. I know I could get the actor name and concatenate it with the parameter name to create a unique string key, but if possible I'd prefer something that allows me to use the actor and the parameter themselves as indices. I guess I want lists or tuples for the two values, placed in a dictionary keyed by parameter, with those dictionaries placed in a dictionary keyed by actor. I'm having a little trouble imaginining the syntax for extracting the two numerical values from such a construction though. How would that look?


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


Ajax ( ) posted Fri, 22 August 2003 at 7:51 AM

Oh...and the big question - How do I dynamically declare a dictionary for each actor? If I want to go through a list of actors and creat a dictionary of tuples keyed by parameter for each actor, how do I do that?


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


ockham ( ) posted Sat, 23 August 2003 at 4:25 PM

This is getting interesting; I'm having to stretch to reach! Feels good. Here's a working example of generating and accessing a dict-of-dicts, somewhere near your idea. import poser scene = poser.Scene() DictOfDicts = # Declare it for OneActor in scene.Actors(): ~AN = OneActor.Name() ~DictOfDicts[AN] = # Set up sub-dict ~for OneParm in OneActor.Parameters(): ~~PN = OneParm.Name() ~~PV = OneParm.Value() # Hold the orig ~~DV = PV + 0.1 # Simulating a delta.... ~~DictOfDicts[AN][PN] = (PV,DV) # Now to access one element with the names: (GroundScale,GroundDelta) = DictOfDicts["GROUND"]["Scale"] print GroundScale,GroundDelta Note that you need to pick up the full tuple each time, and then use whichever members you need.

My python page
My ShareCG freebies


Ajax ( ) posted Sun, 24 August 2003 at 1:26 AM

Thanks ockham. That's just the info I was looking for. I've got the "tickling" script written now but there are two very big problems. The first one is that when you have to check every dial that could be a master against every dial that could be a slave, it takes a very long time for the script to run - too long to be practical. The second problem is that I can't find a way to account for cascaded relationships. For example, say I have a dial called Master which controls a dial called SubMaster which controls a dial called Slave. (Master does not directly control Slave - only via SubMaster) My dial settings are Master=1, SubMaster=0, Slave=0 but because of the relationship between them (for ease, we'll assume all control ratios to be 1) the parameter values are Master = 1, SubMaster=1, Slave=1 I now set all three dials to zero, then I go through tickling each one to see what happens to the others. For Master, I find that it affects both SubMaster and Slave (even though it doesn't have direct control over slave). This is where it breaks down. If I use the information I've gained from tickling, I'll wind up getting the wrong values, as I'll show in a moment. I correctly find that Master is slave to none and that its dial setting must be 1. I correctly surmise that the real dial setting of SubMaster is zero, since its only master is Master (I take the value of SubMaster and subtract the contribution from Master to get the dial setting). For Slave, I see that its value is 1 and that it is controled by Master, which has a value of 1, as well as by SubMaster, which also has a value of 1. I incorrectly conclude that Slave's setting is 1-1-1 = -1 instead of zero. Now of course it would be possible in this case to use the information that SubMaster's real dial setting is actually zero and get the correct result for Slave, but it won't work in all cases. There's no accurate way to make sure that the order you look at the dials runs from Masters to slaves, since within a body part the master may be listed after the slave and dials may even control body parts which are above them in the hierarchy. That means we might be trying to work out SubMaster's contribution to Slave before we've discovered that SubMaster's value has to be adjusted to account for Master. End result: I don't think it's possible with the current Poser Python methods to accurately work out a dial's setting - not without some incredibly time consuming iterative methods that include building a map of the hierarchy of master-slave relationships. I think we're going to have to wait until CL gives us a method that will actually tell us what a dial's setting is. (Grrrrrr - not happy).


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


ockham ( ) posted Sun, 24 August 2003 at 9:35 AM

That's a masterful piece of analysis. I wonder if CL was even aware of this basic but subtle inconsistency? I'd never noticed it, and the parm dials are what I play with more than anything else. You could, of course, get the ERC relationships by reading the source CR2/PP2 file. That would work if you ask the user to specify the filename of the source before starting to work on it. (There's no logical way to get the filename internally.)

My python page
My ShareCG freebies


ockham ( ) posted Sun, 24 August 2003 at 9:49 AM

Attached Link: http://ockhamsbungalow.com/Music/clipmorph.zip

In case you want to try reading the CR2, here's a script (not very useful in itself) that might give you a starting point. The hard part is counting brackets.....

My python page
My ShareCG freebies


Ajax ( ) posted Mon, 25 August 2003 at 4:42 AM

I'll bet that CL had no clue this was going on. I've sent something to their suggestions address about it, but based on past exerience I doubt they'll do anything. They say they go by frequency of complaint and I'll bet I'm the only guy that ever writes to them to complain about this sort of stuff. Frankly I wonder whether what I've written will ever even be seen by somebody that would understand what I was talking about. I only did the analysis after discovering that even when I was sure the script was working the way it was supposed to, I still couldn't get the right info into a pose for the EasyPose tube. It has exactly the sort of set-up I describe above, except that there are 47 intermediate SubMasters between the master bendAll dial and the xrot in the last body part, so the effect is.....rather noticeable. I could have probably saved myself a lot of time by thinking this through properly at the start, but at least I've learned a lot about Python so if I think of other cool things I could do with a script it won't take me so long next time. I'd rather not go as far as having the script read the cr2. If I have to do that, I might as well have a separate utility written in VB, which I probably will do now that I know Poser Python isn't going to give me a decent solution. In the mean time, I'll set up my script to just write the effective parameter values into the pose and write the valueParms as zero. It's ugly and it won't work if the ERC is driven by anything other than a valueParm, but it will have to do for now. I'm really very dissapointed. I just couldn't believe it when I realised they hadn't provided any method for reading a user's dial settings. Sigh. I wonder whether I'll have any better luck with DAZ Studio when it comes out.


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


Ajax ( ) posted Mon, 25 August 2003 at 4:44 AM

BTW - thanks for all your help, Ockham. I've learned a lot from you while I've been working on this script.


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


ockham ( ) posted Mon, 25 August 2003 at 10:40 AM

I share your disappointment. I was hoping you could make this happen for Easy-Pose, because I'd really like to have a more flexible way to set up things like wires and blood vessels for my educational work. The basic settings on EP just aren't quite enough for that. Ideally, the user should be able to mark some control points with little props, and the EP would spline itself through those points. Random thought: would this be more workable if the EP was designed with only single-level ERC? Each piece controls only its immediate neighbors, no overall master or IK.

My python page
My ShareCG freebies


Ajax ( ) posted Mon, 25 August 2003 at 5:06 PM

Yes, if there were only one level of master-slave relationships it would be possible to get the saved poses right, but it would still take ages to tickle every dial and check to see which dials laugh. If you restricted it futher to only recognise valueParms as potential master dials you could make it workable. EasyPose always uses cascaded relationships though. You know, Bushi wrote a script that worked much like what you describe - you drew a spline in the interface and your figure posed itself to match the spline. I wonder what happened to that project. It looked really exiting. I don't know if he's still contactable but you might want to see if you can get hold of him. Maybe you could take over developement for the script.


View Ajax's Gallery - View Ajax's Freestuff - View Ajax's Store - Send Ajax a message


Privacy Notice

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.