Digital humans the art of the digital double
Ever wanted to know how digital doubles are created in the movie industry? This course will give you an insight into how it's done.
# 1 07-03-2011 , 03:19 PM
Registered User
Join Date: Mar 2011
Posts: 4

Mel scripting

Hello, I am new at mel scripting and am in need of a script that selects all faces of a polygonal object, that face the x direction. Please could anyone help with a sample script, or point me to a site that could help. Thank you

# 2 07-03-2011 , 04:38 PM
LauriePriest's Avatar
Moderator
Join Date: May 2003
Location: London
Posts: 1,001
Hmm,
tis involved for someone who hasn't scripted before.

I guess the script would look something like this:

For each vertex in object :
calculate dot product of the unitized normal with a unitized direction. If the result is bigger positive it will be facing toward the camera, if it is negative it will be facing away.
If it is a positive value add it to a list and then after the for loop convert that list to a selection and then to polygons if needs be.

You will need to look up how to do unitize vectors to do this properly otherwise it won't give you an expected result.

If you want to use an object as your direction you would have to add another for loop before this to add a vector for each object that describes the normalized direction from each vertex to that object.
It might be as easy to write in code as this normalized(objectPos-vertexpos)
but its good to understand whats going on under the hood.

This is a bit mathsy but it looks something like this,
Displacement D to object = (obj.tx, obj.ty, obj.tz)- (vetex.tx, vertex.ty, vertex.tz)
Length L of the vector D = squareRoot(D.x*D.x + D.y*D.y + D.z*D.z)
Normalized Displacment D = D*(1.0/L)

However you could always just declaire the direction at the beginning of the script as a written vector. As long as its normalized !

I hope that gives you a starting point, it will be worth doing a few tutorials to understand how to do for loops and access information across maya to use before trying to do this.

Does that make some sense?
Cheers,

Laurie


Also could you not just do backface culling, make your selection and then turn backface culling off, or are you doing something special per frame ?


FX supervisor - double negative
# 3 08-03-2011 , 09:43 AM
Registered User
Join Date: Mar 2011
Posts: 4
Hi Laurie,

Thank you for your quick reply..
I hope that i am over complicating the situation here, but all i really need it to select all the world x facing faces of a poly object, front and back faces.
I am creating over 500 polygon houses and need to uv project all the walls, this is very time consuming to manually select all the x faces and project, invert my selection and project on the z.

I have been looking for days for a simple solution..

Could you maybe help with a simpler solution.
I have a generic poly cube names pCube1.
Here is where i am:

//Select all the faces of an object
select -r pCube1.f["*"];

//now get the number of faces in the selection
$faceList = `filterExpand -sm 34`;

//check that i have all the faces
print $faceList;

print ("Num of faces is: " + size($faceList) + "\n");

//Now get the per face normal direction of the selection
polyInfo -faceNormals;

I am a little stuck here, I need to convert the "polyInfo -faceNormals" into a usable variable array.
I found this but not sure how it works or how to use it:


proc vector translatePolyInfoNormal( string $pin )
{

vector $normal;
float $x;
float $y;
float $z;

string $tokens[];
int $numTokens = `tokenize $pin " " $tokens`;

// Make sure we're looking at polyInfo data:
if ( ( $numTokens > 3 ) && ( $tokens[0] == "FACE_NORMAL" ) )
{
// Maya performs data-type conversion here.
$x = ($tokens[$numTokens-3]);
$y = ($tokens[$numTokens-2]);
$z = ($tokens[$numTokens-1]);

$normal = << $x, $y, $z >>;

// Normalize it.
$normal = `unit $normal`;
}

// Return it.
return $normal;
print $normal;
}


My thinking in words is as follows:
Select the object, put the selected face numbers into an array, query the face normal vector direction and store them in an array. do a for loop using the face number size as the amount of loops to check if the x value of the face normal vector direction is within certain paramaters, if so then select that face. do the loop untill all the desired faces are selected.

I know it seems simple, but I really am battling with it.
Thank you for your time

# 4 08-03-2011 , 02:57 PM
Registered User
Join Date: Mar 2011
Posts: 4
Hi Laurie,

I have searched many forums and read hundereds of lines of code and finally built a script that works for this task.

The task is to select each and every poly face that faces the x axis only,
The useful purpose for this is to select all x facing poly faces of a structural mesh like a house and uv project in that axis. Once you have the x axis projected you can manually invert your selection and project for the z axis very easily, and the y axis is a breeze.

I am new to mel so please excuse the amature code:

//__________________________________________________ ______________________________________________
//Select all the X facing faces of a poly mesh selection
//created by: bikehawk
//date: 08-03-2011

//------------------------------------------------------
//Select one poly mesh
select -r pCube1 ;
//list the selection
string $selection[] = `ls -sl`;
print $selection;

//Select all the faces of an object
select -r $selection.f["*"];

//add a line
print ("\n");

//now get and display the individual number of faces in the selection
string $faceList[] = `filterExpand -sm 34`;

print $faceList;

//add a line
print ("\n");

//declare a variable with the number of faces
$nof = (size($faceList));

//variable to loop the for loop the correct amount of times
$nofLoop = $nof - 1;

//print the number of faces
print ("Num of faces is: " + $nof + "\n");

//select the cube to clear the face selection
select -r pCube1 ;

//Start the FOR LOOP*************************
for ($i=0;$i<=$nofLoop;$i=$i+1)
{
print $faceList[$i];
print ("\n");

//get all the face normal vectors
string $polyInfo[] = `polyInfo -faceNormals $faceList`;

//specify 1 face normal vector
$polyInfo = stringToStringArray($polyInfo[$i]," ");

//put vectors into variables
float $vPosX = $polyInfo[2];
float $vPosY = $polyInfo[3];
float $vPosZ = $polyInfo[4];

if ($vPosX >= 0.5)
{

print ("Select this face: " + $faceList[$i]);
select -tgl ($faceList[$i]);
}
if ($vPosX <= -0.5)
{
print ("Select this face: " + $faceList[$i]);
select -tgl ($faceList[$i]);
}

//add a line
print "\n";

}
//end the FOR LOOP*************************

//------------------------------------------------------

Hope this helps a few people, and any comments or code cleanup are very welcome.
Cheers guys

# 5 08-03-2011 , 02:59 PM
David's Avatar
SM Tea Boy
Join Date: Apr 2002
Location: Prague
Posts: 3,228
Thanks a lot for sharing user added image

And welcome to SimplyMaya
Dave


From a readers' Q and A column in TV GUIDE: "If we get involved in a nuclear war, would the electromagnetic pulses from exploding bombs damage my videotapes?"
# 6 08-03-2011 , 05:49 PM
LauriePriest's Avatar
Moderator
Join Date: May 2003
Location: London
Posts: 1,001
Cool, glad that worked out!

Remember if you want to get this to work on an aribtary axist youll have to do a dot product as if your axis is .4 1 3 for example it will be tricky to do a greater than argument to get a correct result.
Good work!!


FX supervisor - double negative
# 7 09-03-2011 , 09:37 AM
Registered User
Join Date: Mar 2011
Posts: 4
Thanx guys:user added image

Posting Rules Forum Rules
You may not post new threads | You may not post replies | You may not post attachments | You may not edit your posts | BB code is On | Smilies are On | [IMG] code is On | HTML code is Off

Similar Threads