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.


Updates:
07/03/12:  0.6.0
    Fixed issue selecting some verts.
                 0.7.0
   Added poly faces - now requires modified version of owen burgess' 2009 script "getfacecenters.py" (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:
"L_test_me_out_bind_jnt".split("_")[2:-1]

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!