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.Originally posted by vladimirjp
i wish thre were,
// 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; }
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...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.
// 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; }