View Full Version : sampling tex color at poly face pivot in MEL
deadalvs 07-26-2008, 11:25 AM hi !
i want to write a little script that deletes all poly faces of an object that fall in a specific range of color. for example all polys with less than rgb .3 .3 .3.
how would i script this in MEL so it runs thru all polys and deletes them ?
i used the colorAtPoint command for nurbsSurfaces to sample colors via UV position, so i basically just need a solution to get an averaged UV position of all the vertices of the active poly face... any hint ?
thx !
|
|
deadalvs
07-26-2008, 02:31 PM
okay. i got the code nailed down.
but it's kinda slow... maybe can give me a hint how to speed this up ?
it's all about this tutorial:
http://www.thegnomonworkshop.com/tutorials/trans_shadow.html
so to able not to manually delete all poly faces or with artisan i decided to write a script that just gets rid of all black faces that were intended not to be displaced.
so here's the code for free use: but i'd like to know how to improve speed please... :bounce:
* * *
basic idea:
• be sure to enter the displacement shader node's name in the script window.
• loop thru all selected objects (with the same displacement texture node).
• then run thru each poly face and give back all the CV IDs
• convert those cvs (per triangle) to uvs and get their UV positions. divide the sum by 3 to get the average value.
• check if rgb brightness is dark. if dark --> no displacement --> write face name in an array
• at the end select all the face names in the array and delete them. (they cannot be deleted on the fly cos all other faces with get renamed)
* * *
// deleteDarkPolys script deadalvs, july 2008
////////////////////////////////////////////////////////////////////////////////////// start GUI
if (`window -exists "deleteDarkPolysWin"` == 1){deleteUI "deleteDarkPolysWin";}
window -t "d_deleteDarkPolys" deleteDarkPolysWin;
columnLayout -adjustableColumn 1;
frameLayout -label "delete dark polys .." -cll true -collapse 0 pipesFromSurfacesLayout;
columnLayout -adjustableColumn 1;
text -l "";
text -l "value black [0;1]";
floatField -width 300 -v 0.3 valueWhitePerc_floatField;
text -l "";
text -l "target texture";
textField -width 300 targetTextureName_textField;
text -l "";
button -h 25 -l "delete dark polys !" -command "d_deleteDarkPolys(); ";
setParent ..;
setParent ..;
showWindow deleteDarkPolysWin;
///////////////////////////////////////////////////////////////////////////////////////////////
global proc d_deleteDarkPolys(){
// select tool to get rid of the ... Warning: line 0: Some items cannot be moved in the 3D view
global string $gSelect;
string $oldTool = `currentCtx`;
setToolTo $gSelect;
global float $valueWhitePerc;
$valueWhitePerc = `floatField -q -v valueWhitePerc_floatField`;
global string $targetTextureName;
$targetTextureName = `textField -q -tx targetTextureName_textField`;
global string $toDeleteFacesArray[];
$toDeleteFacesArray = {};
global string $selectedPolyObjectsArray[];
$selectedPolyObjectsArray = `ls -sl`;
for ($eachPolyObject in $selectedPolyObjectsArray){
select -r ($eachPolyObject + ".f[0:100000]");
global string $selectedPolyFacesArray[];
$selectedPolyFacesArray = `ls -sl -fl`;
for ($eachPolyFace in $selectedPolyFacesArray){
global int $CVIDsArray[];
$CVIDsArray = `d_getCVIDsFromPolyFace($eachPolyFace)`;
//print $CVIDsArray;
// calc average UV Position for face center
// A
select -r ($eachPolyObject + ".vtx[" + $CVIDsArray[0] + "]");
ConvertSelectionToUVs;
string $selectedUVPointarray[] = `ls -sl`;
string $selectedUVPoint = $selectedUVPointarray[0];
float $A_PosUV[] = `polyEditUV -query`;
// B
select -r ($eachPolyObject + ".vtx[" + $CVIDsArray[1] + "]");
ConvertSelectionToUVs;
string $selectedUVPointarray[] = `ls -sl`;
string $selectedUVPoint = $selectedUVPointarray[0];
float $B_PosUV[] = `polyEditUV -query`;
// C
select -r ($eachPolyObject + ".vtx[" + $CVIDsArray[2] + "]");
ConvertSelectionToUVs;
string $selectedUVPointarray[] = `ls -sl`;
string $selectedUVPoint = $selectedUVPointarray[0];
float $C_PosUV[] = `polyEditUV -query`;
global float $U_average;
$U_average = ($A_PosUV[0] + $B_PosUV[0] + $C_PosUV[0]) * 1.0 / 3;
global float $V_average;
$V_average = ($A_PosUV[1] + $B_PosUV[1] + $C_PosUV[1]) * 1.0 / 3;
global string $targetTextureName;
global float $valueWhitePerc;
vector $imgColor = `colorAtPoint -o RGB -u $U_average -v $V_average $targetTextureName`;
float $blackValue = 1 - ((abs (`mag $imgColor`))/1.73205);
//print ( $blackValue+ "\n");
if ($blackValue > $valueWhitePerc) {
global string $toDeleteFacesArray[];
//print $toDeleteFacesArray;
string $eachPolyFaceNameAsArray[];
$eachPolyFaceNameAsArray = stringToStringArray ($eachPolyFace, "");
$toDeleteFacesArray = stringArrayCatenate ( $toDeleteFacesArray, $eachPolyFaceNameAsArray);
//$eachPolyFace = "pSphere1.f[36]";
}
// end for ($eachPolyFace in $selectedPolyObjectsArray)
}
//end for ($eachPolyObject in $selectedPolyObjectsArray)
}
select -r $toDeleteFacesArray;
delete;
select -r $selectedPolyObjectsArray;
setToolTo $oldTool;
// end d_deleteDarkPolys
}
///////////////////////////////////////////////////////////////////////////////////////////////
global proc int[] d_getCVIDsFromPolyFace(string $polyFace){
string $pi[]=`polyInfo -faceToVertex ($polyFace)`;
string $piParts[];
tokenize $pi[0] $piParts;
//print ("#verts: "+(size($piParts)-2)+"\n");
int $faceID_A = $piParts[2];
int $faceID_B = $piParts[3];
int $faceID_C = $piParts[4];
return {$faceID_A, $faceID_B, $faceID_C};
//END... getCVIDsFromPolyFace
}
///////////////////////////////////////////////////////////////////////////////////////////////
deadalvs
07-27-2008, 04:30 AM
i found out why it is so slow. because of all the filling up in the name array.
i just took an other route to assign a shader as a «set» that might run faster in maya faster than filling up large arrays of names.
now it's slow cos all the shader assignments are printed out .. well, but at least i put in an output that shows the progress in the script editor ..
// deleteDarkPolys script deadalvs, july 2008
////////////////////////////////////////////////////////////////////////////////////// start GUI
if (`window -exists "deleteDarkPolysWin"` == 1){deleteUI "deleteDarkPolysWin";}
window -t "d_deleteDarkPolys" deleteDarkPolysWin;
columnLayout -adjustableColumn 1;
frameLayout -label "delete dark polys .." -cll true -collapse 0 pipesFromSurfacesLayout;
columnLayout -adjustableColumn 1;
text -l "";
text -l "value black [0;1]";
floatField -width 300 -v 0.2 valueWhitePerc_floatField;
text -l "";
text -l "target texture";
textField -width 300 targetTextureName_textField;
text -l "";
button -h 25 -l "delete dark polys !" -command "d_deleteDarkPolys(); ";
setParent ..;
setParent ..;
showWindow deleteDarkPolysWin;
///////////////////////////////////////////////////////////////////////////////////////////////
global proc d_deleteDarkPolys(){
// select tool to get rid of the ... Warning: line 0: Some items cannot be moved in the 3D view
global string $gSelect;
string $oldTool = `currentCtx`;
setToolTo $gSelect;
global float $valueWhitePerc;
$valueWhitePerc = `floatField -q -v valueWhitePerc_floatField`;
global string $targetTextureName;
$targetTextureName = `textField -q -tx targetTextureName_textField`;
//get all selected poly objects
global string $selectedPolyObjectsArray[];
$selectedPolyObjectsArray = `ls -sl`;
shadingNode -asShader lambert;
rename "PolyDeleteLambert";
setAttr "PolyDeleteLambert.color" -type double3 1 0 0 ;
for ($eachPolyObject in $selectedPolyObjectsArray){
select -r ($eachPolyObject + ".f[0:100000]");
global string $selectedPolyFacesArray[];
$selectedPolyFacesArray = `ls -sl -fl`;
global int $numberPolys;
$numberPolys = size ($selectedPolyFacesArray);
for ($eachPolyFace in $selectedPolyFacesArray){
global int $CVIDsArray[];
$CVIDsArray = `d_getCVIDsFromPolyFace($eachPolyFace)`;
//print $CVIDsArray;
// calc average UV Position for face center
// A
select -r ($eachPolyObject + ".vtx[" + $CVIDsArray[0] + "]");
ConvertSelectionToUVs;
string $selectedUVPointarray[] = `ls -sl`;
string $selectedUVPoint = $selectedUVPointarray[0];
float $A_PosUV[] = `polyEditUV -query`;
// B
select -r ($eachPolyObject + ".vtx[" + $CVIDsArray[1] + "]");
ConvertSelectionToUVs;
string $selectedUVPointarray[] = `ls -sl`;
string $selectedUVPoint = $selectedUVPointarray[0];
float $B_PosUV[] = `polyEditUV -query`;
// C
select -r ($eachPolyObject + ".vtx[" + $CVIDsArray[2] + "]");
ConvertSelectionToUVs;
string $selectedUVPointarray[] = `ls -sl`;
string $selectedUVPoint = $selectedUVPointarray[0];
float $C_PosUV[] = `polyEditUV -query`;
global float $U_average;
$U_average = ($A_PosUV[0] + $B_PosUV[0] + $C_PosUV[0]) * 1.0 / 3;
global float $V_average;
$V_average = ($A_PosUV[1] + $B_PosUV[1] + $C_PosUV[1]) * 1.0 / 3;
global string $targetTextureName;
global float $valueWhitePerc;
vector $imgColor = `colorAtPoint -o RGB -u $U_average -v $V_average $targetTextureName`;
float $blackValue = 1 - ((abs (`mag $imgColor`))/1.73205);
//print ( $blackValue+ "\n");
if ($blackValue > $valueWhitePerc) {
global int $numberPolys;
select -r $eachPolyFace;
print ($eachPolyFace + " of total " + $numberPolys + " polys\n" );
hyperShade -assign PolyDeleteLambert;
}
// end for ($eachPolyFace in $selectedPolyObjectsArray)
}
//end for ($eachPolyObject in $selectedPolyObjectsArray)
}
hyperShade -objects PolyDeleteLambert;
delete;
select -cl;
select -r "PolyDeleteLambert";
delete;
select -r $selectedPolyObjectsArray;
setToolTo $oldTool;
// end d_deleteDarkPolys
}
///////////////////////////////////////////////////////////////////////////////////////////////
global proc int[] d_getCVIDsFromPolyFace(string $polyFace){
string $pi[]=`polyInfo -faceToVertex ($polyFace)`;
string $piParts[];
tokenize $pi[0] $piParts;
//print ("#verts: "+(size($piParts)-2)+"\n");
int $faceID_A = $piParts[2];
int $faceID_B = $piParts[3];
int $faceID_C = $piParts[4];
return {$faceID_A, $faceID_B, $faceID_C};
//END... getCVIDsFromPolyFace
}
///////////////////////////////////////////////////////////////////////////////////////////////
greatPumpkin
07-27-2008, 05:30 AM
you should try removing all your select calls. Particularly if there are lots of vertices. just about all of maya's commands will work correctly without needing to select them.. selection will probably cause maya to have to update in some way between each vertex-
e.g.instead of this selecting the vertice, and then assign a shader using the hyperShade command (also bad because you are relying again on the UI when you don't need to):
select -r $eachPolyFace;
print ($eachPolyFace + " of total " + $numberPolys + " polys\n" );
hyperShade -assign PolyDeleteLambert;
something like :
// note you have to using the shading engine of the shader, not the shader itself for the
// -forceElement flag
sets -edit -forceElemnt PolyDeleteLambertSG $eachPolyFace;
you could also do a counter loop to only print out a status update say every 1000 vertices, or even a time based status update say every 10 seconds using timerX so that you won't get bogged down by a crazy amount of print outputs.
..hmm... I wonder if maybe some mod would like to post a sticky about why it's not a good idea to use global variables if you don't need to... seems like it's super common in a lot of 'need help with mel' threads.
CGTalk Moderation
07-27-2008, 05:30 AM
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.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.