Loading...
14 April, 2013#

Photoshop Script: sr_SaveGroup

I’ve written a few handy photoshop scripts over the years and never got around to sharing them so I will try here and there.

I’ve used this, or variations of this script for years. To save out the various types of textures from one PSD, Diffuse, Glossiness, Bump, Specular, Reflection, Refraction Etc.

When you run the script it will save out a jpg based on the name of the PSD file and the GROUP you have selected.

Usage

Robot.psd
Using groups like the example below. Running the script with the ‘Diffuse’ group selected will save out ‘Robot_Diffuse.jpg’ in the same location as the PSD file.

Also if there is a ‘Wire’ or ‘Wireframe’ layer at the top, it will be temporarily hidden during save.

Installation

Copy the script file into [photoshop install dir]/Presets/Scripts/ folder/.
And it will appear in File>Scripts -I’d recommend making a shortcut for it too from there.

Download

Sr SaveGroup
Sr SaveGroup
sr_SaveGroup_v1.0.jsx
Version: 1.0
1.5 KiB
24 Downloads
Details...

 

27 June, 2012#

3ds Max Maxscript Help: Snippets

Here is a list of practical examples for the syntax of scripting in 3ds Max with it’s internal language, maxscript. This isn’t a tutorial and HOWTO script, but more of a reference of how to format commands.

I’ll continue to update this post as I go on as it’s a resource for me as much as anyone else, let me know if there are any useful additions!

Note also that the indenting isn’t necessary but I think it’s a good habit (and I mostly use Python which requires it)

Arrays

/* Create an array */
oFruitArray = #("Apple","Orange")
 
/* Append to an array */ 
append oFruitArray "Banana"
 
/* Loop through an array */
for oFruit in oFruitArray do
(
	print oFruit
)
 
/* Arrays start from 1 in maxscript */
print oFruitArray[1] -- returns "Apple"

Strings

/* Substring - cut characters from a string */
oString = "String"
substring oString 2 3 
/* returns "tri" */
 
-- It's often useful to remove extensions
oFile = maxFileName
oFileNoExt = substring maxFileName 1 (oFile.count-4)

Scene

/* Scene Path (read only)*/
oFilePath = maxFilePath
/* Scene Filename (read only) */
oFileName = maxFileName
/* Render Ouput File Name */
rendOutputFilename = "C:/Renders/Render.exr"

Objects

/* 	lists all the properties of the object, very useful  */
showProperies $
 
/* Selected objects */
$
 
/* Check the type/class of an object */
classof $
 
/* Change radius of selected spheres */
$.radius = 10
 
/* Selection FOR loop */
for oObj in $ do
(
	print oObj
)
 
/* Another method */
for obj in selection do
(
	print oObj
)

Modifiers

/* Accessing noise controller on a modifier */
$.Bend.BendAngle.controller.seed = 541274
 
-- Create an empty array
oDisplaceExists = #()
 
-- For loop through selected objects
for oObj in $ do
(
	-- Get the top modifier
	oMod = oObj.modifiers[1] 
	-- Get the class of the modifier
	oModClass = classof oMod
	if (oModClass == VRayDisplacementMod) then
	(
		/* Append to an array */ 
		append oDisplaceExists oObj
		print (oObj.name + " doesn't have a vray disp")
	)
	else
	(
		print (oObj.name + " has a vray disp")
	)
)
 
-- For loop for those with a vray disp modifier on top
for oArrayObj in oDisplaceExists do
(
	print oArrayObj.name
)

Interaction

/* Message box to give user some info */
messageBox "Asset name field is empty! Not saving.."

Macroscript loader

Useful to load at startup, points at an updateable script

macroScript AnalogSave
	category:"Lemongood"
	toolTip:"LemonSave"
(
	filein "\\\\Server\\share\\Workgroups\\3dsMax_Workgroup\\MACROS\\LemonSave_v1.01.mcr"
)

Misc

/* Random */
random 1 99999
 
/* Create a box at every position of selected objects */
 
for oObj in $ do
(
	oPosition = oObj.pos
	oCreateBox = Box pos: oPosition
)
 
/* try catch to pick up errors */
oName = "Hello"
 
try
(
	oName = (oJobIndex as integer)
)
catch
(	
)
 
/* Loop through all the RPManager controls */
for i=1 to 90 do
(
	oNum = i as string
	ooP = (oNum + ": ")
	vals = rpmdata.RMGetValues i 1
	valsstring = vals as string
	print (ooP + valsstring)
)

System access

In windows…

/* Get user or computer name */
sysInfo.username
sysInfo.computername
 
/* Get local time and date */
localTime
-- returns "13/07/2012 14:33:11"
 
/* Recursively create directories*/
makedir ("c:/whatever"))	
 
/* Create a text file and write a line to it */
oFilePath = "C:/Hello.txt"
oTextFile = createFile oFilePath
 
/* Open the file for editting */
oOpenTextFile = openFile oFilePath mode:"at"
 
	/* Write a line to the text file*/	
	oWriteLine = "This is a line in a text file"
	format "%\n" oWriteLine to:oOpenTextFile
 
/* Close the file */
close oOpenTextFile
close oTextFile
 
/* Open that text file and read the line */
oOpenTextFile = openFile oFilePath mode:"r"
	oReadLine = readLine oOpenTextFile
close(oOpenTextFile)
21 June, 2012#

LemonRender – Batch Renderer

As a Softimage user, I’m not given any kind of render manager software like the straight forward but useful application that is backburner. I’ve worked at many studios and used many render farms (including backburner) but some of the main ones are Royal Render, Deadline . Anyway these ones are can be quite complex, and if you start beta testing a renderer like VRay in Softimage, you can come up against issues. I’ve now found that while I wait for a new version of Deadline, Softimage 2013 isn’t supported either….. So I’ve gone back to using this wee batch rendering system I made last year.

It involves only a few elements:

  • a plugin/submitter for Softimage
  • a batch file that runs…..
  • the main Lemon Render Python script
  • a simple web interface (run by a simple web server)
From this though, I can print logs of my renders to see how long they have been taking, and queue up jobs. These are all just stored (from the submitter) in simple text files which I can later alter/delete etc.
At the moment there is no priority,  the only thing a user can do is pause jobs in the queue.
I’m sure I could easily write plugins for Maya/Max/Nuke too but have never gotten around to it.
If there is any interest in it then I may do so!

lightbox

20 June, 2012#

Fix My Pen – Wacom Windows 7 Issues

This tool makes life much easier while using a wacom and Windows 7. Simple.

http://viziblr.com/news/2011/8/13/fix-my-pen-makes-your-wacom-tablet-just-work-on-windows-7.html

26 October, 2011#

Softimage XSI Custom Menu

The easiest way to access your own, or third party scripts from the UI in Softimage XSI is creating a toolbar. With these you can simple drag & drop text from the script editor onto your own toolbar, then save that in your user or workgroup folders.
That is fine, but they don’t really have place to dock them to the layout.

Instead of that, my much preferred way is to create your own custom menu in the menu bar.

I recall not really finding much information of how to make these custom menus for XSI, the help file has never really provided much information, but the best way to start usually would be to make a custom property from the wizard.
Animate > Create > Parameter > Custom Property Wizard

This isn’t specifically for making a menu, but it creates a plugin script that you can then open and it may help you understand some of the concepts associated with a plugin.

(as it says in the old/not amazingly useful wiki here: http://softimage.wiki.softimage.com/index.php/Custom_Menus).

So to save you all that trouble, here is a basic custom menu template that you can easily use and adopt for your own menus.

The following code should be saved as a Python file (.py) in the Application/Data/Plugins directory.
I would always recommend creating your own workgroup which is software version independent, and others can connect to (potentially very useful for a custom menu where you might be sharing studio tools on a server)

sr_Example_menu_v1.0.py

You will see I have saved the version on the script file which aligns with the versioning in the script:

in_reg.Major = 1
in_reg.Minor = 0

If you use these, XSI will always load the latest version.

I have commented in the example script where you should insert your own code – but if you use as is, it should display the example menu correctly.

# ############################################################
# sr_Example_Menu
#
# www.simonreeves.com
# simon@simonreeves.com
# 26/09/2011
# ############################################################
 
import win32com.client
from win32com.client import constants
 
# ############################################################
# On startup
 
def XSILoadPlugin( in_reg ):
	# the basic info goes here, self explanatory, author name/email etc.
	in_reg.Author = "simonr"
	in_reg.Name = "sr_Example_Menu"
	in_reg.Email = "simon@simonreeves.com"
	in_reg.URL = "http://www.simonreeves.com"
	# XSI will automatically look for the higer version number so this is good to use.
	in_reg.Major = 1
	in_reg.Minor = 0
 
	# Register Menus
 
	# Here we register the menu's to be used in this plugin by any of the scripts, "constants.siMenuMainTopLevelID" creates a menu bar item
	# They need to be labelled so you can reference that name later in this example: "sr_Example"
	in_reg.RegisterMenu(constants.siMenuMainTopLevelID,"sr_Example", False, False)
	# or else you can pick a menu that already exists, search for siMenuAnchorPoints in the SDK help to find all the menus you can attch your scripts to
	in_reg.RegisterMenu(constants.siMenuTbRenderPassPartitionID, "sr_ExamplePartitionMenu",False,False)
 
	# Register Commands
	# Next we register the scripts/commands that will be used - the order doesn't matter here, neither does the menu as the commands can be placed onto various menus.
	in_reg.RegisterCommand("ExampleScript1","ExampleScript1")
	in_reg.RegisterCommand("ExampleScript2","ExampleScript2")
 
	return True
 
# ############################################################
# Add commands to menus
 
# Next we add the COMMANDS on to the MENUS were just registed in the correct order.
# The def starts with the menu "sr_Example" suffixed with "_Init"
 
def sr_Example_Init( in_ctxt ):
 
	oMenu = in_ctxt.Source
 
	# This line adds each command as a simple item, the first paramater is the label, the second is command name we registered.
	oMenu.AddCommandItem("ExampleScript1","ExampleScript1")
 
	# Add a seperator
	oMenu.AddSeparatorItem()
 
	# Add a SubMenu and a command to it
	oExampleSubmenu = oMenu.AddSubMenu("SubMenu")
	oExampleSubmenu.AddCommandItem("ExampleScript2","ExampleScript2")
 
	return True
 
def sr_ExamplePartitionMenu_Init( in_ctxt ):
 
	oMenu = in_ctxt.Source
 
	# This line adds each command as a simple item, the first paramater is the label, the second is command name we registered.
	oMenu.AddCommandItem("ExampleScript1","ExampleScript1")
 
	# Add a seperator
	oMenu.AddSeparatorItem()
 
	# Add a SubMenu and a command to it
	oExampleSubmenu = oMenu.AddSubMenu("SubMenu")
	oExampleSubmenu.AddCommandItem("ExampleScript2","ExampleScript2")
 
	return True	
 
# ############################################################	
# Command Scripts
 
# Now we associate the commands that have been registered with actual scripts
# Again the defs for the COMMANDS are run with a suffix, this time of "Execute"
 
def ExampleScript1_Execute():
	print "ExampleScript1!"
	return
 
def ExampleScript2_Execute():
	print "ExampleScript2!"
	return

I’m sure I had some good help/spying at their menus from Juan Brockhaus (nice website link I found here for him), Andy Nicholas and Peter Agg over the last couple of years in this area to thanks to them!

If you have any comments then ask below!

26 September, 2011#

Nuke Custom Scripts Folder

Keeping custom stuff (scripts/menus/gizmos etc.) outside of an application’s own folder and into a custom folder such as on a server is useful for keeping your things organised, and potentially VERY importaly sharing between more than one user in a work environment.

Also I find it’s useful for backing up, instead of having to go and find lots of different application folders you need to keep, you can keep them all on the server.
I’ll probably use the ‘Workgroup’ quite often as that’s what it’s called in XSI, which is set up really well for this kind of business.

So for Nuke there is a ‘init.py’ file that you can add paths to that nuke will check for scripts.
I’m not going to go into any great detail what it is for, but just what is needed to achieve the point of the post.

In windows, it’s in a folder like this (depending on Nuke version)

C:\Program Files\Nuke6.0v2\plugins\init.py

Instead of adding to that file, you can create your own blank ‘init.py’ script in your user folder, this is much cleaner and is independent of Nuke versions.
You should create the file in a path similar to this:

C:\Users\Simon Reeves\.nuke\init.py

Inside the file, all you need to do is add one line, telling Nuke where to pick up the scripts. Be careful to use ‘/’ instead of window’s ‘\’ which causes potential conflicts:

nuke.pluginAddPath("Z:/Nuke_Workgroup", addToSysPath=True)

In my Nuke workgroup folder I have a few scripts which I’ll detail in a differnet post.
Namely there is:

  • menu.py – A custom menu in the menu bar.
  • sr_Scripts.py – Contains my custom scripts which the menu references
19 August, 2011#

I made this script when I discovered a decent way to clean a curve so that I could make a bike chain in ICE. There is an operator called ‘reparametrize’ but that doesn’t do the job fully.
Also I have attached my ICE Compound to distribute points along a curve but that’s not entirely what this is about in case that has problems :)

Note:
For CLOSED curves this seems to be working very well, OPEN curves are more trouble but I added something in so the script will close it for you and you have to do some manual work after.
All is explained in the video above!

Installation:
If you don’t have a Workgroup outside of the installation dir and your user (which changes every version of XSI) then I would recomment creating one.

For any of those options, the “sr_CleanCurve” python script should be extracted to:
\XSI_Workgroup\Application\Plugins\
And “sr_DistributePointsOnCurve.1.4.xsicompound” goes into:
\XSI_Workgroup\Data\Compounds\ (create this folder if it doesn’t exist)

Please ask any questions here, also try me on twitter.