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.

Monday, 2 July 2012

ROME II announced

What I'm currently working on here at CA.

Thursday, 31 May 2012


Thought i'd update, considering it has been a month or two.
Been pretty busy lately with the moving, new job and 5-hour commute (temporary), so I haven't had much time to work on any of my own stuff, or do... well... anything.
Once settled i'll probably get back on it.

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 (
or creativecrash here.

Any comments/suggestions welcome.

Tuesday, 3 April 2012

The Animated Sparrow

Really lovely animation (modeling and texturing) on the finished Sparrow rig by Geraint Wright.

Friday, 30 March 2012

Python: Writing nested dictionaries to file

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

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):
    newData = pickle.dumps(dict, 1)



# read file decoding with cPickle/pickle (as binary)
def ld_readDicts(filePath):
    data = pickle.load(f)
    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

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):
    newData = json.dumps(dict, sort_keys=True, indent=4)


# read file decoding with json
def ld_readDicts(filePath):
    data = json.loads(
    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.

Thursday, 15 March 2012

Mel: Invert Selection from a render layer

Thought I might post up this useful code someone asked for...

//  ld_invertSel_rlyr.mel  0.2
//  Authors:     Lee Dunham
//  Licence:     Creative Commons, Attribution, Share Alike
//  About:       Inverts selection for visible objects in current render layer.
//  Usage:
//      ld_invertSel_rlyr ;
global proc ld_invertSel_rlyr(){
string $currentRenderLayer=`editRenderLayerGlobals -q -currentRenderLayer` ;
string $objsRenLayer[]=stringArrayRemoveDuplicates(`editRenderLayerMembers -q $currentRenderLayer`) ;
for($obj in $objsRenLayer)
    if(`getAttr ($obj+".v")`==1 && `objectType -isType "transform" $obj`)
        select -tgl $obj ;
        select -d $obj ;

It'll invert the selection for whatever visible transform objects are in the current render layer. Its not fantastic but it was a 5-minute job.

Wednesday, 14 March 2012

ld_mirrorMe v1.5.0

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

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.

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.

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

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.

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

and thanks to Valen Wagner for the icon.

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:

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.

Thursday, 23 February 2012

Mel: ld_animToCurve - create nurbs curve from moving objects or verts

Download the script directly, here (follow link and place it in maya's script directory)
or from creativecrash here.

Creates a nurbs curve for each selected object and/or vert over a series of frames (like a motionTrail, but without the motionTrail bit).

Works using xforms - so object could be skinned, constrained, driven by expressions etc,
Simple to cleanup - just rebuild the curve,
Simple to use - select the objects and/or verts you want and execute using ld_animToCurve ;

Useful for quickly putting together complex shapes or tracking a vert's/object's position.

07/03/12:  0.6.0
    Fixed issue selecting some verts.
   Added poly faces - now requires modified version of owen burgess' 2009 script "" (included).

Tuesday, 21 February 2012

Mel: Query part of a string, given its index and separator: PART 3

Update from PART 2.
Thanks to Viktoras Makauskas for the suggestions and link.
// get an item from a string given the string, separator and index range // ld_getName "L_test_me_out_bind_jnt" "_" 2 -2 ; global proc string ld_getName(string $obj,string $separator,int $start,int $end) { string $buffer[],$name ; int $numTokens=`tokenize $obj $separator $buffer` ; if($start<0) $start=$numTokens+$start ; if($end<0) $end=$numTokens+$end ; if($start<0 || $start>=$numTokens || $end<0 || $end>=$numTokens || $start>$end) return "" ; $name=$buffer[$start] ; for($n=($start+1);$n<=$end;$n++) $name+=$separator+$buffer[$n] ; return $name ; }
Changes include:
  1.  Separating the indexing to individual ints instead of a string that needs to get split.
  2.  Using the indexes to specify the token, not the separator.
  3.  More error checking.
Main difference is 0 -1 will now return the entire string rather than all but the last token (as it does in Python), mainly for functionality due to the removal of the colon. Can still return one item using the same int (ie the last token would be -1 -1).

Monday, 20 February 2012

Mel: Query part of a string, given its index and separator: PART 2

Update to previous post (here), needed to grab a range of items from a string given a separator and index/range (supports reverse and extended indexing).
I do have a horribly sneaky suspicion there is already a built in command for this...
Will work with ranges given as "0", "-1", "0:","-2:", ":2", ":-2", "1:3" and "-3:-1" etc.
// get an item from a string given the string, separator and index number/range as string (supports reverse indexing) //ld_getName "L_test_me_out_bind_jnt" "_" "2:-1" ; global proc string ld_getName(string $obj,string $separator,string $index) { string $mulBuffer[],$indBuffer[],$name ; int $range[],$start,$end ; tokenize $index ":" $mulBuffer ; $range[0]=int($mulBuffer[0]) ; if(startsWith($index,":")) { $mulBuffer[1]=$range[0] ; $range[0]=0 ; } else if(endsWith($index,":")) $mulBuffer[1]=-1 ; tokenize $obj $separator $indBuffer ; $start=$range[0] ; if($range[0]<0) $start=size($indBuffer)-(abs($range[0])) ; if(size($mulBuffer)>1) { $range[1]=int($mulBuffer[1]) ; $end=$range[1] ; if($range[1]<0) $end=size($indBuffer)-abs($range[1]) ; if($end>(size($indBuffer)-1)) return "" ; $name=$indBuffer[$start] ; for($n=($start+1);$n<$end;$n++) $name+=$separator+$indBuffer[$n] ; } else { if($start<0) $name=$indBuffer[size($indBuffer)-int(abs($start))] ; else $name=$indBuffer[$start] ; } return $name ; } Would appreciate any feedback (I know how much simpler this is in python, was curious how simple it was to do in mel).
Python, i think, would handle like this:

Thursday, 16 February 2012

Mel: Query part of a string, given its index and separator

UPDATE: Updated version with better functioning here.
I realised how often I was using a mix of the tokenize, startString and endString to get sections of a string, whether the start or end (various ways) or the middle (ie getting the side "L_*" or "R_*" or type of object "*_ctrl" "*_bind_jnt") etc, and I loved the way python handles this instead (especially the reverse indexing) so I come up with this.
global proc string ld_getName(string $obj,string $separator,int $index) { string $buffer[],$name ; tokenize $obj $separator $buffer ; if($index<0) $name=$buffer[size($buffer)-int(abs($index))] ; else $name=$buffer[$index] ; return $name ; } //ld_getName "L_test_me_out_ctrl" "_" -1 ;
EDIT: Changed positive indexing to match 0 = start, -1 = end

Saturday, 4 February 2012

Correctional blendshapes

I always had nightmares creating correctional blendshapes for rigs, having to work on the duplicated default mesh whilst watching the result mesh update (still trying to get over how I ever did this on a single 15" monitor...),
and then I found out how blendshape weights aren't limited from 0 to 1... and less than 0.

Now creating correctional blendshapes is far more enjoyable and takes up much less time, using a very simple setup.

Its actually very basic math (the way I see it anyways)
a + b = c
which therefore means...
b = c - a
so if "a" was a pose, "b" was its correction, and "c" the result of both. Now if you take the pose away from the result, your left with... the correction!

Corrective blendshape wise, you need to put your character into its pose you want to correct,

duplicate the mesh and create the correction ("b"),

duplicate the mesh orginal mesh off again (to get "a")

Then you duplicate the mesh with no deformations on it (as you would creating a normal blendshape), and assign the pose mesh and the corrective mesh ("a" + "b"). You finally want to turn on the correction blend weight to 1, and the pose blend weight to -1.

Your then left with just the correction, which you duplicate off and apply as a corrective blendshape target for you character.

This can be taken so much further to do live pose updates (above is all automated), but I wont go into that yet.

I hope this helps!

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 proc string rt_addPadding(int $num,int $padding) { return `python("'%0"+$padding+"d' % "+$num)` ; }
Useful :)

Thursday, 26 January 2012

Bird Rig: Current WIP

Geraint Wright asked if I could build a quick rig for a sparrow animation (model would be supplied).

This is where it is atm. (still alot of work to go into it) but alot of the base ideas are there.

The separation of the feathers was far simpler than I though actually, using a couple of curves and the very useful pointOnCurveInfo nodes (same nodes used in motionpaths but without the extra crap), then just a basic heirachy of dependencies of controllers and aim constraints (the feather bending is hideous but was only quickly thrown together, needs more thought behind it so expect that to change).
One issue (kinda solved, looking into better solutions) was due to the aim constraint, feathers wouldn't react accordingly to folding or certain positions, especially when pulled about a fair bit. Simple solution was to declare the aims up object as another controller (well, one for each segment).
Alot of automation (of course each with manual overrides and on/off blending) will be needed to get a smoother transition and to 'hide' any smaller issues, included with a smart system to fold the wing (some scripting required).
The animation it'll be used in you wont really see much of the detail but I'd rather put the work in now if any shots/ideas for closer cuts are thrown in...


Wednesday, 18 January 2012

ld_animateMe v1.0.0

ld_animateMe now available! - Download
current version 1.2.1

Re-arrange, offset and reverse keyframes, plus other useful tools.

To Install:
Place the downloaded "ld_animateMe.mel" file into one of your Maya scripts directories, restart Maya and use the following code to load the UI.


To Use:
animateMe is designed to be compact and clutter free, giving you the valuable screen space you need.
Besides minimizing the frames for each section, you can remove it from the tool under the "Display" menu by unchecking the related box. If you cant it back, simply re-check the box.
As well as clicking the relevant buttons, you can use the sliders to adjust the value you want and once released, it will run that tool, making it as quick as possible to use.

 - User Info:
The user info is designed to quickly let you know some useful information regarding your scene that could potentially save hassle later, such as; Forgetting to turn auto-save on, or whether your animating to 24fps or 25. The information is  reloaded on creation of the UI, or by clicking the refresh icon to the right.

 - Adjust Animation - Shift mode:
To adjust animation, you must select keyframes from either the timeline, or the curve editor.
Entering a number will shift the selected keys by that value, whether positive (ie "2" = shift selected keys 2 frames later, or "-2" = shift selected keys 2 frames earlier.)
EDIT: 19/01/2012 - v 1.2.0
- If no range in timeline or keys selected in curve editor, animtaion will be adjusted from current point onwards.

 - Adjust Animation - Offset mode:
To adjust animation, you must select keyframes from either the timeline, or the curve editor.
Offset animation works with your selection order. It will offset every selected object's selected keyframes by X amount of frames relative to the object selected before it.

1. object1, 2 and 3 each has a key on frame 1.
2. You select them in numerical order (object1 first and object3 last).
3. You use Offset mode with value of 2.
4. object2's key will now be at frame 3 and object3's key will now be at frame 5.

 - Adjust Animation - Reverse mode:
You can reverse your animation by selecting the keys from either the timeline, or the curve editor.

 - Scale Keys - Individual Pivots:
To use scale keys, you must have keys or curves selected in the curve editor.
For every key selected, it will  scale it at the point between its previous and next value, as if it was blending the key between the keys either side. It works great for toning up or down, facial expressions, poses etc or even adding overshoot.

 - Scale Keys - Pivot on 0:
To use scale keys, you must have keys or curves selected in the curve editor.
This mode will scale all the selected keys the same pivot of 0.

 - Selection Sets:
Compact version of ld_selectMe (Link).
Maya's own selection sets are node based, meaning that creating a selection set for a character will only work in that file, which is and very limiting. This tool, instead, compiles a selection script and saves it to shelf to be used in any file, along with a toggle selection function by ctrl+clicking the shelf button.
"Name" is to enter the name of the button as it will appear on the shelf.
"clear" clears the list and name field.
"+" adds selected objects to list.
"-" removes selected list items from list (can also press "delete" key).
EDIT: 19/01/2012 - v 1.2.0
- Now creates selection shelf button that will attempt to use namespace of the FIRST currently selected object, if no objects currently select, default one is used.

Version 1.5.0 is underway, automating the user info with extra information displayed, such as the last saved time for the current file, snapping tools (including component snapping), and a new Scale Keys mode, called "Falloff".
Thanks to quick feedback, I've been able to make some adjustments to the functionality of the tool.

Version 1.2.0:
19/01/2012 -
Edited functionality of Adjust Animation.
   - If no range in timeline or keys selected in curve editor, animtaion will be adjusted from current point onwards.
Edited functionality of Selection Sets.
   - Now creates selection shelf button that will attempt to use namespace of the FIRST currently selected object, if no objects currently select, default one is used.

Version 1.2.1:
19/01/2012 -
Fixed issue with Selection Sets update.
  - If current selection's namespace didnt't contain an item in selection list, it would error, it will now instead just use default namespace.

Any suggestions, please let me know.

Sunday, 15 January 2012

RigReel 2010-11

Finally got round to uploading last years rig reel, still finishing off current one, will upload as soon as its done.

Reel Breakdown:

Sequence 1 (0026):
Rigged character ('Skitter') in Maya.
Setup nCloth dynamics for screen and node-based rig for timewarp in Maya.

Sequence 2 (0201):
Rigged character, 'Skitter', in Maya;
 - Modular built, stretchable and dynamic tail rig based on hair dynamics with full Fk control system and blending, and control over main dynamic attributes to tweak shot specific and avoid intersection with props.

Sequence 3 (0937):
Rigged prop (table) in Maya;
 - Fully driven by expressions to assist animators and provide continuity throughout show.

Sequence 4 (1034):
Rigged all characters and props in Maya;
 - Including all facial rigs.
 - All characters include controllable dynamic tails and ears, to assist animators and to assist retaining animation continuity.

Sequence 5 (1225):
Rigged  character (Splish) in Maya;
 - All rigs scaleable to assist animation.
 - Stretchable Ik/Fk style spine rigs, identical setup and control for all characters to retain familiarity and allow interchangeable animation.

Sequence 6 (1655):
Rigged  characters (Splish and Splash) and prop (controller), in Maya.

Sequence 7 (1855):
Rigged  character (Splish) in Maya;
 - All rigs with squash/stretch limbs, Ik/Fk blending, auto-flatten and foot-roll.

Sequence 8 (2173):
Assisted in animation in Maya, once rigging was complete.
Co-created Studio specific Animation and Pipeline Toolsets, including;
 - Ik/Fk snapping,
 - shared user creatable and customizable selection sets,
 - animation key/curve cleaning, blending and re-timing,
 - customizable animation trails,
 - animation HUDs and automatic notification of shot completion and versioning.

Friday, 13 January 2012

Maya: Starting scripts on load - userSetup.mel

To execute scripts, whether custom or local, each time you startup maya (in the studio ours check important prefs, timeUnits etc) is very simple.

All you need to do is create a mel script called "userSetup.mel" and place it into you maya/scripts folder in your documents (of course there are instances, depending on what the script is doing, if its messing with mainWindow states etc, you need to make sure they load first by using the "evalDeferred" command - at least that's what I've come to believe.

For example if you created a mel script like this;
string $win=`window` ; columnLayout -adj true ; text -label "Hello World" -align "center" ; setParent.. ; showWindow $win ;
called it "userSetup.mel" and placed it into maya/scripts/  folder, on starting maya, you can expect to see a window with the text "Hello World" pop up when maya starts.
Generally this idea is taken further (if in a studio) and either each user's environment vars point to a userSetup.mel on the network, or each have their own userSetup.mel on their local machine that points to a separate startup script on the network, which then its fairly simple for the user to modify their own startup, based on their preferences.

At some point, once I get some time, I do intend on revisiting and furthering most of my posts, taking the time to actually explain what's going on and why, and giving links the right documentation.

Comments welcome.

Maya: IK Handles not updating on undo

I had this problem a few times (even back on maya 5), where you set up a rig, and you point constrain the ikHandle to a control object. It moves around fine, up until you undo. The handle just doesn't seem to behave properly, and scrubbing or moving it again will snap the ikHandle to where it should be.
So I thought I might give a workaround.
Directly constraining an IkHandle seems to have the issue of not updating when undoing.
It seems to be a clash with the way the ik handles and constraints evaluate, and something seems to get missed.
You can avoid this by parenting the ikHandle under the controller, or (if you want the outliner to be tidy) you can parent the ikHandle under a null or locator and constraint that instead.

Brad Clark (Co-founder - provided more info and suggested a better solution.
You shouldn't have this problem if you turn off the snap setting on the ik handle. Then it won't be trying to get back to the end of the chain and should stick with the constraint target. There is a bug with Maya Undo though that if you are moving a node and hit the undo hot key before releasing the mouse button for the current transform, it will undo the previous transform, leaving the move you just did outside of the que, causing an offset that has to be fixed by hand.

Comments welcome.

Maya: Typical Sound/Audio issues during playback.

Another frequent problem is not being able to hear audio during playback, but working fine whilst scrubbing.

Typically, the issue could be down to your playback settings.
Just open your maya preferences, and under "Time Slider", check your "Playback Speed" is at Real-time. If its at anything else you wont hear the audio during playback.

Maya: Window display issues - "...Panel is torn off."

This seems to be a frequent problem, in which some people result in doing a complete reinstall!.

Cant show my graph editor/outliner/etc window, keeps telling me "... Panel is torn off."

What this typically means is that somewhere along the line the window has been placed off-screen, usually happens when users either switch monitors around or remove a monitor.
A few very simple fixes, and any one of them should solve your problem.

1.  You can reset your maya's window preferences simply by deleting the "windowPrefs.mel" located in your maya prefs folder ("USER\My Documents\maya\2011-x64\prefs\") whilst maya is CLOSED. Dont worry, once opening maya again, it will automatically create the "windowPrefs.mel" file again, all windows should now load at their default position.
2. You can edit the "windowPrefs.mel" file, to tell maya where to place the windows, just open it in a text editor (notepad usually does the trick, and again whilst maya is closed), and for each window you'll see a "-topLeftCorner" flag with 2 numbers after it. Change them to something like 10 10, save the mel file and load maya.
3. If you only have 1 rogue window you can use mel to reposition the window (you will of course need to know the name of the window, found when trying to load the window - as long as you have "Echo all commands" ticked on in the script editor)
window -e -tlc 10 10 "graphEditor1Window" ;
Now depending on the window your trying to reposition, the naming convention might differ from ending in "Window" or "Panel#Window" ("#" is the number id of the window, typically its 1).
Again, any questions etc, please feel free to comment.

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))) 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!

Tuesday, 10 January 2012

Mel: Parenting shape nodes to new parents (ie polyMesh to Joint)

Was asked about combining a polySphere/nurbsSphere to a joint, so selecting the sphere still selects the joint.

Its fairly simple actually, its the same way as you would combine two nurbs curves under one transform node (to get more complex/detailed control objects).

string $parent="joint1"; string $shape="pSphereShape1"; parent -add -shape $shape $parent;
As simple as!

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.
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

Adding notes to nodes in Maya through mel

Its fairly straightforward to add notes to a node in Maya (under Attribute Editor, add text to under Notes section), but through mel there's one more step you need to go through before you can.

Simply put, the node needs a "notes" (or s/n "nts") attribute first, then its plain sailing (manually writing a note creates the attr, which then stores the string - or so im assuming, looks like that's handled through a scriptJob)
So to add a note to a node, first check whether it already has an attribute called "notes", create one if not, then write something.
string $node[]=`polyCube` ; if(!`attributeQuery -node $node[0] -ex "notes"`) addAttr -ln "notes" -sn "nts" -dt "string" $node[0] ; setAttr -type "string" ($node[0]+".notes") "This node now has a Note. You can store various bits of information here." ; (The note on this script example is on the transform node of the polyCube object ($node[0]) as $node[1] would be the shape object)

Wednesday, 4 January 2012

Iconicles VFX Showreel

My work includes;
All Character/Prop Rigs, as well as - Animation, Dynamics, Animation Tools and Pipeline Development/Tools.

Still sorting current showreel, will be up asap.

Selecting animated objects

Quick little script for selecting any (dag) objects with animation on.
string $allObjects[]=`ls` ; select -cl; for($i=0;$i<`size($allObjects)`;$i++) if(`keyframe -q -keyframeCount $allObjects[$i]` != 0) select -tgl $allObjects[$i] ;
I was already aware that mel doesn't need curly brackets "{}" following if statements or for loops (will only execute the next line of code), it seems that it doesn't need them even if your incorporating another statement or loop :) such as the above code shows...

Tuesday, 3 January 2012

Toggle lighting script

simple script to toggle the lighting between "default" and "use all lighting" on the current panel.
string $currentPanel=`getPanel -withFocus` ; string $mode="default" ; if(`getPanel -to $currentPanel`=="modelPanel") if(`modelEditor -q -dl $currentPanel`=="default") $mode="all" ; modelEditor -edit -dl $mode $currentPanel ;