3dcheapskate opened this issue on Mar 01, 2012 · 18 posts
3dcheapskate posted Thu, 01 March 2012 at 2:51 AM
Okay, here's my first stab at the script. I adopted the monolithic one-size-fits-all approach. It uses one AskMenu() and makes copious use of the DialogSimple MessageBox() and YesNo() methods to give a reasonable amount of flexibility. Here's an overview of what it does:
If you have a figure selected it asks if you want to change all the materials in that figure.
If not (or you say no), and you have an actor selected it asks if you want to change all materials in that actor.
If not (or you say no), and you have a material selected it asks if you want to change that material.
If it has got a material list, then it asks if you want to set a fixed tiling value, or adjust the current value by a percentage.
It asks for confirmation if you enter values that are likely to be mistakes.
It then states what it's about to do, and asks for confirmation.
If there's more than one material it gives you the option to select yes/no to each material individually.
Here's the main code (functions GetTilingPercent() and GetTilingPercent() in the following posts).
Any advice, suggestions, and constructive criticism much appreciated:
import poser
# function defs here
try:
True, False
except NameError:
(True, False) = (1, 0)
aborted = False
fig = poser.Scene().CurrentFigure()
act = poser.Scene().CurrentActor()
mat = poser.Scene().CurrentMaterial()
if fig:
yn = poser.DialogSimple.YesNo(" Current Figure: "+str(fig.Name())+"nnChange all materials for this figure?")
if yn == 0:
fig = None
else:
mats = fig.Materials()
if act and not fig:
yn = poser.DialogSimple.YesNo(" Current Actor: "+str(act.Name())+"nnChange all materials for this actor?")
if yn == 0:
act = None
else:
mats = act.Materials()
if mat and not act:
yn = poser.DialogSimple.YesNo(" Current Material: "+str(mat.Name())+"nnChange this material?")
if yn == 0:
act = None
else:
mats = [mat]
if not mat:
poser.DialogSimple.MessageBox("Please select a figure, actor, or material first!")
if mats:
optlist = ("Adjust tiling by xxx%","Set tiling to xxx")
action = poser.DialogSimple.AskMenu("Change Tiling (U/V_Scale)","Method?",optlist)
if action == optlist[0]:
tp = GetTilingPercent()
yn = poser.DialogSimple.YesNo("U_Scale and V_Scale will be set to "+str(tp)+"% of their current values.nnYes to proceed, No to cancel")
if yn == 0:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
else:
bypc = True
elif action == optlist[1]:
tv = GetTilingValue()
yn = poser.DialogSimple.YesNo("U_Scale and V_Scale will be set to "+str(tv)+".nnYes to proceed, No to cancel")
if yn == 0:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
else:
bypc = False
else:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
if not aborted:
interactive = False
cnt = 0
yn = poser.DialogSimple.YesNo("There are "+str(len(mats))+" materials.nWould you like to confirm each material individually?")
if yn != 0:
interactive = True
for mat in mats:
cnt = cnt+1
changemat = True
if interactive:
yn = poser.DialogSimple.YesNo("Material: "+mat.Name()+"n(Material "+str(cnt)+" of "+str(len(mats))+")nnChange this material?")
if yn == 0:
changemat = False
if changemat:
tree = mat.ShaderTree()
nods = tree.Nodes()
for nod in nods:
if nod.Type() == poser.kNodeTypeCodeIMAGEMAP:
if bypc:
nv = nod.Input(2).Value() * tp / 100.0
nod.Input(2).SetFloat(nv)
nv = nod.Input(3).Value() * tp / 100.0
nod.Input(3).SetFloat(nv)
else:
nod.Input(2).SetFloat(tv)
nod.Input(3).SetFloat(tv)
tree.UpdatePreview()
Like I said - any advice, suggestions, and constructive criticism much appreciated.
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
3dcheapskate posted Thu, 01 March 2012 at 2:51 AM
def GetTilingPercent():
global aborted
tp = poser.DialogSimple.AskInt("Enter the percentage you want to scale by.n(Integer values only, no % sign)")
if tp is None:
poser.DialogSimple.MessageBox("Invalid entry (or user cancelled)nnOperation cancelled.")
aborted = True
return 0
if tp == 0:
yn = poser.DialogSimple.YesNo("Zero will turn off tiling?nnDid you intend to do this?")
if yn == 0:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
return 0
else:
return 0
if tp == 100:
poser.DialogSimple.MessageBox("A value of 100% will have no effect.n(makes the tiles exactly the same size)nnOperation cancelled.")
aborted = True
return 0
if tp yn = poser.DialogSimple.YesNo("Negative values ("+str(tp) + "%) invert the texture.nnDid you intend to do this?")
if yn == 0:
poser.DialogSimple.MessageBox("Ignoring the minus sign.n Proceeding with "+str(-tp) + "%")
tp = -tp
if tp > 1000 or tp yn = poser.DialogSimple.YesNo(str(tp)+"% will make the tiles "+str(tp/100)+" times bigger.nnDid you intend to do this?")
if yn == 0:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
return 0
elif (tp 0) or (tp >-10 and tp yn = poser.DialogSimple.YesNo(str(tp)+"% will make the tiles "+str(100/tp)+" times smaller?.nnDid you intend to do this?")
if yn == 0:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
return 0
else:
return tp
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
3dcheapskate posted Thu, 01 March 2012 at 2:52 AM
def GetTilingValue():
global aborted
tv = poser.DialogSimple.AskFloat("Enter the tiling value to set.n(Numeric values only)")
if tv is None:
poser.DialogSimple.MessageBox("Invalid entry (or user cancelled)nnOperation cancelled.")
aborted = True
return 0.0
if tv == 0.0:
yn = poser.DialogSimple.YesNo("Zero will turn off tiling?nnDid you intend to do this?")
if yn == 0:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
return 0.0
else:
return 0.0
if tv yn = poser.DialogSimple.YesNo("Negative values ("+str(tv) + "%) invert the texture.nnDid you intend to do this?")
if yn == 0:
poser.DialogSimple.MessageBox("Ignoring the minus sign.n Proceeding with "+str(-tv) + "%")
tv = -tv
if tv > 100.0 or tv yn = poser.DialogSimple.YesNo(str(tv)+"% will make the tiles "+str(tv/100)+" times bigger.nnDid you intend to do this?")
if yn == 0:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
return 0.0
elif (tv 0) or (tv >-0.01 and tv yn = poser.DialogSimple.YesNo(str(tv)+"% will make the tiles "+str(100/tv)+" times smaller?.nnDid you intend to do this?")
if yn == 0:
poser.DialogSimple.MessageBox("Operation cancelled.")
aborted = True
return 0.0
else:
return tv
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
3dcheapskate posted Thu, 01 March 2012 at 2:54 AM
Hmmm... not sure that was the best way to post it, with all the line-wrapping. Maybe I should have done it as an attachment?
Anyway, as I said earlier, any advice, suggestions, and constructive criticism much appreciated.
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
ElZagna posted Thu, 01 March 2012 at 5:58 AM
Well, here's my suggestion, and it's the same suggestion I offer to almost every Poser script out there. Tell us what its purpose is. You've told us what it does - it sets the U/V_Scale of image maps in the current figure/actor - but that's a different thing from what its purpose is. What problem does it solve? In MBA parlance, what pain does it address? Why would someone want to use it?
There was an old Saturday Night Live skit that started with, "How many times have you coughed up a piece of lung and had no place to store it?" (It was a commercial for Playmate coolers.) A silly example, I guess, but that's how products are sold. You don't sell coolers by saying, "Playmate coolers insulate their contents by surrounding it with materials that don't allow the heat exchange... " You start with some kind of "don't you hate it when" statement.
I know I'm going on and on about this, but I see so many scripts out there that someone has put hours and hours into, but they never get used because the potential users have no clue as to why they would want to use them.
Sorry I can't be more helpful about the script per se. It looks impressive, though.
OS: Windows 10 64-bit, Poser: 10
3dcheapskate posted Thu, 01 March 2012 at 7:23 AM
Very sensible advice. Thanks. I think we get so involved in what we're doing that we forget the obvious. So here's what I should have said at the top:
This script makes it much easier to adjust the size of my tileable mail textures (in the Renderosity Freestuff here) to suit the item it's applied to. It should also be suitable for adjusting any texture that uses a tiled image map. Or to follow on from that Saturday Night Live sketch - "Don't you just hate it when that ballista bolt goes straight through the holes in your chain mail? You should have been using smaller links - if only you'd had this handy little Tile-O-Matic script!"
I had been trying to do this with a Poser 5 material file, but advice in this thread pointed me to Python, and once I'd got the script more-or-less ready I moved to this thread you're looking at (but forgot to point back to the original thread).
It's my first ever Python script, which is the main reason I've asked for comments. I'm still debugging it, but I posted it since it seems to work 99% as intended (testing in Poser 6 on Windows 7).
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
ElZagna posted Thu, 01 March 2012 at 9:11 AM
You got it! I see that you're obviously no stranger to the concept. From your "Miscellaneous Positional Reset Poses"
Do you ever make a complete mess of posing a figure, and need to start again?
Do you have to spend ages hunting around for a pose to reset the figure?
Simple solution - put all your figure reset poses in one easy-to-locate folder!
OS: Windows 10 64-bit, Poser: 10
ElZagna posted Thu, 01 March 2012 at 9:23 AM
Another thing I like about your comments for your Reset Poses script is that you address the issue of obsolescence. It would be nice if all scripts indicated if subsequent releases of Poser had made the script obsolete. I spent a lot of time once trying to get a script to work, and finally asked the author what I was doing wrong. He said, “That old thing? Forget it. Poser does that natively now.”
OS: Windows 10 64-bit, Poser: 10
3dcheapskate posted Fri, 02 March 2012 at 12:06 PM
Actually the "Miscellaneous Positional Reset Poses" are just that, .pz2 pose files. But your comments are just as valid nevertheless.
I'm going to upload the script to the Renderosity Freestuff as soon as I'm happy with it - I'm not sure how long to wait to see if anybody comments on the script itself. I've already fixed a couple of bugs, but one I'm not sure how to handle - the line...
mats = act.Materials()
...(around the 22nd code line in the first post) errors if you have, say, just a camera in the scene as the selected actor. I could use an
if not act.IsCamera():
but I wonder what other actors will cause similar problems?
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
markschum posted Fri, 02 March 2012 at 10:40 PM
you can do an
if mats:
# do stuff
that will skip if the actor has no materials.
3dcheapskate posted Sat, 03 March 2012 at 4:51 AM
It's an odd one, cos I already use an 'if mats:'. I stuck a message box either side of it like this.
poser.DialogSimple.MessageBox("Gonna do 'if mats'")
if mats:
poser.DialogSimple.MessageBox("Done 'if mats'")
When I run the script the first message box (Gonna do 'if mats') appears, but then I get the Python print window with this
poser.error: Actor has no available material
I'm puzzled - the whole purpose of the 'if mats:' is to check for this. Still trying to make sense of this.
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
3dcheapskate posted Sat, 03 March 2012 at 6:30 AM
I've cut the script down to just a few lines to try and get to the bottom of this:
import poser
fig = poser.Scene().CurrentFigure()
act = poser.Scene().CurrentActor()
mat = poser.Scene().CurrentMaterial()
mats=[]
if act and not fig:
yn = poser.DialogSimple.YesNo(" Current Actor: "+str(act.Name())+"nnChange all materials for this actor?")
if yn == 0:
act = None
else:
mats = act.Materials()
poser.DialogSimple.MessageBox("Check 'if mats is None'")
if mats is None:
poser.DialogSimple.MessageBox("mats is None")
else:
poser.DialogSimple.MessageBox("Done 'if mats'")
I start Poser 6 from scratch with just the default ground, cameras and lights. The Main Camera is selected by default. I run the script either from an mt5 with just a 'runPythonScript' line or direct from File > Run Python Script, makes no difference. I get the "Check 'if mats is None'" and "mats is None" messages, and then this:
poser.error: Actor has no available materials
It's definitely the highlighted mats = act.Materials() that's causing it. If I change that line to mats = None then the poser.error doesn't occur.
Seems that I'll have to avoid calling the Materials() method if the actor doesn't have any materials. Anybody have any other thoughts on this?
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
adp001 posted Sat, 03 March 2012 at 11:11 AM
Wrap the material check with try/except. try: mat = actor.Materials() except poser.error: mat = None
3dcheapskate posted Sat, 03 March 2012 at 8:04 PM
No joy, tried that already - same problem! Just to be sure I edited the cut-down script from the previous post...
import poser
fig = poser.Scene().CurrentFigure()
act = poser.Scene().CurrentActor()
mat = poser.Scene().CurrentMaterial()
mats=[] # It was picking up previous mats?
if act and not fig:
yn = poser.DialogSimple.YesNo(" Current Actor: "+str(act.Name())+"nnChange all materials for this actor?")
if yn == 0:
act = None
else:
try:
** mats = act.Materials()**
** except poser.error:**
** poser.DialogSimple.MessageBox("error")**
** mats = None**
poser.DialogSimple.MessageBox("Check if mats is None")
if mats is None:
poser.DialogSimple.MessageBox("mats is None")
else:
poser.DialogSimple.MessageBox("mats isn't None")
...sure enough, same problem. Note: the 'except' doesn't catch it either - I don't get the "error" message box. Curiouser and curiouser.
But like I said before, I can work round the problem with this:
if not act.IsCamera():
mats = act.Materials()
else:
mats = None
That works. What puzzles me most is that the error doesn't show up until the end of the script. It would be nice (but not essential) to know what the heck is going on here!
(by the way, I'm using Poser 6. Is this just a Poser 6 issue? Can Somebody check the problem in Poser 7/8/9? Just run the cut-down script from my previous posts with no figure in the scene and the Main Camera selected.)
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
adp001 posted Mon, 05 March 2012 at 4:28 AM
If I open a Python-Shell in Poser (2012) and execute: sc=poser.Scene() type(sc.Cameras()[0].Materials()) The answer is: type 'NoneType' No error-message. So the result is just None.
3dcheapskate posted Tue, 06 March 2012 at 9:07 AM
Anyway, just uploaded the script to the Renderosity Freestuff - should be appearing there soon. Here's the first of two images to help people who want to try it out.
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
3dcheapskate posted Tue, 06 March 2012 at 9:08 AM
The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
*also available in ShareCG, DAZ, and HiveWire3D flavours (the DeviantArt and CGBytes flavour have been discontinued).
nruddock posted Tue, 06 March 2012 at 1:25 PM
The message you posted isn't an error (it's clearly not a stack trace) but a warning/informational one (it could even be debugging output left in the release) so it's not surprising that the try ... except isn't catching anything because no exception is being thrown.