Forum Moderators: Staff
Poser Python Scripting F.A.Q (Last Updated: 2024 Sep 18 2:50 am)
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.
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===
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
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...)
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?
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
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
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.
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
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.
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
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?
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.
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.
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?
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).
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)
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.
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.
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?
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
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.
-*- 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!)
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.
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!