Complex UV Layout in Maya
Over the last couple of years UV layout in Maya has changed for the better. In this course we're going to be taking a look at some of those changes as we UV map an entire character
# 1 03-04-2006 , 07:35 PM
vladimirjp's Avatar
Subscriber
Join Date: Jun 2003
Location: stuck in the 90's boston, USA
Posts: 1,871

normals [state]

is there a way to catch the state of normals? to know what direction they are facing?
if they are facing away from camera or not.

im tring to writte a script that finds all objects who's normals are inverted. and make them point in the right direction.

# 2 03-04-2006 , 09:08 PM
MattTheMan's Avatar
Registered User
Join Date: Apr 2005
Location: Fairfield, CT
Posts: 2,436
well, you could scan all normals and then take the dot product between the normal and the camera (which the normal of the camera would be a vector from the actual camera and the point it is rotating around, and then normalize that

then if the dot product was negative, then its facing outward, but if the dot product was positive then its facing inward

then you flip the normals that the dot product was negative

this might work, but I'm not sure


Live the life you love, love the life you live

Last edited by MattTheMan; 05-04-2006 at 01:03 AM.
# 3 05-04-2006 , 04:13 PM
vladimirjp's Avatar
Subscriber
Join Date: Jun 2003
Location: stuck in the 90's boston, USA
Posts: 1,871
you lost me at "dot"

what is that? is that a mel function?

can u write a pseudo code on how youd hadle this.

this sound like a logical approach.

if i could get the state or the "dot" positive/negative of normals facing camera, i could easily write a mel that reverse them.

# 4 05-04-2006 , 04:46 PM
Velusion's Avatar
Registered User
Join Date: May 2004
Location: Utah, USA
Posts: 369
I'm pretty sure there is an option, under normals, that will flip whichever normals are not pointing in the same direction as the majority of them.

# 5 05-04-2006 , 05:09 PM
vladimirjp's Avatar
Subscriber
Join Date: Jun 2003
Location: stuck in the 90's boston, USA
Posts: 1,871
i wish thre were,
but the option under normals>conform
as i thought it was, really does nothing,

so any mel savvy members can look into this, i have a model and a huge scene with many many parts im trying to set all their normals to face the camera.

# 6 05-04-2006 , 11:24 PM
MattTheMan's Avatar
Registered User
Join Date: Apr 2005
Location: Fairfield, CT
Posts: 2,436
dot product, or scalar product, is a mathmatical operation done like this:

vectors c and n, c being camera, n being normal

dot product = n.x*c.x + n.y*c.y + n.z*c.z


Live the life you love, love the life you live
# 7 06-04-2006 , 12:06 AM
vladimirjp's Avatar
Subscriber
Join Date: Jun 2003
Location: stuck in the 90's boston, USA
Posts: 1,871
i think youre way off matt

# 8 06-04-2006 , 12:18 AM
MattTheMan's Avatar
Registered User
Join Date: Apr 2005
Location: Fairfield, CT
Posts: 2,436
me too but I was just trying to help.


Live the life you love, love the life you live
# 9 06-04-2006 , 10:18 AM
kbrown's Avatar
Moderator
Join Date: Sep 2002
Location: London, UK
Posts: 3,198

Originally posted by vladimirjp
i wish thre were,

Well, there is but depending on the situation it takes some trial and error to get the normals sorted out. Usually some mode of the Conform function followed by Set To Face does the trick. Sometimes you have to do it in reverse order. I don't really know what's going on with these normal operations but they do work eventually.


Kari
- My Website
- My IMDB

Do a lot, Fail a lot and Learn a lot!
# 10 06-04-2006 , 10:31 AM
kbrown's Avatar
Moderator
Join Date: Sep 2002
Location: London, UK
Posts: 3,198
Here's a copy-paste of my getFaceNormals procedure, which I wrote for my auto map script. It takes in a string variable containing the name of the polygon object and returns a vector array containing face normals.

Code:
// getFaceNormals by kbrown
//
proc vector[] getFaceNormals(string $sPolyObject)
{
	vector $vNormals[];
	int $i;

	// get all face normals in to a string array
	string $sFaceNormals[] = `polyInfo -fn $sPolyObject`;
	
	// parse the string array and create a vector array holding the normal info
	for($i = 0; $i < size($sFaceNormals); $i++)
	{
		string $sBuffer[];
		tokenize($sFaceNormals[$i], $sBuffer);
		float $fX = $sBuffer[2];
		float $fY = $sBuffer[3];
		float $fZ = $sBuffer[4];
		$vNormals[$i] = <<$fX, $fY, $fZ>>;
	}
	
	// free some memory
	clear($sFaceNormals);
	
	// return the vector array
	return $vNormals;
}


Kari
- My Website
- My IMDB

Do a lot, Fail a lot and Learn a lot!
# 11 06-04-2006 , 10:34 AM
kbrown's Avatar
Moderator
Join Date: Sep 2002
Location: London, UK
Posts: 3,198

Re: normals [state]

Originally posted by vladimirjp
is there a way to catch the state of normals? to know what direction they are facing?
if they are facing away from camera or not.

im tring to writte a script that finds all objects who's normals are inverted. and make them point in the right direction.

I think there is a problem with this concept. Normals can face away from camera and still be just fine. I'm talking about the faces on the back side of the object (which the camera cannot see). Might be safer if you just investigate the normals of the selected faces only...


Kari
- My Website
- My IMDB

Do a lot, Fail a lot and Learn a lot!
# 12 06-04-2006 , 12:53 PM
vladimirjp's Avatar
Subscriber
Join Date: Jun 2003
Location: stuck in the 90's boston, USA
Posts: 1,871
yea, the state [or directions] of my normals matter a lot.

im doing a lot of dynamics which requires normals to be pointed out to calculate.

also some rendering issues i have with inverted normals.

i did a lot of negative duplicates, so the normals get inverted [sometimes arbitrarily user added image ]
ill experiment with your code with some of the codes i already have for this.


thankx. ill keep testing.

this is harder than it seems. i dont know why alias hasnt made a tool for this yet.


Last edited by vladimirjp; 06-04-2006 at 01:34 PM.
# 13 07-04-2006 , 01:50 PM
vladimirjp's Avatar
Subscriber
Join Date: Jun 2003
Location: stuck in the 90's boston, USA
Posts: 1,871
close enough:
"normalChecker; "
of course since its from alias it only does half the job.

Code:
 // Copyright (C) 1997-2004 Alias Systems Corp.
// 
// The information in this file is provided for the exclusive use of the
// licensees of Alias.  Such users have the right to use, modify,
// and incorporate this code into other products for purposes authorized
// by the Alias license agreement, without fee.
// 
// ALIAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
// EVENT SHALL ALIAS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
//
// authors: afuchs and rreyer
//
// Version 23.12.04 - 13:55
//
//
//

proc copyTRS( string $source, string $dest)
{
	float $v[] = `getAttr ($source + ".translate")`;
	setAttr -type double3 ($dest + ".translate") ($v[0]) ($v[1]) ($v[2]);
	float $v[] = `getAttr ($source + ".rotate")`;
	setAttr -type double3 ($dest + ".rotate") ($v[0]) ($v[1]) ($v[2]);
	float $v[] = `getAttr ($source + ".scale")`;
	setAttr -type double3 ($dest + ".scale") ($v[0]) ($v[1]) ($v[2]);
}

global proc normalChecker( )
{
	
		string $selection[] = `ls-sl`;

		string $shapes[];
		string $inverse[];
	
		$shapes = `ls -v -ni -ut -sl -dag -type nurbsSurface -type mesh`;
		
	if (size($shapes)) {			// create red inverse surfaces
	
		string $inverseShadingGroup;
		if (!`objExists "normalCheckRedShader"`) {
			$inverseShader = `shadingNode -name "normalCheckRedShader" -asShader lambert`;
			setAttr ($inverseShader +".color") -type double3 1 0 0 ;
			$inverseShadingGroup =`sets -renderable true -noSurfaceShader true -empty -name ($inverseShader +"SG")`;
			connectAttr -f ($inverseShader + ".outColor") ($inverseShadingGroup + ".surfaceShader");
		} else $inverseShadingGroup = "normalCheckRedShaderSG";
	
		if (!`objExists "normalCheckLayer"`) {
			createDisplayLayer -name "normalCheckLayer" -number 1 -empty;
			setAttr normalCheckLayer.displayType 2;
		}
	
	
	
		for ( $obj in $shapes ) 
		{
			// check, if this shape is connected to the inverseLayer (that means, it is an inverse)
			if (!`isConnected normalCheckLayer.drawInfo ($obj + ".drawOverride")`) {
				string $tmp[] = `listRelatives -p $obj`;
				string $parent = $tmp[0];

				string $inverse;
				if ( `objectType $obj` == "nurbsSurface" ) 
				{
					// first check, if an inverse already exists
					if (!`objExists ($obj + "_inverse")` || !`isConnected ($obj + ".worldSpace[0]") ($obj + "_inverse.create")`) {

						$inverse =`createNode -n ($obj + "_inverse") nurbsSurface`;
//						$inverse =`createNode -p $parent -n ($obj + "_inverse") nurbsSurface`;
						connectAttr -f ($obj+ ".worldSpace[0]") ($inverse +".create");
					}
				} else {
					// first check, if an inverse already exists
					if (!`objExists ($obj + "_inverse")` || !`isConnected ($obj + ".outMesh") ($obj + "_inverse.inMesh")`) {

						$inverse =`createNode -n ($obj + "_inverse") mesh`;
//						$inverse =`createNode -p $parent -n ($obj + "_inverse") mesh`;
						connectAttr -f ($obj + ".outMesh") ($inverse + ".inMesh");
					}
				}

				// do we have a new inverse?
				if (size($inverse)) {

					string $tmp[] = `listRelatives -p $inverse`;
					string $inverseParent = $tmp[0];
					copyTRS( $parent, $inverseParent);

					select $inverseParent;
					layerEditorAddObjects normalCheckLayer;

					// now set the new shape to be reverse (from whatever the orig ist)
					setAttr ($obj + ".doubleSided") 0;
					setAttr ($inverse + ".doubleSided") 0;

					// set the opposite flag for the single side option
					setAttr ($inverse + ".opposite") (!`getAttr ($obj + ".opposite")`);

					// connecting it to the red shader
					select -r $inverse;
					sets -e -forceElement $inverseShadingGroup;
				}
			}
		}

	} else {			// delete red inverse surfaces, the layer and the red shader
		if (`objExists "normalCheckLayer"`) {
			layerEditorSelectObjects normalCheckLayer;

			// set the original shapes back to "doublesided"
			string $shapes[] = `ls -v -ni -ut -sl -dag -type nurbsSurface -type mesh`;
			for ( $s in $shapes ) {
				string $tmp[];
				if ( `objectType $s` == "nurbsSurface" ) $tmp = `listConnections -s 1 -p 0 -sh 1 ($s + ".create")`;
				else $tmp = `listConnections -s 1 -p 0 -sh 1 ($s + ".inMesh")`;
				setAttr ($tmp[0] + ".doubleSided") 1;
			}

			if (size(`ls -sl`)) delete;
			evalDeferred ("layerEditorDeleteLayer normalCheckLayer");
		}

		if (`objExists "normalCheckRedShader"`) {
			string $tmp[] = `listConnections -d 1 "normalCheckRedShader.outColor"`;
			$tmp = `ls -type shadingEngine $tmp`;
			if (size($tmp)) delete $tmp;
			delete normalCheckRedShader;
		}
	}

	select -r $selection;

}


Last edited by vladimirjp; 07-04-2006 at 01:54 PM.
# 14 24-04-2006 , 08:21 PM
Velusion's Avatar
Registered User
Join Date: May 2004
Location: Utah, USA
Posts: 369
I'm going to look into this tonight. I know that one of my books explains how Maya can find and flip normals that aren't pointing in the same direction as the majority.

Question: If some of the normals are flipped, can't you just tell Maya to make your texture double sided?

# 15 27-04-2006 , 01:47 AM
Velusion's Avatar
Registered User
Join Date: May 2004
Location: Utah, USA
Posts: 369
Well, I struck out. I can't find a way to flip the "odd" normals but one thing I don't understand is how you guys are running into situations where some of your normals are getting reversed. I've never had that happen,,, yet.

One thing I discovered is that if YOU reverse some or all of your normals using the reverse function, a node is created and you really can't unreverse those normals by hitting the reverse normals button again. You have to delete the node. I reversed some normals on purpose then went into the outliner and turned off DAG OBJECTS ONLY then went down to the node that was created; POLYNORMAL, and deleted it. By doing this, the normals that I reversed turned back around the way they originally were.

I've yet to come across a situation that has made me want to reverse normals except sometimes when I import a model from Zbrush. Sometimes when I import the model, the normals are reversed. When that happens, it's the whole model and not just a few normals.

I'm going to post this question in the Polygon modeling forum..


Last edited by Velusion; 27-04-2006 at 01:57 AM.
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