Accessing Texture Data [MEL]



 

 

Textures in maya are stored as MFn::kFileTexture nodes. These are each connected to a texture placement node of type MFn::kPlace2dTexture. The output from the texture will be connected to a colour channel on a material node.

 

 

 

 

Finding all Textures
in a Scene

Maya has some fairly nice little tricks when dealing with textures. Essentially we have to build a list of all MFn::kFileTexture nodes.

 

We could simply write out the full path names of the textures to the exported file. Alternatively we can make use of the maya class MImage to access the image data directly.

 

For the purposes of this example, i have described both methods.

 

To find the filename of the applied texture, you have to access the fileTextureName (ftn) attribute of the file texture node. This string attribute will hold the full path for the texture file.

 

The second half of the function then writes all of the texture files to a custom texture pack. MImage is used to read the texture data from the file node. The width, height and byte depth are then written to the file.

 

It is worth mentioning that MImage also allows you to resize image files. It may therefore be a good idea to ensure, that the width and height of the image are both powers of two.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


#include<maya/MFnTransform.h>
#include<maya/MItDependencyNodes.h>

void WriteTextures(const char* filename) {

 

// create an iterator to go through all transforms
MItDependencyNodes it(MFn::kFileTexture);

// an array to hold all of the texture nodes
MObjectArray Files;

//iterate through all textures
while(!it.isDone())
{
 

// attach a dependency node to the file node
MFnDependencyNode fn(it.item());

// append the texture to a list of files
Files
.append(it.item());

// get the attribute for the full texture path
MPlug ftn = fn.findPlug("ftn");

// get the filename from the attribute
MString filename;
ftn.getValue(filename);

// write the file name

cout << filename.asChar() << endl;

// get next transform
it.next();

}

FILE* fp = fopen(filename,"wb");

if(!fp) return;

// write the number of textures to the file
int NumTextures = Files.length();
fwrite(&NumTextures,1,sizeof(int),fp);

// loop through each texture file
for
(int i=0;i<NumTextures;++i) {

 

MFnDependencyNode fn(Files[i]);

// write the node name

fwrite( fn.name().asChar(),1,
fn.
name().length()+1,
fp );

// use the MImage class to get the image data
MImage img;
img.
readFromTextureNode( Files[i] );

// get the image size

unsigned int
w,h,d=img.depth();
img.getSize(w,h);

// write image attributes
fwrite
(&w,1,4,fp);
fwrite(&h,1,4,fp);
fwrite(&d,1,4,fp);

// write either 24 or 32 bit data
if
(d==4) {

  fwrite(img.pixels(),1,w*h*4,fp);

} else {

  // write 24bit data in chunks so we skip
// the fourth alpha byte

for(unsigned int j=0;j < w*h*4; j+=4 ) {
  fwrite(img.pixels()+j,1,3,fp);

}

}

}

}

 

 

 

Outputting Texture Placement Nodes

 

Texture Placement nodes allow you to alter the position, scale and rotation of textures placed on a geometry surface.

 

You may find that exporting texture placement nodes may be useful in certain situations, for example animated uv scrolling.

 

There is no specific Function set for texture placement nodes, so you will again have to use the MFnDependencyNode to access the data via the nodes attributes.

 

For more information take a look at the Node and Attribute reference in the Maya Documentation.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


#include<maya/MFnDependencyNode.h>

void OutputTexturePlacement(MObject& obj)
{
 

MFnDependencyNode fn(obj);

cout << "Placement2D " << fn.name().asChar() << "\n";

float f;
bool b;

// get the texture coverage in U and V
MPlug plg = fn.findPlug("cu");
plg.getValue(f);
cout<< "\tCoverage " << f << " " ;
plg = fn.findPlug("cv");
plg.getValue(f);
cout << f << endl;

// output the texture frame translation
plg = fn.findPlug("tfu");
plg.getValue(f);;
cout<< "\tTranslateFrame " << f << " " ;
plg = fn.findPlug("tfv");
plg.getValue(f);
cout << f << endl;

// get the texture frame rotation
plg = fn.findPlug("rf");
plg.getValue(f);
cout<< "\tRotateFrame " << f << endl;

// the u direction texture mirroring.
plg = fn.findPlug("mu");
plg.getValue(b);
cout<< "\tMirrorU " << b << endl;

// the v direction texture mirroring.
plg = fn.findPlug("mv");
plg.getValue(b);
cout<< "\tMirrorV " << b << endl;

// is the texture staggered.
plg = fn.findPlug("s");
plg.getValue(b);
cout<< "\tStagger " << b << endl;

// the u direction texture wrapping.
plg = fn.findPlug("wu");
plg.getValue(b);
cout<< "\tWrapU " << b << endl;

// the v direction texture wrapping.
plg = fn.findPlug("wv");
plg.getValue(b);
cout<< "\tWrapV " << b << endl;

// The UV repeat. Determines how many times texture
// repeats in the given u and v directions

plg = fn.findPlug("reu");
plg.getValue(f);;
cout<< "\tRepeatUV " << f << " " ;
plg = fn.findPlug("rev");
plg.getValue(f);
cout << f << endl;

// The UV offset. Determines the offset of the texture
// from the 0,0 u and v texture origin.

plg = fn.findPlug("ofu");
plg.getValue(f);;
cout<< "\tOffsetUV " << f << " " ;
plg = fn.findPlug("ofv");
plg.getValue(f);
cout << f << endl;

// the rotation angle for the uv coords
plg = fn.findPlug("r");
plg.getValue(f);
cout<< "\tRotateUV " << f;

// The noise in the U & V texture directions
plg = fn.findPlug("nu");
plg.getValue(f);;
cout<< "\tNoiseUV " << f << " " ;
plg = fn.findPlug("nv");
plg.getValue(f);
cout << f << endl;

}


 

 

 

 

What Next?

Material Data

Animation Curves

index

Rob Bateman [2004]


[HOME] [MEL] [API]