Category: Maya

Opening a newer version Maya file in an older version of Maya

A common issue when using AW Maya is trying to open a file that was created in a newer version of Maya than your installed version. Maya files are not backwards compatible, in my experience. There are two ways that I know of to deal with this. One is to simply select “Ignore Version” in the File->Open dialog. I tried this today and it failed, Maya crashed. Another option, which did work for me, is to save the newer version file as an ASCII file (file.ma), and edit the file’s data manually. This is very simple to do. You will need to have access to the newer version of Maya to accomplish this though, or have your collaborator deliver an ASCII version of the file. Once you have the ASCII file, do the following things:

1) Save a dummy ASCII file from your older version of Maya (ex: dummyFile.ma) so that you can see the older format file’s data. For safety, make a copy of your “Newer Version” file, as you will be editing the code directly.

2) open both files side by side examine the “headers”, the top portion of each file. You will note a similarity in the first 10 – 15 lines of data. I am using a Mac, so examining the files, the last line I see in what I would call header information is: fileInfo "osv" "Mac OS X 10.8.2";. After this there is a “createNode” Maya command, that I don’t want to disturb. It’s slightly different from one file to another and one version to another, but only slightly. You will have no trouble figuring out where to copy and where to paste. Copy this header data from the older version file and paste to the newer version file, overwriting the relevant code.

2) The file should now open in the older version of Maya. Of course any features of the newer version of Maya that are not available in the older version of Maya will not work in this opened scene (actually I’m not certain what happens in this scenario).

There may be other methods, but I am not aware.

Maya Particle Instancing Experiment

Maya Python script:

[py]
#Audio Driven Particle System 2011.10.27 A1
#Python for Maya
#Code By: Oliver Wolfson
#oliverwolfson.com – wolf@oliverwolfson.com
#You will need keyframes formatted in text files in an exclusive directory to make this work. See:
#http://oliverwolfson.com/animating-with-audio/ for more details

import os
import maya.cmds as mc

##LIGHT
Light = mc.spotLight(ca=120, n="mySpotLight")
mc.setAttr( ("mySpotLightShape.useDepthMapShadows"), 1)
mc.setAttr( ("mySpotLightShape.dmapResolution"), 2048)
mc.setAttr( ("mySpotLightShape.dmapFilterSize"), 6)
mc.setAttr( ("mySpotLightShape.penumbraAngle"), 10)
mc.setAttr( ("mySpotLightShape.dropoff"), 1)
mc.setAttr( ("mySpotLight.translateX"), 125)
mc.setAttr( ("mySpotLight.translateY"), 100)
mc.setAttr( ("mySpotLight.translateZ"), 20)
mc.setAttr( ("mySpotLight.rotateX"), -33)
mc.setAttr( ("mySpotLight.rotateY"), 10)
mc.setAttr( ("mySpotLight.rotateZ"), -45)
mc.setAttr( ("mySpotLight.scaleX"), 30)
mc.setAttr( ("mySpotLight.scaleY"), 30)
mc.setAttr( ("mySpotLight.scaleZ"), 30)

##AUDIO DRIVEN THING
num = 0
for p in range(0, 64, 2):
print("this is the " + str(num) + " num:" + str(p))
num += 1
Locator = mc.spaceLocator(n=("myLocator"+ str(num)))

Shader = mc.shadingNode(‘blinn’, asShader = True)
mc.setAttr ((Shader+ ".glowIntensity"), .1)
SG = mc.sets (renderable=True, noSurfaceShader=True, empty=True)
mc.connectAttr((Shader +".outColor"), (SG + ".surfaceShader"))
mc.setAttr((Shader + ".color"),0.203189, 0.252033, 0.57554)

Plane = mc.polyPlane(h = 10, sw = 1, sh = 15, cuv = 2)
mc.setAttr(str(Plane[0]) + ".rotateX", 90)
mc.setAttr(str(Plane[0]) + ".scaleX", .25)
mc.makeIdentity( apply=True )
mc.hyperShade(assign = Shader)

mc.select(clear=True)
Emitter = mc.emitter (type = ‘omni’)
Particles = mc.particle()
mc.connectDynamic(Particles, em= Emitter )
mc.setAttr((Particles[1] + ".lifespanMode"), 1)
mc.select(Plane[0])

Wave = mc.nonLinear( type= ‘wave’ )
mc.setAttr((Wave[0] + ".wavelength"), .4)
mc.setAttr((Wave[0] + "Handle.rotateZ"), 90)
mc.setAttr((Wave[0] + "Handle.rotateY"), 50)
mc.setAttr((Wave[0] + "Handle.translateY"), -7)
mc.setAttr((Wave[0] + "Handle.translateZ"), 11)
mc.makeIdentity( apply=True )
mc.select(clear=True)
mc.particleInstancer( Particles[1], addObject = True, object = Plane[0], cycle=’None’, cycleStep=1, cycleStepUnits=’Frames’, levelOfDetail=’Geometry’, rotationUnits=’Degrees’, rotationOrder=’XYZ’, position=’worldPosition’, age=’age’)

mc.expression ( s = Wave[0] + ".offset = " + Locator[0] + ".translateY/10;\n" + Wave[0] + ".amplitude = " + Locator[0] + ".translateY/10;\n" + Wave[0] + "Handle.rotateX = frame;\n" + Wave[0] + "Handle.rotateZ = " + Locator[0] + ".translateY*0;\n" + Wave[0] + "Handle.scaleX =" + Locator[0] + ".translateY;\n" + Wave[0] + "Handle.scaleY = " + Locator[0] + ".translateY;\n" + Wave[0] + "Handle.scaleZ = " + Locator[0] + ".translateY;\n")
mc.expression ( s = Emitter[0] + ".translateY = " + Locator[0] + ".translateY;\n" + Emitter[0] + ".rate = " + Locator[0] + ".translateY*20;\n" + Emitter[0] + ".speed = " + Locator[0] + ".translateY;\n")
mc.expression ( s = Plane[0] + ".rotateY = " + Locator[0] + ".translateY*60;\n" + Plane[0] + ".translateY = " + Locator[0] + ".translateY;\n" + Plane[0] + ".scaleY = " + Locator[0] + ".translateY/;\n" + Plane[0] + ".rotateX = " + Locator[0] + ".translateY;\n")
mc.expression ( s = Shader + ".incandescenceR =" + Locator[0] + ".translateY/200;\n" + Shader + ".incandescenceG = " + Locator[0] + ".translateY/200;\n" + Shader + ".incandescenceB = " + Locator[0] + ".translateY/100;")

mc.select(Locator)
mc.select(Plane, add=True)
mc.select(Emitter, add=True)
mc.select(Wave , add=True)
mc.group(n= ("myGroup" + str(num)) )
mc.setAttr("myGroup" + str(num) + ".translateZ", p*-10)

mc.select(clear=True)
for l in range(1, 33, 1):
mc.select(("myLocator" + str(l)), add=True)

## add path to keyframe data files – just the source directory that contains them.
rootdir=’/Volumes/2TB/work/3D/Maya/Maya_projects/Mogwai/sound/ranoPanoKeys01/zapped’
## "ty", in line 13, refers to the Maya attribute channel of the selected objects. Modify this attribute as necessary.
objs= mc.ls(sl=True)
for subdir, dirs, files in os.walk(rootdir):
for thisFile, o in zip(files, objs):
file = open((os.path.join(rootdir, thisFile)), ‘r’)
lines = file.readlines()
file.close()
for i in range(len(lines)):
mc.setKeyframe(o, at=’ty’, v=float(lines[i]), t=i, itt=’linear’, ott=’linear’)

[/py]

Use this information to build key data for this script
http://oliverwolfson.com/extracting-raw-key-frame-data/

CG Rain Drops

Splashes created in Real Flow, and instanced to Maya Particles.

Ripples created with a dynamic fluid texture.

[text collapse=”true”]
float $colU = particleShape1.collisionU;
float $colV = particleShape1.collisionV;

if ($colU > 0) {
int $xpos = fluidTexture2DShape1.resolutionW * $colU;
int $ypos = fluidTexture2DShape1.resolutionH * $colV;
setFluidAttr -xi $xpos -yi $ypos -at density -ad -fv 0.6 fluidTexture2DShape1;
particleShape1.lifespanPP=0;
}
[/text]

Maya particle instancing with real flow rain drops



Create animated instances geometry at a particle collision.

For my raindrop splash, I am using an animated sequence of geometry, created in realflow (70mb). The realflow bin sequence is a single node after it is imported to Maya, it needs to be converted (duplicated) to a sequence of Maya nodes, multiple nodes. Use the following MEL script to convert the bin to multiple nodes.

[c]//Select your realflow imported bin
string $bin[] = `ls-sl`;
//this is set up to to "convert" (duplicate) the bin from frame 1 – 100. Set the frame range that you want to convert below.
for( $index = 1; $index <= 100; $index++ )
{
currentTime $index;
select $bin[0];
duplicate;
select -cl ;
}[/c]

Now you should have a sequence of separate meshes, each representing a frame of your instanced animation. These will be loaded into the “particle instancer” to allow for animation at the point where each particle collides.

Create a collision event for your particle
1. Select particle and collision object and go to Menu : Particles > Make Collide
2. Set a particle collision event for your selected particle. Particles > Particle collision event editor. Set: event type to “emit”. Set: inherit to 0. Set: 1 particle emitted per collision. Set: Original Dies.
3.Press the create event button. A new particle object will be created.

Instance the geometry to the newly created particle.
1.Go to Menu>Particles > Instancer options
2. Load your sequence of separate meshes into the “Instanced Objects” section. Make sure that your particleShape is NOT loaded into the create instancer as an instanced object as it will try and instance itself.
3. Set: particle object to instance to : particleShape2 or whatever the particle object that was created by the collision event.
4. Select the newly created particle object shape. In the attribute editor, set: the lifespan of the particle to the duration of you splash object geometry sequence (number of individual nodes). The lifespan is in seconds…so you will need to do the math to get your frame count..

Tracking the position of a particle collision.

Rough guide:

  1. Create planes, one above the other, scale to 10 units square, and place in positive unit space.
  2. Select the top plan. Make it emit particles: Particles > Emit From Object >options (select “surface” as emitter type).
  3. Make particles and ground plane collide. Select the particles, Shift-select the plane, then select Particles > Make Collide.
  4. Select particlesShape, add CollisionU and CollisionV attributes. Set the lifespan attribute to LifespanPP only.
  5. Create a locator called loc.
  6. Create a dynamic expression with the code below.

[c]
float $colU = particleShape1.collisionU;
float $colV = particleShape1.collisionV;

if ($colU > 0) {
particleShape1.lifespanPP=0;
loc.translateX = ($colU*10);
loc.translateZ = ((1 – $colV) * 10);
}
[/c]

Scene file.

determining the bounding box of a Maya object

[text]
float $boboArray[] = `polyEvaluate -b pCube1`;
[/text]

for a default cube, this will return : // Result: -0.5 0.5 -0.5 0.5 -0.5 0.5 //, the units returned correspond to the 6 coordinate locations of the cubes vertices.

[text]
float $boboArray[] = `polyEvaluate -b pSphere1`;
[/text]

for a default sphere, this will return : // Result: -1 1 -1 1 -1 1 // , the units returned correspond to the coordinate locations of the a cube that is “fitted” to the sphere’s bounding box.