View Full Version : How to get MEL script to read multiple columns

02 February 2011, 08:34 PM

I've been working on a project that involves using Maya and MEL scripting. The code I have currently reads a text file with 3 translation coordinates and 3 rotation coordinates, which are arranged in 6 columns and many rows. The idea is to read through the first row, getting the x,y,z translation and then x,y,z rotation, moving the selected object. However, my code will only read down the first column, and doesn't even read the other 5 columns. The code is shown below, can anyone tell me why it's only reading down the first column and not across the rows? Thanks.

float $joint1Angle, $xVal, $yVal, $zVal, $xRot, $yRot, $zRot;
int $fileid;

// need to load the robot (needs to be in current directory)
file -o -f "C:/MayaPolaris/arm6.mb";
refresh -f;

// in order to test the robot, will read in points from a file
$fileid = fopen("C:/MayaPolaris/new.txt","r");
if ($fileid == 0)
print("ERROR: Problem reading in text file.\n");

// iterate through text file, collecting each set of x,y,z coordinates
// pass coordinates to Maya to show planned robot trajectory
string $nextWord = fgetword($fileid," \n");
while (size($nextWord) > 0) {
// each iteration of this while loop corresponds to one robot position
$xVal = $nextWord;
$yVal = fgetword($fileid," \n");
$zVal = fgetword($fileid," \n");
$xRot = fgetword($fileid," \n");
$yRot = fgetword($fileid," \n");
$zRot = fgetword($fileid," \n");

// this is all the code that is needed to get the robot in the correct
// position

setAttr "r_humerus.translateX" $xVal;
setAttr "r_humerus.translateY" $yVal;
setAttr "r_humerus.translateZ" $zVal;
setAttr "r_humerus.rotateX" $xRot;
setAttr "r_humerus.rotateY" $yRot;
setAttr "r_humerus.rotateZ" $zRot;

// delay by 1 second for visualization
refresh -f;
pause -sec 0.5;

$nextWord = fgetword($fileid," \n");


02 February 2011, 10:56 PM
I suppose the layout of your file looks like the following:

tx1 ty1 tz1 rx1 ry1 rz1
tx2 ty2 tz2 rx2 ry2 rz2

To read this it is much more conveniant to read one line at once with fgetline().

string $line = fgetline(fileID);
string $array[];
tokenize " " $line $array; //I'm not sure about the syntax here
setAttr yourObject.translate (float)$array[0] (float)$array[1] (float)$array[2];
setAttr yourObject.rotate (float)$array[3] (float)$array[4] (float)$array[4];
$line = fgetline(fileID);

Or a bit shorter with python:

fh = open("file.txt", "r")
for line in fh:
tx, ty, tz, rx, ry, rz = map(float, line.split())
cmds.setAttr("yourObject.translate", tx, ty, tz)
cmds.setAttr("yourObject.rotate", rx, ry, rz)

Or even shorter with pymel:

fh = open("file.txt", "r")
yourObject = PyNode("yourObject")
for line in fh:
v = map(float, line.split())

I didnt test this code so there are maybe some errors.

edit: Just saw that your file layout seems to be more like this:

So it may be a bit different. But the getline() is here useful too with the difference that it returns only one value.
The code above coule be modified this way:

while($line= fgetline(fileID))
string $array[];
$array[0] = $line;
// read the next 5 lines
for(int i = 0; i < 5; i++)
$array[size($array)] = fgetline(fileID);

tokenize " " $line $array; //I'm not sure about the syntax here
setAttr yourObject.translate (float)$array[0] (float)$array[1] (float)$array[2];
setAttr yourObject.rotate (float)$array[3] (float)$array[4] (float)$array[4];

CGTalk Moderation
02 February 2011, 10:56 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.