Extracting text file data to position locators

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  04 April 2013
Extracting text file data to position locators

Hi all,

I have a bit of a question. I have recently used a 3D body scanner which produces a poly mesh. As well as the mesh, it spits out some calculated joint data in the form of a text file.

l_hip -15.22 127.56 952.51
l_knee -47.39 138.57 533.75
l_ankle -110.90 173.47 83.75
r_hip -22.36 -106.86 955.30
r_knee -56.79 -129.64 533.75
r_ankle -119.39 -158.64 86.25
vt1 -44.42 15.58 1646.25
l_sternoclavicular 23.64 31.85 1543.75
l_acromioclavicular -36.22 154.16 1593.75
l_shoulder 6.57 205.15 1541.67
l_elbow -68.07 288.34 1197.53
l_wrist 9.34 331.81 931.83
r_sternoclavicular 21.43 -8.09 1543.75
r_acromioclavicular -41.66 -173.09 1571.25
r_shoulder -21.36 -196.89 1533.80
r_elbow -113.08 -253.15 1193.21
r_wrist -35.14 -335.73 924.99
sacroiliac -82.33 4.57 1133.75


Is it possible, using MEL or Python, to extract this positional data and place locators (or even joints) at the locations given in the text file?

Thanks,

Andy
 
  04 April 2013
Yes!
Have a crack at it and post your code if you get stuck.

David
__________________
http://www.djx.com.au
 
  04 April 2013
Originally Posted by djx: Yes!
Have a crack at it and post your code if you get stuck.

David


I'm really new to scripting so I really don't quite know where to start. I've managed to get Maya to read the text file as string lines with the following code:

string $filePath = "H:/My Documents...filename.joints";
$fileId = `fopen $filePath "r"`;
string $nextLine = `fgetline $fileId`;
while (size($nextLine) > 0) {
    string $cleanLine = strip($nextLine);
    print ($cleanLine+"\n");
    $nextLine = `fgetline $fileId`;
}


However I think I'm a long way off being able to take the floating point values from this. Can you point me in the right direction?
 
  04 April 2013
look at the Tokenize command to split each line into separate components.
 
  04 April 2013
Originally Posted by rgkovach123: look at the Tokenize command to split each line into separate components.


Thanks, that helps a bit. I have this code now which splits the lines up and stores the parts as name, X, Y and Z:

string $filePath = "H:/My Documents...filename.joints";
$fileId = `fopen $filePath "r"`;
string $nextLine = `fgetline $fileId`;
string $trans[];
while (size($nextLine) > 0) {
    string $cleanLine = strip($nextLine);
    int $numTokens = `tokenize $cleanLine " " $trans`;
    string $name = $trans[0];
    float $X = $trans[1];
    float $Y = $trans[2];
    float $Z = $trans[3];
    print $trans;
    $nextLine = `fgetline $fileId`;
};


It returns the following for each line of the text file:
l_hip
-15.22
127.56
952.51

I guess what I now need to do is put these to some use.
The name needs to correspond to the locator (or joint) and the values need using as a float to position the XYZ co-ordinates.

Any help would be appreciated.

Last edited by andyman121 : 04 April 2013 at 06:12 PM.
 
  04 April 2013
I presume also that I will have to index it somehow by line? If I print $name or any of the other vars it comes out as a big long line of unseparated values.
 
  04 April 2013
OK so I think I've cracked it to place locators at the positions given in the text file:

{
    string $filename = "H:/My Documents...filename.joints";
    int $fileId = `fopen $filename "r"`;
    if (!`filetest -f $filename`) error "Specified File not Found!";
    while (!`feof $fileId`)
    {
        string $nextLine = `fgetline $fileId`;
        string $token[];
        while (size($nextLine) > 0)
        {
            string $cleanLine = strip($nextLine);
            tokenize $nextLine " " $token;
            string $name = $token[0];
            float $x = $token[1];
            float $y = $token[2];
            float $z = $token[3];
            spaceLocator -n $name -p ($x / 100) ($y / 100) ($z / 100);
            $nextLine = `fgetline $fileId`;
        }
    }
    fclose $fileId;
}
select -all;
rotate -90deg -90deg 0;
FreezeTransformations;
select -clear;


I tried replacing spaceLocator with joint to see if the same code would place joints at the locations, but for some reason they came out in a different position slightly further forward in the Z-axis and parented in order that they were drawn (I kind of expected that bit).

Thanks a lot for your help, and if you spot any mistakes or can think of how I might develop this please let me know.
 
  04 April 2013
That's pretty good. Just a few comments.

Generally you should avoid doing selections in the script. It is usually better to catch the names returned by the command into an array or string, depending on the command. And I usually try to avoid the high level commands like FreezeTransformations.

You could simplify the transformation into maya's coordinate space by rearranging the way you interpret the axes.

Based on your script I changed as follows:
{
	string $filename = "U:/mayaProjects/cgtalk/data/locationData.txt";
	int $fileId = `fopen $filename "r"`;
	if (!`filetest -f $filename`) error "Specified File not Found!";
	string $locators[] = {};
	while (!`feof $fileId`){
		string $nextLine = `fgetline $fileId`;
		string $token[];
		while (size($nextLine) > 0){
			string $cleanLine = strip($nextLine);
			tokenize $nextLine " " $token;
			string $name = $token[0];
			float $x = $token[1];
			float $y = $token[2];
			float $z = $token[3];
			string $locators[] = `spaceLocator -n $name -p ($y / 100) ($z / 100) ($x / 100)`;
			makeIdentity -a 1 $locators[0];
			$nextLine = `fgetline $fileId`;
		}
	}
	fclose $fileId;
}


For joints, you could get them in the right place by clearing the selection between creations (since creating a new joint leaves it selected, and as you already know, subsequent creations are parented to the previous one)

{
	string $filename = "U:/mayaProjects/cgtalk/data/locationData.txt";
	int $fileId = `fopen $filename "r"`;
	if (!`filetest -f $filename`) error "Specified File not Found!";
	string $locators[] = {};
	while (!`feof $fileId`){
		string $nextLine = `fgetline $fileId`;
		string $token[];
		while (size($nextLine) > 0){
			string $cleanLine = strip($nextLine);
			tokenize $nextLine " " $token;
			string $name = $token[0];
			float $x = $token[1];
			float $y = $token[2];
			float $z = $token[3];
			select -clear;
			string $j = `joint -n $name`;
			move ($y / 100) ($z / 100) ($x / 100) $j;
			$nextLine = `fgetline $fileId`;
		}
	}
	fclose $fileId;
}


After you have created the joints, you could then parent them and preserve their transforms if you wish.

David
__________________
http://www.djx.com.au
 
  04 April 2013
That's brilliant, thank you so much for your help. I had considered to reorder the axis, and my workaround for the joint chain was slightly different to yours. Here is what I had:

{
    string $filename = "H:/My Documents...filename.joints";
    int $fileId = `fopen $filename "r"`;
    if (!`filetest -f $filename`) error "Specified File not Found!";
    while (!`feof $fileId`)
    {
        string $nextLine = `fgetline $fileId`;
        string $tokens[];
        while (size($nextLine) > 0)
        {
            string $cleanLine = strip($nextLine);
            tokenize $nextLine " " $tokens;
            string $name = $tokens[0];
            float $z = $tokens[1];
            float $x = $tokens[2];
            float $y = $tokens[3];
            joint -n $name -p ($x / 100) ($y / 100) ($z / 100);
            $nextLine = `fgetline $fileId`;
        }
    }
    fclose $fileId;
}
select -cl;
select `ls -typ joint`;
parent -w;
select -cl;


I'm sure your code is a much cleaner way of doing this given your tip about avoiding selections in the script. I don't know why I didn't think of clearing the selection between creations, that makes perfect sense.

What I can't quite get my head around in your script is this bit:
string $j = `joint -n $name`;
move ($y / 100) ($z / 100) ($x / 100) $j;
I presume that is the bit where the joint is created but because I'm totally new to scripting I can't see how it creates them. Does it create a string with the variable j then calls it at the end of the move command? If so, is it necessary to create the string and use the move command rather than use the line:
joint -n $name -p ($x / 100) ($y / 100) ($z / 100);

Thanks again for your help.

Andy
 
  04 April 2013
string $j = `joint -n $name`;

The back quotes are used when you want to execute a command and return the result, in this case the name of the new joint, which is assigned to the variable $j. This is how we avoid having to select it later. Obviously in this case it will be selected anyway, but it is not always like that, and it is better to capture return values than to rely on selections.

It is true that the "move" command is somewhat redundant and I could have specified the the position in the "joint" command. This is purely a personal preference of mine. But it does help illustrate the idea of using variables to store object names for use in other commands.

David
__________________
http://www.djx.com.au
 
  04 April 2013
Fantastic. Your help has been most useful
 
  04 April 2013
Thread automatically closed

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.
__________________
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 09:56 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.