How To ... Output Object Data To File

MAXScript lets you create text files on disk and output custom data. The following example will create a macroScript that will output the speed of the current object selection on each frame and its average speed to a text file.

Related Topics:

Defining Macroscripts

Save File Dialog

Text Files Creation and Output

NATURAL LANGUAGE

Package the code as macroScript to be able to use as a button, menu item, or shortcut.

Let the user specify an output filename to save the information.

Write out the list of all selected objects as the file header.

Go through all frames in the current animation segment, get the selection’s position on the current frame and the frame before, and calculate the units per frame speed.

Write out the result for each frame.

Collect all frame speed values and divide by the length of the animation segment to get the average speed.

Write out the average speed result.

Show the user the result by opening the file in an Editor.

MAXSCRIPT

macroScript SpeedSheet category:"HowTo"
(
if selection.count > 0 then
(
  output_name = getSaveFileName caption:"SpeedSheet File" types:"SpeedSheet (*.ssh)|*.ssh|All Files (*.*)|*.*|"
  if output_name != undefined then
 (
  output_file = createfile output_name
  at time animationrange.start format "Object(s): %\n" (selection as array) to:output_file
  average_speed = 0
  for t = animationrange.start to animationrange.end do
  (
  at time t current_pos = selection.center
  at time(t-1f) last_pos = selection.center
  frame_speed = (distance current_pos last_pos)*FrameRate
  average_speed += frame_speed
  format "Frame %: %\n" t frame_speed to:output_file
  )
  average_speed /= (animationrange.end-animationrange.start)
  format "Average Speed: %\n" average_speed to:output_file
  close output_file
  edit output_name
 )--end if
)--end if
)--end macroScript


Step-By-Step:

MacroScript SpeedSheet category:"HowTo"
(

We create a new macroScript called SpeedSheet that will appear in the "HowTo" category.

Defining Macro Scripts

if selection.count > 0 then
(

The script will function only if there is at least one object selected. We check the number of objects in the current scene selection and execute the code only if the number is higher than 0.

ObjectSet Values

output_name = getSaveFileName caption:"SpeedSheet File" types:"SpeedSheet (*.ssh)|*.ssh|All Files (*.*)|*.*|"

Then, we present the user with a standard windows File Saving dialog box. The dialog title bar will show the custom caption string "SpeedSheet File". We specify the default file type as .SSH (SpeedSheet) file. If the user types in a file name, the extension specified in the dialog is being added automatically.

Standard Open and Save File Dialogs

if output_name != undefined then
(

If the user canceled the file selection in the Save File Name dialog, the output_name variable will contain undefined. In such a case, we will have to skip the whole output code. If the file name is valid, we can go on.

output_file = createfile output_name

Then, we create a new file for output using the specified file name. If the file already exists, it will be overwritten.

FileStream Values

at time animationrange.start format "Object(s): %\n" (selection as array) to:output_file

Right after creating the file, we write out the names of the selected objects. The at time context ensures that position data of the objects is printed out for the first frame in the animation. The format method uses a formatting string where variables are denoted with %. "\\n" forces a new line.

at time

3ds MaxSystem Globals

FileStream Values

average_speed = 0

To calculate the average speed, we initialize a variable to store all speed values for all frames.

for t = animationrange.start to animationrange.end do
(

Now, we go through all frames in the current animation segment. The variable t will contain a frame value which will change from the first to the last frame of the scene animation range.

For Loop

AnimationRange_Time_Configuration

at time t current_pos = selection.center

Using the current time from the for loop variable t , we read the position of the center of the object selection.

at time

ObjectSet Values

at time (t-1f) last_pos = selection.center

Then, we read the position of the selection center one frame before the current frame.

frame_speed = (distance current_pos last_pos)*FrameRate

The frame speed on the current frame is equal to the distance traveled by the selection center since the last frame, multiplied by the frame number in a second. This gives us a speed in Generic Units per second.

Distance_Point3

FrameRate_Time_Configuration

average_speed += frame_speed

The average speed variable collects all frame speed values. Note that the same can be expressed in the full form as average_speed = average_speed + frame_speed .

Format "Frame %: %\n" t frame_speed to:output_file

The frame speed is written together with the frame number to the output file.

FileStream Values

)
average_speed /= (animationrange.end - animationrange.start)

After the loop is over, the average speed can be calculated by dividing the sum of all frame speed values through the number of frames. The same can be written as average_speed = average_speed / (animationrange.end-animationrange.start) .

AnimationRange_Time_Configuration

format "Average Speed: %\n" average_speed to:output_file

The result is printed out to the output file.

Close output_file

The file is ready. We must close it before we can open it for reading.

close_fileStream

edit output_name

Using the edit method, we open the file in a Scripting Editor window.

edit_MAXScript_Editor

)--end if
)--end if
)--end macroScript

Using the Script

Evaluate the script and customize a toolbar by dragging the SpeedSheet button from the "HowTo" category. You can create any number of objects and animate their position. While the objects are selected, press the SpeedSheet button, specify the name of the output file and the result appears in a second.

Where to go from here

If you want to see the content of the text file in an external editor, for example in Windows Notepad, you can replace the line,

edit output_name

with the line,

shellLaunch "notepad.exe" output_name

which will launch the external application notepad.exe with the file name of the file as parameter.

You might want to improve the script by calculating real-world units (inches, feet, meters, and so on) instead of generic units.

Back to

"How To" Tutorials Index Page