View Full Version : Selecting a shader, and the faces using it
05-03-2007, 10:18 PM
This time I am in need of some help performance wise. See, I wrote a exporter script that, given a character, would export an ascii file with the shader that is applied to every poly face. It is rather straight forward. Select the mesh(es) and run the script. Out comes text file(s) for each mesh(es) with a detail list of the shader applied to every face... It works but it is slow, specially when restoring the shaders. This is because I store each face.
is much less efficient than
I was wondering if there's a better way of selecting the faces per shader, instead of a flatten list, a more consiced and optimized version, I like the "myobject.f[0:100]".
Ideally I would like to replicate the functioonality that you get when you right click on a shader and are able to select the geometry using the shader (converting the selection to faces won't work because it select the whole object, regardless of how many shaders might be using it).
As I said, right now I am able to do this, but it creates a long list, and even though I am sorting my text file for faster selection (I.e., all the "lambertSG5" together), I would like to have the [xx:yy] format, as I think it is faster.
05-04-2007, 09:22 PM
In script it is a bit tricky - but if you have access to C++ or Python, you can use a map/sorted-list per object. The magic would be to sort the map based on face number, and then you can pretty quickly come up with lists of adjacent faces that share the same material.
map<int, string> mtlMap;
void AddMtl(int faceNumber, MString materialName)
mtlMap[faceNumber] = materialName;
void ExportMtlList(MStringArray & mtlListOut)
for(int i = 0; i < numFaces;)
int initial = i;
string currentMtl = mtlMap[i];
for (string testingMtl = mtlMap[i];
currentMtl == testingMtl;
testingMtl = mtlMap[i])
int end = i-1;
if(initial != end)
output = MString("object.f[") + MString(initial) + MString(":") + MString(end) + MString("]");
output = MString("object.f[") + MString(initial) + MString("]");
Though I hasten to add that what's above is only a thought experiment, and has not been compiled or tested (^_^) - but hopefully it communicates the idea. I haven't thought about what the equivalent would be in Mel, but whatever it is, it doesn't seem easy at all.
before you print out your faces, try storing the list of faces as an array.
Then, select the array of faces and list the selection to get the short list
string $faces = ["object.f","object.f","object.f","object.f"] //or however you want to get the faces into the array
select -r $faces;
$faces = `ls -sl`;
// Result: object.f[1:4]
05-07-2007, 10:31 PM
Thank you all for your reply. I decided to add a step to optimize the selection and this has improved performanced quite a bit. A little background: The idea was to allow the user to select 1 or multiple polymeshes and store the per face shader information on a text file that could be used later to restore the textures on a character.
The selection is converted to faces (per mesh), yet "polymesh.f[0:26500]" now needed to be processed to store each face's shader. The way I break it down is by storing each face's shader on an array (with 26500 shaders), where the array position is the face's index value. I then optimized them based on their order, so something like
<object name>+f[0:2] (using lambert5SG)
<object name>+f[3:4] (using lambert6SG)
<object name>+f (using lambert5SG)
<object name>+f[6:7] (using lambert6SG)
<object name>+f (using lambert7SG)
The optimization step sped up the script by 70 % when restoring the shader data.
Thanks for your ideas. I always really appreciate them.
05-07-2007, 10:31 PM
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.