Thu, Nov 28, 4:53 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: 2024 Sep 18 2:50 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: Copying materials


JohnRickardJR ( ) posted Fri, 04 February 2005 at 1:05 PM ยท edited Thu, 28 November 2024 at 4:49 PM

I'm sure I'm making a simple mistake, or underestimating the difficulty of the task. I'm trying to write a simple script to copy one material to another. To be precise, I want to write a script that copies the material from the skin to all other skin type materials, eventually to use with V3 and the skin node, but this version is meant to be for Posette. I get File "", line 6 SyntaxError: can't assign to function call whenever I run this script, or varients on it. import poser scene = poser.Scene() actor = scene.CurrentActor() actor.Material("lips") = actor.Material("skin") A search of this forum tells me that there is a way to copy one material to another without having to go through each setting in turn. Help!


duckmango ( ) posted Fri, 04 February 2005 at 4:22 PM

In terms of syntax, the problem with the line:
actor.Material("lips") = actor.Material("skin")

is that the left side of the assignment operator "=" needs to be a variable, not a function call. So, for example, the line could look like this instead:
mySkin = actor.Material("skin")

In terms of your project, I'm not aware of a way to copy material settings in python without going through the Diffuse, Ambient, Reflection, etc settings in turn. Hope someone else can help you out -- I'd be curious to see a shortcut myself.

BTW, are you referring to PP or P5? Because there's no direct python access to P5's material room. Good luck.


underdog ( ) posted Fri, 04 February 2005 at 5:30 PM

I see what you want to do, and it makes sense to try it that way.. essentially you are saying, "copy this 'skin' material object to this 'lips' material object..." but that dog don't hunt.

What you need to do instead is, as duckmango suggested, replace each of the parameters...

For example, I just posted a script that saves all of the transparency settings for a figure or prop to a data file and then set's those transparency settings to ZERO. On the second run it reads the saved file and restores the transparency settings. I used these lines...

material.SetTransparencyMax(0.0)<br></br>material.SetTransparencyMin(0.0)

...to set the transparency min and max to zero and similar code to restore it from the saved data.

That "material" variable came from...

  materials = actor.Materials()<br></br>  ...<br></br>  for material in materials:<br></br>    ...<br></br>    material.SetTransparencyMax(0.0)<br></br>    material.SetTransparencyMin(0.0)

Look for scripts that set all materials to white. There are at least a couple of those in the "Free Stuff" and they will iterate over all of the materials. However, those scripts don't change the prop's transparency or reflection, etc.. just the color. ===Underdog===


JohnRickardJR ( ) posted Fri, 04 February 2005 at 5:47 PM

Ah well. I was following up a search in here that had suggested it was possible to copy over an entire P5 material in Python - I've been playing with the skin node and was trying to find a way to avoid the repeated copy and paste in SkinHead, SkinTorse, SkinForarm, SkinArm etc. Not to mention the eye materials. Thanks for all for your help


JohnRickardJR ( ) posted Fri, 04 February 2005 at 6:32 PM

A quick followup question: If I do the mySkin = actor.Material("skin") line, what infomation do I copy into mySkin, and how do I access it or view it?


underdog ( ) posted Fri, 04 February 2005 at 9:41 PM

Ah geeze, there are a ton of them actually. Do you have a copy of the Poser Python docs? Sadly, they have turned off cut-and-paste, so I can't answer this easily without typing them all in.

Here are a few..

mat.AmbientColor()             # gets the ambient color<br></br>mat.SetAmbientColor(r, g, b)   # sets the ambient color<br></br>mat.BumpMapName()              # gets the bump map filename<br></br>mat.SetBumpMapName(fname)      # sets the bump map filename

I just tried downloading the PDF from curiouslabs.com again. These guys REALLY need to get over their copy-protection and email-spam fetish. They demanded my email address just to download documentation, and then they don't actually SEND me the link... I have tried before. Maybe it will show up soon. (grumble grumble)

You might try visiting curiouslabs.com and seeing if they let YOU download it (assuming you don't already have that manual, that is... it ships with poser 5 as I recall...)


JohnRickardJR ( ) posted Sat, 05 February 2005 at 2:46 AM

Yes, I've still got the pdf - thats where I got the original call from. I think I need to research more Python, but I all the guides I've seen say start from existing PoserPython scripts first, then work back to proper Python as it doesn't work in the same way. Would mySkin.SetBumpMapName(fname) change the skin (to use the example above? I was assuming that mySkin contained a copy of the material but I gather it contains a pointer to the original data instead, so mySkin.SetBumpMapName is a shortcut for poser.Scene.CurrentActor.Material("lips").SetBumpMapName or am I still barking up the wrong tree?


underdog ( ) posted Sat, 05 February 2005 at 11:27 AM ยท edited Sat, 05 February 2005 at 11:29 AM

Yes. "mySkin" is a reference to the actual material on that actor.

Put this another way. If you were to create a "mySkin2" using the same process and then you did:

  mySkin.SetBumpMapName("filename.bmp")<br></br>  print "bump=",mySkin2.BumpMapName()

... it would print... bump= filename.bmp

... since both "mySkin" and "mySkin2" are references to the same material object on the same actor.

But then again, I may not know what I am talking about! [GRIN]

===Underdog===

P.S. Please post any references you have handy. I am always looking for new material. Message edited on: 02/05/2005 11:29


face_off ( ) posted Sat, 05 February 2005 at 9:00 PM

John...are you trying to do this for P4 or P5? If P5, then I'm not aware of any way to directly copy one material to another, since the PoserPython library doesn't support the P5 Material Room. One way you could do it in P5 is to have the script save the scene and then extract the materials from the save file and construct a new mat pose which the script then applies to the figure. A tough script to write!

Creator of PoserPhysics
Creator of OctaneRender for Poser
Blog
Facebook


tromnek ( ) posted Tue, 08 February 2005 at 6:37 PM

I have a poser file parsing class that would take care of most of the hard work in the above suggestion.
The problem is when you create the temporary cr2 file it might be pretty big and take a while to write to disk.

Then I need to parse that big file which could take at least 30 seconds on a reasonable computer.

I could jump to the last Megabyte of the file and begin parsing there. Are the materials alwasy at the end of a cr2 file? Do you think using just the last Megabyte be safe?

Let me know what you all think, and I can probably code something this weekend.


face_off ( ) posted Wed, 09 February 2005 at 1:53 AM

Good question tromnek. It depends how many figures are in the scene. If there is more than one figure, then only reading the final 1 Meg might not work. You'd need to do some experimenting.

Creator of PoserPhysics
Creator of OctaneRender for Poser
Blog
Facebook


tromnek ( ) posted Thu, 10 February 2005 at 8:46 PM

file_180423.jpg

The baby took a long nap this afternoon so I could play.

Here is a beta. It should do what JohnRichardJR requested (and a little more). I think I will probably add to it someday so that you can extract and clone materials from an already existing .cr2 file or .pz2 file, but I have other projects I want to wrap up first.

Make sure you have a figure selected before you run it.
I really need to add a bunch of sanity checks to the code.


face_off ( ) posted Thu, 10 February 2005 at 11:25 PM

Wow - impressive Tromnek. I haven't got a chance to play with it in the short-term (heading away for a bit), but will have a look when I get back. Hopefully John will have had a chance to check it out by then.

Creator of PoserPhysics
Creator of OctaneRender for Poser
Blog
Facebook


JohnRickardJR ( ) posted Sun, 13 February 2005 at 7:52 AM

Sorry for the silence - I've been away from the internet for a week. This looks like it does exactly what I'm after, but when I run it I get the following error. Traceback (most recent call last): File "", line 577, in ? NameError: name 'MatCopyApp' is not define Poser 5, sr4, script moved into the Poserscript directory and a figure selected when I start it. What am I doing wrong?


tromnek ( ) posted Sun, 13 February 2005 at 8:54 AM

file_180424.jpg

My mistake, sorry. I renamed the app class from 'MatCopyApp' to 'MatCloneApp'. The old class name was still in the global namespace when I tested, so it didn't produce an error. I should 'Reinitialize Python' before final testing to avoid this kind of thing. Here's a new version. One change in line 577.


JohnRickardJR ( ) posted Sun, 13 February 2005 at 10:42 AM

Wow - almost exactly what I had in mind, just better and much more flexible. I'm going to spend some time looking through this to get an idea of how it all works. Very impressed to think that this is the work of an afternoon, never mind how long, and with a baby to distract! Many thanks for this - now time to go and play with the skin nodes again.


tromnek ( ) posted Sun, 13 February 2005 at 5:25 PM

In truth is was more than just a couple hours. Most of the work for parsing the files was already done in a previous class I created. I'm not so good with Tk/Tcl so it takes me a while to do the user interface. Which by the way has a flaw in the file save. I force the extension to be .pz2 (after the file save as dialog), so be careful. It would be best if you specify the .pz2 in the dialog. I'll fix this (add a warning) after I get some feed back.


JohnRickardJR ( ) posted Mon, 14 February 2005 at 2:45 AM

Ok. I'll keep an eye on that as I go along. One possible bug report - I get an error when I try to use the script in a scene with one V3 and two clothes. Exception in Tkinter callback Traceback (most recent call last): File "E:Program FilesCurious LabsPoser 5RuntimePythonliblib-tkTkinter.py", line 1292, in call return apply(self.func, args) File "", line 200, in handleGo TypeError: an integer is require Doesn't happen with just the single figure. Settings were to clone on the single figure only. and a suggestion/ request.. WOuld it be possible to add preset destination lists? A single button that would pick out all of the V3 skin body materials, head materials and eye materials etc?


tromnek ( ) posted Mon, 14 February 2005 at 8:46 AM

Bug: I bet that you were only processing the last 1MB of data (the default) and it didn't find the 'material'. I need to check whether the material was found and if not, prompt for a 'retry' letting the user pick a larger amount of data. Can you test again but select either 'Entire File' or a large number of megabytes? Also, check your 'temp' directory for any large .cr2 files that may have been left there when the script bombed. Suggestion/request: I figured that someone would ask for this. I'll think about a good solution. In the meantime, I'll try to make a special case for you. I work my day job on mon, tue and wend. I'll try to get to this on thursday (when the baby sleeps).


JohnRickardJR ( ) posted Mon, 14 February 2005 at 10:56 AM

Bug: Yup, that fixed it. Working perfectly with that scene now (shame Poser froze my computer while rendering - it tends to sulk if I swap away to something else while rendering) Suggestion/request: Actually, I was sort of edging towards having a bash at this myself as a Python learning experience. I was thinking adding a fourth selection box with a list of options, picking the options up from the script itself, allowing someone to add their own within the source rather than within the interface. Pick option off list, click on select this button and that updates the selection box or settings. If you have no objection, I'll have a bash at it over the weekend and get back to you with my efforts (if any)


tromnek ( ) posted Mon, 14 February 2005 at 2:52 PM

I have no problems with you modifying/fixing the code (and please do). In fact the license at the top of the script gives you that right (just make a brief note in the comments with the date about your changes). I'll try to get you a fixed version before the weekend. There are a number of things I need to fix (the file name thing, retry with larger data chunk and probably some others). Also, I need to move my support classes inside the body of my App class and eliminate some other global pollution.


JohnRickardJR ( ) posted Tue, 15 February 2005 at 12:23 PM

Progress report - I've now got the interface up and running and very nearly the actual implementation - just having a problem with variable typing, which I've now run out of time to deal with for now Should fix it in the morning


tromnek ( ) posted Tue, 15 February 2005 at 8:51 PM

file_180425.jpg

great. Here is an update on my side, I think I fixed most of it. It got somewhat reorganized, if you need help merging this with your work let me know. Another thing that would be nice is a couple drop-down lists above the 'Source' and 'Destination' list boxes that would let you choose figures for the corresponding materials.


JohnRickardJR ( ) posted Wed, 16 February 2005 at 4:13 AM

Ok, done and updated, although it doesn't fit with the new look yet. Next question, how do I go about posting it?


tromnek ( ) posted Wed, 16 February 2005 at 7:25 AM

Save a copy of it with a '.txt' extension. Then post a message to this thread and use Attach File: -> Browse to select the '.txt' file. Then it will appear as a link in the new message.


JohnRickardJR ( ) posted Wed, 16 February 2005 at 10:00 AM

file_180426.jpg

Here it is - the presets are defined at the bottom of the code. TO add a new preset, increase the count by one and add eleven more items to the list, with the preset name in the first one.


JohnRickardJR ( ) posted Wed, 16 February 2005 at 10:00 AM

file_180427.jpg

Here it is - the presets are defined at the bottom of the code. TO add a new preset, increase the count by one and add eleven more items to the list, with the preset name in the first one.


tromnek ( ) posted Thu, 17 February 2005 at 8:36 PM

Works great.
(but I think you have a couple of typos in your 'prelist' list)

There is another bug in my code. We need to add

self.Update()

around line 347, right after del MatExtract

btw,
Is 11 slots for materials enough for the common/typical figures?


JohnRickardJR ( ) posted Fri, 18 February 2005 at 3:38 AM

The prelist list I put in place was just a quick test list. I picked 11 because that gives a nice round number - 10 materials plus the name, but that size can easily be increased. Also, there are nine body skin materials on V3, and ten on Aiko. Is there any way to create two dimensional list arrays in Python? If there is, the code could be made much neater, and the size limit made user changable.


JohnRickardJR ( ) posted Fri, 18 February 2005 at 4:08 AM

file_180428.jpg

Found the answer to my own question In this version the individual lists are stored seperatly, then combined in a single list. The presize variable controls all size functions in the code, so if you want to change the size of the lists to 20 set presize to 21 (20 mats plus the list name). The rest of the code now appears to work, and I've added in the correct lists for V3 skins and heads (or at least the ones I wanted to use) Also added the self.Update() as above


tromnek ( ) posted Fri, 18 February 2005 at 10:01 AM

We could easily make the number of lists and the number of elements in each list totally arbitrary. This would make it easy to let the user define and add a new preset based on what they have currently selected in the 'Destination' frame. I'll look into it when I get a chance. Here is a rough idea using a dictionary whose values are lists.

presets = { 'All On'       : () ,<br></br>          { 'All Off'      : () ,<br></br>          { 'All Toggle'   : () ,<br></br>            'v3 body skin' : ('SkinTorso','SkinNeck','SkinHip','SkinFeet','SkinLeg','SkinArm','SkinHand') ,<br></br>            'v3 skin head' : ('SkinHead','SkinScalp'),<br></br>            'posette bits' : ('nipple','lips')<br></br>          }

then to populate the list box widget,

for ps in presets.keys():<br></br>  self.psetMAT.insert(Tkinter.END, ps)

then to process it, something like this def handleset(self):
for thisPS in self.psetMAT.curselection():
if self.psetMAT.get(thisPS) == 'All On':
self.DstMAT.select_set(0, Tkinter.END)
elif self.psetMAT.get(thisPS) == 'All Off':
self.DstMAT.select_clear()
elif self.psetMAT.get(thisPS) == 'All Toggle':
for thisMATndx in range( self.DstMAT.size() ):
# Some toggle code for each thing
else:
for thisMATndx in range( self.DstMAT.size() ):
if self.DstMAT.get(thisMATndx) in presets[self.psetMAT.get(thisPS)]:
self.DstMAT.select_set(thisMATndx)

I'll check this idea when I get a chance later.
What do you think?


tromnek ( ) posted Fri, 18 February 2005 at 10:41 AM ยท edited Fri, 18 February 2005 at 10:42 AM

oops, the presets has some extra open braces, here's the correct syntax.

presets = { 'All On'       : (),<br></br>            'All Off'      : (),<br></br>            'All Toggle'   : (),<br></br>            'v3 body skin' : ('SkinTorso','SkinNeck','SkinHip','SkinFeet','SkinLeg','SkinArm','SkinHand'),<br></br>            'v3 skin head' : ('SkinHead','SkinScalp'),<br></br>            'posette bits' : ('nipple','lips')<br></br>          }

Message edited on: 02/18/2005 10:42


JohnRickardJR ( ) posted Fri, 18 February 2005 at 11:22 AM

Looks elegent. Covers areas of Python I haven't had a look at yet - dictionaries in particular. Must look further into it.


tromnek ( ) posted Fri, 18 February 2005 at 10:33 PM

file_180430.jpg

Here's a version that seems to work well. I moved your preset frame over next to the destination frame. I also reorganized the buttons a little.

This version now creates a visible instance variable for the application.

#MatCloneApp(Tkinter.Tk(), '').master.mainloop()<br></br>matcloneapp = MatCloneApp(Tkinter.Tk(), '')<br></br><br></br>matcloneapp.addpreset( 'v3 body skin', ('SkinTorso','SkinNeck','SkinArm','SkinHand') )<br></br>matcloneapp.addpreset( 'v3 skin head', ('SkinHead','SkinScalp') )<br></br><br></br>matcloneapp.master.mainloop()

Notice the new class method addpreset().
This has the added effect that you can run another python script (while this one is running) that looks like this.

# Posette Bits preset<br></br>try:<br></br>  matcloneapp.addpreset( 'posette bits', ('nostril','lips') )<br></br>except:<br></br>  pass<br></br># comment line, so we don't end the script on an indented line.

and this preset will be added to the preset listbox.
This seems pretty flexible.


dlfurman ( ) posted Wed, 09 March 2005 at 4:38 PM

-*- Bookmarking

"Few are agreeable in conversation, because each thinks more of what he intends to say than that of what others are saying, and listens no more when he himself has a chance to speak." - Francois de la Rochefoucauld

Intel Core i7 920, 24GB RAM, GeForce GTX 1050 4GB video, 6TB HDD space
Poser 12: Inches (Poser(PC) user since 1 and the floppies/manual to prove it!)


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.