View Full Version : Remove Duplicate Textures Script ?

09 September 2010, 10:00 AM

I have searched around creativecrash and found a few scripts that propose to remove duplicate shader networks, and possibly work, but not in the way that I require. I am looking for a script that will look at all the 'textures' in a scene, not shaders, and if, for instance, there is 4 grass shaders ( all referencing the same texture - Grass.tga ), then take the first shader, make that the 'default' shader, and apply to whatever faces the other shaders are applied to, then remove those 3 duplicates. Is this possible ? And does a script for this already exist ?

The ones I have tested, once run, either don't do anything, or come back with '0' duplicates found, despite the fact that I can visually see them in the Hypershade.


09 September 2010, 10:41 AM
He Steven!

ok. So you would like duplicate textures removed. not shaders. But then you say you'd like the other shaders removed as well? Hmm ok but I see what you're aiming at. This would be a nice thing actually.

But yea I don't know if that exists yet. So you don't need help writing one? You just want to have it? :D

09 September 2010, 03:01 PM
give this a shot, should find any materials connected to similar file textures and just use the first one it finds on the objects and delete the others, I haven't tested it much but seems to be working.

global proc int[] stringArrayContainsAtIndex(string $item, string $list[])
int $result = false;
int $index;
string $listItem;
for ($i=0;$i<size($list);$i++) {
if ($item == $list[$i]) {
$result = true;
$index = $i;
return {$result,$index};

string $textureList[];
string $shaderList[];
string $fileTextures[] = `ls -type "file"`;
for ($i=0;$i<size($fileTextures);$i++) {
string $con[] = `listConnections -destination 1 ($fileTextures[$i] + ".outColor")`;
string $temp[];
tokenize $con[0] "." $temp;
if ($con[0] != "") {
int $contains[] = stringArrayContainsAtIndex(`getAttr ($fileTextures[$i] + ".fileTextureName")`,$textureList);
if ($contains[0]) {
hyperShade -objects $temp[0];
string $objects[] = `ls -sl`;
for ($i2=0;$i2<size($objects);$i2++) {
hyperShade -assign $shaderList[$contains[1]] $objects[$i2];
print ("DELETING " + $temp[0] + " AND " + $fileTextures[$i] + " AND ASSIGNING " + $shaderList[$contains[1]] + " INSTEAD ");
delete $temp[0];
delete $fileTextures[$i];
else {
$textureList[size($textureList)] = `getAttr ($fileTextures[$i] + ".fileTextureName")`;
$shaderList[size($shaderList)] = $temp[0];

09 September 2010, 04:05 PM
he jacob! Nice one... though I'd nag about some points here and there... :D

But a thing that might break it: What about bumpmaps? Those are usually connected through bump2d-nodes. And what happens if I have the same texture put into the color and specular port with identical fileNodes? What If an artist intentionally tweaked an attribute at this or that shader?. ...

No really: For a really rock solid approach I wouldn't suggest to come from the fileNode side!

But Okok.. if you really just have the "fileNode as colorMap > shader" situation. That might cut it. But don't rely on it too much. This will eat your stuff if you break the rule ;]

ok additionally: I also like building little helper scripts like this stringArrayContainsAtIndex: But why that intArray? why not having it return -1 if failed: Might be enough as well: global proc int stringArrayContainsAtIndex(string $item, string $list[])
int $numItems = size($list);
for ($i = 0; $i < $numItems; $i++)
if ($list[$i] = $item)
return $i;

return -1;

09 September 2010, 04:39 PM
ah good point on the stringArrayContainsAtIndex, just slapped it together real quick. didn't really take into consideration all the other possibilities of bumps and spec either. at work right now but will update it when i get a chance.

CGTalk Moderation
09 September 2010, 04:39 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.