Community
Maya Forum
Welcome to Autodesk’s Maya Forums. Share your knowledge, ask questions, and explore popular Maya topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Question: Creating renderable measurement values

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
Anonymous
489 Views, 7 Replies

Question: Creating renderable measurement values

I'm creating a series of animations that illustrate the clearance between different objects as they animate.

For example: 

Imagine an infographic that depicts a couch being carried up a flight of stairs.  The animation seeks to depict how much clearance there is between the top of the couch and the ceiling of the stairwell.  Those values will change as the couch is maneuvered up the stairs.

 

What I'd like to be able to do is employ the measurement tool to capture those values between a chosen point on the couch and a chosen point on the ceiling.  Unfortunately there is no built in option to render the measurement tool.

So here's what I'm thinking:

I could try to find a way, via MEL scripting, to export the frame by frame measurement value provided by the measurement tool (which I assume is stored somewhere as a float value) and then add that value in as a layer in AfterEffects (which I assume could be imported, to avoid having to manually enter each value on what could potentially be hundreds if not thousands of frames).

This is the direction I intend to take with my initial research.  I'm wondering if any of you have tackled similar problems in the past using Maya and if you could recommend any additional approaches or areas I could research to help me develop a successful workflow. 

Also, I apologize if I've posted this in the wrong area.  I'm a first time poster and I wasn't sure if this qualified for a more specific area of the forum.  Constructive scolding is welcome.

Tags (3)
7 REPLIES 7
Message 2 of 8
osidedan
in reply to: Anonymous

Haha no need for constructive scolding, this is indeed doable!

Using Python in maya,  and expressions in Aftereffects, I was able to achieve what you are after. (Of note, I did this all on Windows, so you may need to adjust file paths accordingly for using OSX or Unix.)

To start, we need to write the distance between the objects per frame to a file that aftereffects can read. This python script will do that. first off, set your time slider to the range of frames you want. Then select the two objects you want to measure the distance on, and run this in a python window in the script editor. (note: change the part "D:\\output_file.txt" to where you want the file to be saved, and use double back slashes for ALL backslashes in your path. It's just safer that way for python, and also make sure the folder you're saving to exists) 

 

import maya.cmds as cmds
import math

def distance_between_two_objects_over_time():
    start_time = cmds.playbackOptions(query=True,minTime=True)
    end_time = cmds.playbackOptions(query=True,maxTime=True)
    original_time = cmds.currentTime(query=True)
    counter = int(start_time)
    frame_index = 0
    output_file = open('D:\\output_file.txt', "w")
    while (counter <= end_time):
        cmds.currentTime( counter, edit=True)
        selection = cmds.ls(sl=True)
        p1 = cmds.xform(selection[0],query=True,translation=True, worldSpace=True)
        p2 = cmds.xform(selection[1],query=True,translation=True, worldSpace=True)
        distance = distance_between_two_points(p1,p2)
        distance = round(distance,2)
        output_file.write('frame' + str(frame_index) + ' = ' + str(distance))
        output_file.write("\n")
        counter += 1
        frame_index += 1
    output_file.close()

   
def distance_between_two_points(p1, p2):
    return math.sqrt( ((p2[0] - p1[0])*(p2[0] - p1[0])) + ((p2[1] - p1[1])*(p2[1] - p1[1])) + ((p2[2] - p1[2])*(p2[2] - p1[2])))
    
distance_between_two_objects_over_time()

 

 

If you get no errors, you should end up with a file with all the distance info per frame in it, line by line. Now you just need to source that file in Aftereffects. On a text layer, under Text>source text, option left-click the stopwatch to bring up the expressions field. Paste the following in, but change the path to the path where you saved out the file from maya:

currentFrame = timeToFrames(time);
$.evalFile("D:\output_file.txt");
eval("frame" + currentFrame );

 

 

That should be all you need to get it to work!

 

Of note, if you need more or less accuracy in your numbers, you can change the rounding value in the maya python script to do so. On the line "distance = round(distance,2)" the number there is how many decimal places it keeps.

 

Let me know if you need more info, or if you run into trouble on anything. And if you're interested on the hows and whys of how these scripts work let me know, I am more than happy to elaborate.

 

 

Message 3 of 8
Anonymous
in reply to: osidedan

Thank you SO MUCH!

I'm going to attempt to implement this ASAP. 

I'll report back as things progress.

Message 4 of 8
Anonymous
in reply to: osidedan

I implemented the Python script in Maya as instructed and it worked perfectly.

I also implemented the Java script in After Effects to pull the data from the text file and it worked initially then threw the following error:

 

After Effects warning:  Expression disabled Error at line 1 in property 'Source Text' of layer 1 ("Distance Counter") in comp 'Comp 1'.

property or method named 'frame899' in Class 'global' is missing or does not exist.  It may have been renamed, moved, deleted, or the name may have been mistyped.

 

At first I thought I must have mistyped something but I've reviewed all of my code and it is identical to the code that was posted.  I also made sure that the file path to my text file was correct and that the formatting withing the outputted text file was correct.  As far as I can tell everything is typed and formatted properly.

 

I'm especially puzzled by the 'frame899' reference.  I can't seem to find what method or property it is referring to.  The animation I created to test the script was only 120 frames long (0 - 119 in the outputted text file of course).

 

I suspect it is something minute that would be immediately obvious to a seasoned code wrangler and I intend to keep digging until I can  hopefully identify the issue...  But if you can provide any additional insight I'd be grateful.

 

Thanks again!

Message 5 of 8
Anonymous
in reply to: Anonymous

Okay.  Small update.

 

I think the problem has something to do with how the addressing works in the third line of the expression.

 

If I delete the third line, the error disappears but the text layer will only display the last value in the text file (which makes sense because it hasn't been instructed to step through them one per frame).  If instead I add an absolute address in as the third line like so:

 

currentFrame = timeToFrames(time);

$.evalFile("D:\output_file.txt");

frame16

 

The text layer will display the value stored at frame 16 in the text file without fail and without throwing any errors.

 

So it's not an issue with those first two lines (I think...) and it's not a problem for After Effects to locate and access the text document.  The problem lies somewhere in how the expression is using relative addressing to move through the text.  Again, I'm absolutely certain this is something super obvious but I figured trying to logic my way through it is better than simply doing nothing.  (And I'm learning all sorts of new things about scripting and expressions.)

Message 6 of 8
Anonymous
in reply to: Anonymous

Solved!

It turns out that, in the third line of the expression, I had added a space before and after the + symbol.

I got rid of the spaces and it worked perfectly!  SMH  So SIMPLE!

I actually figured it out kind of by accident.  I had gotten rid of "frame" in the third line to see what would happen.  As you most likely know it simply ran through the frame numbers without referencing the text file (useful to know should I ever want to simply display frame count in a text layer).  I realized that I'd narrowed down the issue even further and I knew that "frame" was the proper syntax so the only logical thing left was the + sign and the spaces surrounding it.  And that turned out to be the issue.

 

Thanks again for the help!   Here's the expression written in the format that finally worked for me:

 

currentFrame = timeToFrames(time);

$.evalFile("D:\output_file.txt");

eval("frame"+currentFrame);

Message 7 of 8
Anonymous
in reply to: Anonymous

One last VERY important thing!

 

Again, this is probably obvious to everyone but me...  In order for this expression to work properly with the generated text file inside of After Effects you have to make sure that you set your composition's framerate to 30 FPS.

 

If you don't, and you leave it at 29.97 like I did initially, the math gets a little wonky and it won't move through the text file in the proper order.  (I think that's where that error about frame 899 was coming from.)

 

I apologize for turning this into a conversation about After Effects in a Maya forum...  The Python script for Maya worked swimmingly right out of the gate.

 

Thanks!

Message 8 of 8
osidedan
in reply to: Anonymous

I'm glad you got it to work! Good point about the framerate too. Most of the stuff I tinker with is for games, so I just default to 30fps haha. And no worries about it turning into an aftereffects conversation. At some point I'm sure someone will have a similar issue, and it's better to have it documented than not. Cheers!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report