MEL Scripting: How To Read A Text File
0 Comments
Page 1 of 1
The original tutorial can be found here: https://www.scriptswell.net/2010/09/mel-tutorial-how-to-read-text-file.html
Knowing how to read and write a file in MEL is one of the skills you need to have as a scripter. Maybe the file contains animation data you need to access, or skin weighting data, or even a list of objects needed in a scene. It can contain almost any type of data and at some point or another it will be your job to get that information out of the file and into Maya. This tutorial will show you how to do it.
Skill Level: Beginner to Intermediate
First off we need a data file to test with, so let's make one. Open up your favorite text editor (notepad will work if you don't have anything else), create a new .TXT file. and save it somewhere as "myDataFile.txt". For this lesson, I recommend saving your file somewhere with a relatively simple file path, e.g. "C:\mel\myDataFile.txt".
Copy and paste the following data into your file and save:
-----------------------------------------------------------
Tip: The file doesn't necessarily have to use a .TXT file extension. Any text-based file format will work the same way. You can even make up your own file extension. I like to use .RIG files.
-----------------------------------------------------------
Now that we have a file to test with let's look at what's in it. It's important to look at what type of data you're working with so you can plan on how to bring it in and in what format you'll need it to be in once it's in Maya.
In this case there are multiple lines of text, with each line having ten values separated by commas. We refer to this type of data as comma-separated. Our example has the name of an object and it's nine transform values (translate X,Y,Z, rotate X,Y,Z, scale X,Y,Z). Note that the first line doesn't have any actual values, it just serves to tell us what each value represents. This is common in data files. You may need to adjust your script to skip the first line when it brings in the data.
Using this data we're going to find the objects in our Maya scene and set their transforms. Let's get to it!
The first part of our script is putting the path to the file we just created into a string variable.
-----------------------------------------------------------
Tip: File paths in Maya (and most packages) require that you use forward slashes (/) instead of backslashes (\). You will get errors if you use backslashes.
-----------------------------------------------------------
Now that we have the path saved in $filePath we're going to use a MEL command called fopen . This command tells Maya to find the file and open it and also tells Maya what we're going to do with the file. There is an optional string argument (I recommend always using it) that will tell Maya if you're going to just read the file, write to it, or append to the end of the existing file. Check out the MEL Documentation for a more in-depth description on how these work, but for now just be aware that since we're reading the data from the file, we're going to use "r" for read.
// Open Your File
$fileId = `fopen $filePath "r"` ;
With the line of code above we've stored our "open" file into the variable $fileId. Now anytime we want to refer to that file in our script we can refer to $fileId. By using the "r" string in the command we've also told Maya that it only has permission to read from the file and nothing else. This way we don't have to worry about the file being changed in any way.
-----------------------------------------------------------
Tip: In the fread command, besides "r" (read), you can also use "w" (write) or "a" (append). More on this in the next tutorial.
-----------------------------------------------------------
Now that the file is open, let's interact with it. There are two commands we're going to look at in this tutorial. The first command is fread. This is used in the following way:
// Read The Data Using fread
string $data = `fread $fileId $data` ;
The usage is a little odd since we're simultaneously defining a string variable and using it as an argument in the command, but this is the way fread works. What it will do is take all of your data in the file and return it as a single string. In this case our return string value would be:
Nice! All of the data from the text file is in Maya! Success!
The only problem is...ALL of that information is in a single string. It's not much use to you in this format since the actual data is dense and on multiple lines. If you really wanted to you could take that string and break it up into all of the data you need (a mixture of loops and heavy usage of MEL's tokenize command)...but there's an easier way to handle it. There is another command we can use called fgetline.
The fgetline command will get a single line of data from the file and put it into a string variable. This becomes useful because we can now create a string array and put each line into it separately. This will give us a string array containing our entire text file.
The only hiccup here is fgetline will simply get one line of text and then stop. It's not smart enough to continue through the whole text file, we have to tell it to do that. We do this with a WHILE loop. Check it out below ...let's combine everything we've done so far:
// Define Your File Path
string $filePath = "C:/mel/myDataFile.txt" ;
// Open Your File
$fileId = `fopen $filePath "r"` ;
// Get The First Line
string $nextLine = `fgetline $fileId` ;
// Loop Until The String Size Is Zero (No Data)
while (size($nextLine) > 0) {
// Strip Whitespace From The Beginning And End Of The Line
string $cleanLine = strip($nextLine) ;
// Print Line
print ($cleanLine+"\n") ;
// Get Next Line And Continue
$nextLine = `fgetline $fileId` ;
}
If you run this, you'll see Maya print out the five lines of our text file. This time, each of those lines was printed one at a time. Ultimate success!
Let's make a few more additions and turn this into a procedure. First I want it to return an array, so I'm going to define a string array and then put each of my lines into it when I get them from the text file. Next I want to add an argument to tell it to skip the first line. This is useful if I know the first line of my file contains data I don't want. Lastly, instead of hard coding the path into the function, I want to pass the file path into my procedure as an argument to make it more versatile.
When we're finished our procedure looks like this:
// **********************************************************
// Reads A Text File And Returns A String Array Of Each Line
global proc string[] jgTextFileToStringArray (int $skipFirstLine, string $filePath) {
// Open File
$fileId = `fopen $filePath "r"` ;
// Define String Array
string $dataArray[] ;
// Get The First Line
string $nextLine = `fgetline $fileId` ;
// Loop Until The String Size Is Zero (No Data On That Line)
while (size($nextLine) > 0) {
// Strip Whitespace From The Beginning And End Of The Line
string $cleanLine = strip($nextLine) ;
// Add To Array
$dataArray[size($dataArray)] = $cleanLine ;
// Get Next Line And Continue
$nextLine = `fgetline $fileId` ;
}
// Remove First Line
if($skipFirstLine) stringArrayRemoveAtIndex(0,$dataArray) ;
// Return Array
return $dataArray ;
}
The next tutorial will extend on this and go over how to write to and append to a text file.
Leave a comment below if you found this helpful or have any questions.
For more free mel scripts and tutorials, please visit Script Swell
Knowing how to read and write a file in MEL is one of the skills you need to have as a scripter. Maybe the file contains animation data you need to access, or skin weighting data, or even a list of objects needed in a scene. It can contain almost any type of data and at some point or another it will be your job to get that information out of the file and into Maya. This tutorial will show you how to do it.
Skill Level: Beginner to Intermediate
First off we need a data file to test with, so let's make one. Open up your favorite text editor (notepad will work if you don't have anything else), create a new .TXT file. and save it somewhere as "myDataFile.txt". For this lesson, I recommend saving your file somewhere with a relatively simple file path, e.g. "C:\mel\myDataFile.txt".
Copy and paste the following data into your file and save:
//objectName,posX,posY,posZ,rotX,rotY,rotZ,scaleX,scaleY,scaleZ
pCube1,0,0,0,0,0,0,1,1,1
pSphere1,-5,10,-5,-90,90,-45,1,1,1
pCylinder1,2.5,2.342,4.2823,0,0,0,1,1,1
pPlane1,0,0,0,360,180,45,1,1,1
pCube1,0,0,0,0,0,0,1,1,1
pSphere1,-5,10,-5,-90,90,-45,1,1,1
pCylinder1,2.5,2.342,4.2823,0,0,0,1,1,1
pPlane1,0,0,0,360,180,45,1,1,1
//objectName,posX,posY,posZ,rotX,rotY,rotZ,scaleX,scaleY,scaleZ
pCube1,0,0,0,0,0,0,1,1,1
pSphere1,-5,10,-5,-90,90,-45,1,1,1
pCylinder1,2.5,2.342,4.2823,0,0,0,1,1,1
pPlane1,0,0,0,360,180,45,1,1,1
-----------------------------------------------------------
Tip: The file doesn't necessarily have to use a .TXT file extension. Any text-based file format will work the same way. You can even make up your own file extension. I like to use .RIG files.
-----------------------------------------------------------
Now that we have a file to test with let's look at what's in it. It's important to look at what type of data you're working with so you can plan on how to bring it in and in what format you'll need it to be in once it's in Maya.
In this case there are multiple lines of text, with each line having ten values separated by commas. We refer to this type of data as comma-separated. Our example has the name of an object and it's nine transform values (translate X,Y,Z, rotate X,Y,Z, scale X,Y,Z). Note that the first line doesn't have any actual values, it just serves to tell us what each value represents. This is common in data files. You may need to adjust your script to skip the first line when it brings in the data.
Using this data we're going to find the objects in our Maya scene and set their transforms. Let's get to it!
The first part of our script is putting the path to the file we just created into a string variable.
// Define Your File Path
string $filePath = "C:/mel/myDataFile.txt" ;
string $filePath = "C:/mel/myDataFile.txt" ;
// Define Your File Path
string $filePath = "C:/mel/myDataFile.txt" ;
-----------------------------------------------------------
Tip: File paths in Maya (and most packages) require that you use forward slashes (/) instead of backslashes (\). You will get errors if you use backslashes.
-----------------------------------------------------------
Now that we have the path saved in $filePath we're going to use a MEL command called fopen . This command tells Maya to find the file and open it and also tells Maya what we're going to do with the file. There is an optional string argument (I recommend always using it) that will tell Maya if you're going to just read the file, write to it, or append to the end of the existing file. Check out the MEL Documentation for a more in-depth description on how these work, but for now just be aware that since we're reading the data from the file, we're going to use "r" for read.
// Open Your File
$fileId = `fopen $filePath "r"` ;
// Open Your File
$fileId = `fopen $filePath "r"` ;
With the line of code above we've stored our "open" file into the variable $fileId. Now anytime we want to refer to that file in our script we can refer to $fileId. By using the "r" string in the command we've also told Maya that it only has permission to read from the file and nothing else. This way we don't have to worry about the file being changed in any way.
-----------------------------------------------------------
Tip: In the fread command, besides "r" (read), you can also use "w" (write) or "a" (append). More on this in the next tutorial.
-----------------------------------------------------------
Now that the file is open, let's interact with it. There are two commands we're going to look at in this tutorial. The first command is fread. This is used in the following way:
// Read The Data Using fread
string $data = `fread $fileId $data` ;
// Read The Data Using fread
string $data = `fread $fileId $data` ;
The usage is a little odd since we're simultaneously defining a string variable and using it as an argument in the command, but this is the way fread works. What it will do is take all of your data in the file and return it as a single string. In this case our return string value would be:
// Result: objectName,polygonType,posX,posY,posZ,rotX,rotY,rotZ,scaleX,scaleY,scaleZ
pCube1,0,0,0,0,0,0,1,1,1
pSphere1,-5,10,-5,-90,90,-45,1,1,1
pCylinder1,2.5,2.342,4.2823,0,0,0,1,1,1
pPlane1,0,0,0,360,180,45,1,1,1//
pCube1,0,0,0,0,0,0,1,1,1
pSphere1,-5,10,-5,-90,90,-45,1,1,1
pCylinder1,2.5,2.342,4.2823,0,0,0,1,1,1
pPlane1,0,0,0,360,180,45,1,1,1//
// Result: objectName,polygonType,posX,posY,posZ,rotX,rotY,rotZ,scaleX,scaleY,scaleZ
pCube1,0,0,0,0,0,0,1,1,1
pSphere1,-5,10,-5,-90,90,-45,1,1,1
pCylinder1,2.5,2.342,4.2823,0,0,0,1,1,1
pPlane1,0,0,0,360,180,45,1,1,1//
Nice! All of the data from the text file is in Maya! Success!
The only problem is...ALL of that information is in a single string. It's not much use to you in this format since the actual data is dense and on multiple lines. If you really wanted to you could take that string and break it up into all of the data you need (a mixture of loops and heavy usage of MEL's tokenize command)...but there's an easier way to handle it. There is another command we can use called fgetline.
The fgetline command will get a single line of data from the file and put it into a string variable. This becomes useful because we can now create a string array and put each line into it separately. This will give us a string array containing our entire text file.
The only hiccup here is fgetline will simply get one line of text and then stop. It's not smart enough to continue through the whole text file, we have to tell it to do that. We do this with a WHILE loop. Check it out below ...let's combine everything we've done so far:
// Define Your File Path
string $filePath = "C:/mel/myDataFile.txt" ;
// Open Your File
$fileId = `fopen $filePath "r"` ;
// Get The First Line
string $nextLine = `fgetline $fileId` ;
// Loop Until The String Size Is Zero (No Data)
while (size($nextLine) > 0) {
// Strip Whitespace From The Beginning And End Of The Line
string $cleanLine = strip($nextLine) ;
// Print Line
print ($cleanLine+"\n") ;
// Get Next Line And Continue
$nextLine = `fgetline $fileId` ;
}
// Define Your File Path
string $filePath = "C:/mel/myDataFile.txt" ;
// Open Your File
$fileId = `fopen $filePath "r"` ;
// Get The First Line
string $nextLine = `fgetline $fileId` ;
// Loop Until The String Size Is Zero (No Data)
while (size($nextLine) > 0) {
// Strip Whitespace From The Beginning And End Of The Line
string $cleanLine = strip($nextLine) ;
// Print Line
print ($cleanLine+"\n") ;
// Get Next Line And Continue
$nextLine = `fgetline $fileId` ;
}
If you run this, you'll see Maya print out the five lines of our text file. This time, each of those lines was printed one at a time. Ultimate success!
Let's make a few more additions and turn this into a procedure. First I want it to return an array, so I'm going to define a string array and then put each of my lines into it when I get them from the text file. Next I want to add an argument to tell it to skip the first line. This is useful if I know the first line of my file contains data I don't want. Lastly, instead of hard coding the path into the function, I want to pass the file path into my procedure as an argument to make it more versatile.
When we're finished our procedure looks like this:
// **********************************************************
// Reads A Text File And Returns A String Array Of Each Line
global proc string[] jgTextFileToStringArray (int $skipFirstLine, string $filePath) {
// Open File
$fileId = `fopen $filePath "r"` ;
// Define String Array
string $dataArray[] ;
// Get The First Line
string $nextLine = `fgetline $fileId` ;
// Loop Until The String Size Is Zero (No Data On That Line)
while (size($nextLine) > 0) {
// Strip Whitespace From The Beginning And End Of The Line
string $cleanLine = strip($nextLine) ;
// Add To Array
$dataArray[size($dataArray)] = $cleanLine ;
// Get Next Line And Continue
$nextLine = `fgetline $fileId` ;
}
// Remove First Line
if($skipFirstLine) stringArrayRemoveAtIndex(0,$dataArray) ;
// Return Array
return $dataArray ;
}
// **********************************************************
// Reads A Text File And Returns A String Array Of Each Line
global proc string[] jgTextFileToStringArray (int $skipFirstLine, string $filePath) {
// Open File
$fileId = `fopen $filePath "r"` ;
// Define String Array
string $dataArray[] ;
// Get The First Line
string $nextLine = `fgetline $fileId` ;
// Loop Until The String Size Is Zero (No Data On That Line)
while (size($nextLine) > 0) {
// Strip Whitespace From The Beginning And End Of The Line
string $cleanLine = strip($nextLine) ;
// Add To Array
$dataArray[size($dataArray)] = $cleanLine ;
// Get Next Line And Continue
$nextLine = `fgetline $fileId` ;
}
// Remove First Line
if($skipFirstLine) stringArrayRemoveAtIndex(0,$dataArray) ;
// Return Array
return $dataArray ;
}
The next tutorial will extend on this and go over how to write to and append to a text file.
Leave a comment below if you found this helpful or have any questions.
For more free mel scripts and tutorials, please visit Script Swell
Page 1 of 1
Author: Jay Grenier
Submitted: 2010-10-19 21:25:53 UTC
Tags: data file, fread, fopen, fgetline, mel, file, write, and read
Software: Maya
Views: 16,369
Related Items
-
Gradient Data Manager script for Maya for Maya 1.1.1 (maya script)
$20.00 (USD) -
Animation Data Recovery 1.1.0 for Maya (maya script)
$100.00 (USD) -
File Batch Exporter 1.6.2 for Maya (maya script)
$20.00 (USD) -
UHF Military data radio 3D Model
$49.00 (USD) -
Folder Management for Animation Production pipeline 1.1.0 for Maya (maya script)
$25.00 (USD) -
Easy Environment for Maya 1.6.1 (maya script)
$90.00 (USD) -
Simple Tools Asset Manager 0.9.10 for Maya (maya script)
$20.00 (USD) -
3D Thumbnail Generator (batch script) for Maya 0.3.1 (maya script)
$20.00 (USD) -
Curve Library 1.7.0 for Maya (maya script)
$20.00 (USD)