Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Sunday, 5 June 2016

Python in Maya: Simple node sorting

When applying a worldspace or relative transform to nodes in Maya, you'll often have to account for;
  1. Control behaviour type (IK, Pole Vectors etc)
  2. Control hierarchy
This is where you will probably need to look at sorting your list of nodes prior to applying the data.
Also, space-switch sorting will want to be run as an additional pass over control type and hierarchy. This dependency check will vary based on the type of space-switch setup the rigs are using.

I've added a simple sort setup with individual and combined priorities.
Edit: Enable web view if browsing on mobile.


I'd love to hear your thoughts and how you approach this task.

Sunday, 26 August 2012

[Maya][Python] Querying soft selection

Handy little script modified from here to query and select the soft selection influenced components.


This one instead returns the influenced objects. Great for quickly querying the objects within a specific distance of another object.

Friday, 13 April 2012

Script: ld_selectMe (v2)

Re-wrote my free selection-set creation script, 'ld_selectMe' in python.
Updates include a more dynamic UI, faster set creation and overall, a much better write of the actual selection script, allowing the same functionality but only much, much faster than its mel counterpart.

You can download the re-write for free here (mediafire.com)
or creativecrash here.

Any comments/suggestions welcome.

Friday, 30 March 2012

Python: Writing nested dictionaries to file

Best suggestion I could think of was using cPickle (if available).
try:
    import cPickle as pickle
except:
    import pickle

# nested DICTIONARY
data = { 'one': {'label': 'This is shot 001', 'start': 1, 'end': 10},
         'two': {'label': 'This is shot 002', 'start': 11, 'end': 25},
         'three': {'label': 'This is shot 003 - Needs Editing', 'start': 26, 'end': 50} }

# write to file with cPickle/pickle (as binary)
def ld_writeDicts(filePath,dict):
    f=open(filePath,'w')
    newData = pickle.dumps(dict, 1)
    f.write(newData)
    f.close()

ld_writeDicts('C:/Users/Lee/Desktop/test2.dta',data)

#############

# read file decoding with cPickle/pickle (as binary)
def ld_readDicts(filePath):
    f=open(filePath,'r')
    data = pickle.load(f)
    f.close()
    return data

# return dict data to new dict
newDataDict = ld_readDicts('C:/Users/Lee/Desktop/test2.dta')
# test nesting
print newDataDict['one']['label']
As you can see its very simple to use and very quick. There are loads of alternatives if you wanted a nicely arranged, readable file, including json:
import json

# nested DICTIONARY
data = { 'one': {'label': 'This is shot 001', 'start': 1, 'end': 10},
         'two': {'label': 'This is shot 002', 'start': 11, 'end': 25},
         'three': {'label': 'This is shot 003 - Needs Editing', 'start': 26, 'end': 50} }

# write to file with json encoding
def ld_writeDicts(filePath,dict):
    f=open(filePath,'w')
    newData = json.dumps(dict, sort_keys=True, indent=4)
    f.write(newData)
    f.close()

ld_writeDicts('C:/Users/Lee/Desktop/test',data)


# read file decoding with json
def ld_readDicts(filePath):
    f=open(filePath,'r')
    data = json.loads(f.read())
    f.close()
    return data

# return dict data to new dict
newDataDict = ld_readDicts('C:/Users/Lee/Desktop/test.dta')
# test nesting
print newDataDict['one']['label']

However im all for cPickle.

Wednesday, 14 March 2012

ld_mirrorMe v1.5.0

Edit: Source is now available on GitHub.


I was surprised by the response this tool had, so I'm releasing v1.5.0 to help some people out, it'll be good to hear how you guys use it.
Alongside my softCluster script, you'll definitely notice a speed increase in your workflow.

Download it here (mediafire link).
Download, extract and place script in maya's script directory and use
import ld_mirrorMe
ld_mirrorMe.GUI()


It's features are shown on this much quicker demo (v1.0.0), supporting multi-mirroring for all modes.

Full details:
 - 3 modes:
     1. Curve - mirrors nurbs curves, ideal for mirroring rig controls,
     2. Mesh - mirrors geo, ideal for mirroring blendshape targets,
     3. Deformer - mirrors only clusters (at present), uses object's pivot for mirroring.
 - multi-mirroring on all 3 modes,
 - choose mirror axis,
 - search and replace,
 - alter new objects position (currently either world 0, target, mirror or original - depending on mode),
 - world position/rotation based, will work wherever or whatever the targets connected to,
 - entry objects names retained, if multiple copies needed (ideal for multi-clustering),
 - colourize option for Curves, if given curve is coloured (transform or shape), its mirror can be assigned a different colour,
 - quick and simple to use.

Updates:
09/03/12 - 0.5.0
    Initial working version.
10/03/12 - 0.9.5
    Tidied UI and reduced/cleaned code.
13/03/12 - 1.0.0
    Added colour option for curves.
    Removed all pymel (speed issues).
    Allowed multi-mirroring.
14/03/12 - 1.5.0
    Thanks to Matt Murray for feedback for further improvements.
    Added option to mirror world position of mirrored curve.
    Added further error-checking for all modes.
    Fixed bug causing unwanted locking of attributes.
    Added option to disable colouring of mirrored curve.

Again, any feedback, problems/bugs or ideas lemmie know and I'll do what I can.

Saturday, 10 March 2012

ld_mirrorMe tool demo

Just made a quick demo for one of my 3 main toolsets, (ld_animateMe v2, ld_rigMe v1 and ld_mirrorMe v.9.5) the ld_mirrorMe tool, something I started a while ago but put off.



This demo primarily shows mirroring on objects from world 0, but everything is calculated from worldspace and works accordingly, it doesn't matter where it is or what its connected/parented to, the mirror will work as expected.

Details:
3 modes - Curve, Mesh and Cluster (at present),
 - Curve - Primarily for mirroring nurbs curves for controllers, Mesh - Primarily for mirroring blendshapes (can mirror multiple targets at the same time), and Cluster - (developing for other deformers), given a deformer and its mesh will mirror the deformer over giving a correctly mirrored pivot and origin based on the objects pivot.
Search and replace feature,
Choose mirror axis,
Choose new objects position,
World based - will work wherever or whatever the targets connected to,
Entries retained, no need to keep adding same object of multiple copies needed,
Simple to use.

This was initially going to just be a tool for my rigging UI (ld_rigMe), but I prefer having it separate.

Any ideas/comments welcome.

Wednesday, 7 March 2012

Python: Create Cluster from soft selection

Edit: Source now available on GitHub.

Get the script 
here.
or from creativecrash here.


All thanks to Brian Escribano for his softSelection() code that gathers the id and weights of the current soft selection (basically, all the hard work).
It was simple enough to apply that information to a new cluster.

Usage:
Extract and place script file into a maya script directory (or python path directory) and run with this
import ld_createSoftCluster as sc
sc.ld_createSoftCluster()

and thanks to Valen Wagner for the icon.

Update:
07/03/12 - 0.4.0
    Alters cluster position to match selection rather than influenced average.

Sunday, 4 March 2012

Showreel 2011-12

Latest work from previous project, Ha Ha Hairies, where I worked for Red Wire Media as the Character TD/Animator.



Reel Breakdown:

Overview:
Rigged all shown characters, scripts and GUI's.

Sequence 1 (00:00:10):
Rigged main character 'Kwiff';
- Rig fully scalable and modularly built to provide easy updating of rig if needed.
- Simple Nurbs-based selection GUI for easy interaction.

Sequence 2 (00:00:31):
Hybrid IK/FK spine for extreme posing and toony nature of show;
- Broken hierarchies to separate upper and lower posing and flexibility.
- Traditional FK control during rotation, controllable volume preservation during translation.
- Position and orient switching for full IK control.

Sequence 3 (00:00:39):
Stretchy, bendy, volume-preserving limbs;
- With custom foot-roll, banking and various pivoting attributes.

Sequence 4 (00:01:18):
Various scripts to assist posing and animation;
- Ik/Fk blending, with snapping between the two over a single frame or a range of frames.
- Fk setup to mirror live rotation.
- Script to mirror or flip any part of the rig, including entire poses.

Sequence 5 (00:01:31):
Animator-friendly finger controls;
- Setup to allow quick posing of fingers with 2 attributes, as well as individual control over each finger via attributes and individual controllers.

Sequence 6 (00:01:36):
Insert-blink script;
- Based on animator designs, for a time-saving script.


Sequence 7 (00:01:41):
Selection GUI;
- Interchangeable between full rig and facial controls.
- Varying levels of detail.

Sequence 8 (00:02:19):
Animator friendly facial rig;
- Minimal, joystick inspired controls with multiple functions to provide alot of interactivity with minimal effort.
- Joint and blendshape based, with interactivity between the controls for quicker, stronger posing.
- Tweaking controls for more specific expressions and fine-tuning.

Sequence 9 (00:02:44):
Test facial rig;
- Use of multiple, individually controllable deformers, built into the rig.
- FK beak with tweaking lip controls.
- Various deformers on expressive areas of the face.
- Re-postionable eye sockets.
- Detachable upper/lower head for extreme posing.

Sequence 10 (00:03:12):
Test facial rig - Deform test;
- All deformers work together, rather than prioritising over each other.
- Complete squash, stretching and deformation over the head rig whilst maintaining any pose, blendshape or joint-based.
- Whilst maintaining that important ability to scale.

Tuesday, 31 January 2012

Mel/Python: Adding number padding

I was looking through some older scripts and hit across my dirty attempt to add number padding, and I was surprised it actually worked.
I went about tidying it up and came up with this little number in mel.
global proc string rt_addPadding(int $num,int $padding) { int $lengthNum=size(string($num)) ; string $padString; if($lengthNum<$padding) for($i=0;$i<($padding-$lengthNum);$i++) $padString=$padString+"0" ; return $padString+string($num) ; }
Which works ok, and then a couple of minutes searching I came across a post by Nathan which instead uses python (and is far better).
string $pad = `python ("'%0"+$padding+"d' % "+$num)`;
This then is used as this.global proc string rt_addPadding(int $num,int $padding) { return `python("'%0"+$padding+"d' % "+$num)` ; }
Useful :)

Thursday, 12 January 2012

Python: Create a file listing a folders contents

Our co-ord was just trying to get some info together so I come up with this simple little script to print the contents of a specified folder into a dated file.
I'm aware there are better methods of writing the file (using the list and write each item individually in loop etc), but it was short and does the job.

To get the date, I simply used the datetime module and retrieved today's date (as stipulated on local machine), then converted it to a familiar format.
For writing the file, I simply joined a sorted list of files found into a string separated by a newline, opened a writeable doc, deposited the data and closed it to allow access. import os import datetime def ld_listFiles(path,resultPath): fileString='\n'.join(sorted(os.listdir(path))) d=datetime.date.today() date=d.isoformat() filePath=resultPath+'filesListResults_'+date+'.txt' thefile=open(filePath,'w') thefile.write(fileString) thefile.close() return fileString # ld_listFiles('C:/Users/Lee/Desktop/Documents/','C:/Users/Lee/Desktop/')
...and of course this can then be furthered for error checking (making sure paths exist, folders contain files etc), nativePath conversion (not sure of correct terminology), specify file extensions/types, folder contents, file sizes, modification date etc. This is just a very simple example (and perhaps not a great one, but it works).
In fact I think I might spend some time in creating a decent version.
Any tips, suggestions etc, are more than welcome!

Saturday, 7 January 2012

Mel/Python: Splitting a string by a string (tokenize vs .split)

I know its only a small post and I don't go into detail, more of an outline... it really did bug me was how there are no expressions for tokenize.
I spent a bit of time trying to split a string (ie "L_clavicle_bind_jnt") by with the string "_bind_".
What I found with using tokenize was that it will split the string by the characters instead of the entire string, which to me, was a pain in the backside as I wanted {"L_clavicle","jnt"} but what i'd get with tokenize was {"L,"clav","cle","j","t"}. Now this wouldn't do, and I could find any out of the box way of doing this (I wanted to replace "_bind_" with "_IK_", etc to search), so I ended up turning to python (yet again).
It couldn't be simplier.
"L_clavicle_bind_jnt".split("_bind_")
Which translated as -
python("'"+$child+"'.split('_"+$namespace+"_')") ;
Thinking about it now, im sure there is a command to do this in mel, I just cant find it...

Thursday, 5 January 2012

Using Python list comprehension

Just a quick example of how I use list comprehension to search for matching entries in two lists (of course there's x amount of ways to do this, and results will vary depending on usage).

# two lists with some matching entries a=['jon','mary','frank'] b=['lewis','frank','jon','clive','betty','toni','jim'] #typical method using for loop with if/in statement results=[] for i in a: if i in b: results.append(i) print results # with list comprehension results=[x for x in a if x in b] print results

Sunday, 27 November 2011

python dictionaries

Python dictionaries are really, really damn useful in a pipeline. As you store information in a "key: value" type structure, like storing information on a character they repeatedly needs to be called throughout the pipeline, like its rig file path or characterId number. eg "chaInfo={'johnnyId':564,'davidId':565}", so when you call "character['johnnyId']", "564" is returned. Which can then be taken much further... "chaInfo={'johnny':{'num':'cha01','id':546,'file':{'mesh':'johnny_mesh_master.ma','rig':'johnny_rig_master.ma'}}}", so to get the right information you step through them, so for the rig file path you'd call "chaInfo['johnny']['path']['rig']", or the id number "chaInfo['johnny']['id']". So you could have all the information you need regarding an entity or object within a single file, which is very easily called as and when you need it.

Friday, 21 October 2011

PyQt4 for maya 2012 x64 (compiled against qt 4.7.1)

heres PyQt4 for maya 2012 x64, also a x86 version in the comments section

http://nathanhorne.com/?p=322

Thursday, 18 August 2011

Updating...

phew... far too much has happened to post it all but...

Few weeks into new job at Red Wire Media, down Cardiff Bay and I haven't stopped :)

Started with a compact animation toolset, then onto rigging the main characters (with some lovely work on the faces, even if i do say so myself), now onto setting up the maya and deadline to shotgun api, which is surprisingly easy actually. Just abit more practice on a dummy project and should be up and running soon.

Got so many scripts to upload at some point, so started with a modified version of David Lightbown's 2006 "dlUtils_Profiler.mel" (www.davidlightbown.com) which allows you to compare the difference in speed between two mel scripts (example used, compares difference in speed between multiplication and division in maya - multiplication is about 30% faster from what I remember - so instead of using a /2, use * .5 instead! - added bonus, use to avoid / by 0 errors!)
link:
http://www.creativecrash.com/maya/downloads/scripts-plugins/utility-external/c/mel-python-speed-profiler

I use it fairly often, from comparing simple procs to deciding the best/quickest file management solution, and even started to use it to compare the difference in speed between connected multiple nodes, constraints and expressions (I do also use the fps, but it can vary too much).


Wednesday, 16 February 2011

shoddy shelves

just thought of something, been using maya2011 64bit at work and seem to have an issue with shelf commands defaulting to "mel" even if saved as "python".

instead of thinking about it, i just put my python scripts into a mel wrapper, rather than;
closing maya, and editing the shelf pref flag to -sourceType "python".

duh.