Random Face Color Script

I’ve taken to playing with materials and the end result is this funny little toy that just sticks random diffuse colors on every face of the selected mesh. ( Hopefully low-poly :wink: ) Nothing serious but I had fun with it.


# random_face_color.py (c) 2011 Phil Cote (cotejrp1)
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
bl_info = {
    'name': 'Random Face Color',
    'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
    'version': (0,2),
    "blender": (2, 5, 9),
    "api": 39307,
    'location': '',
    'description': 'Generate random diffuse faces on each face of a mesh',
    'warning': 'Don\'t use on meshes that have a large number of faces.',
    'category': 'Add Material'}

"""
How to use:
- Select a material with no more than one material on it.
- Hit "t" to open the toolbar.
- Under "Random Mat Panel", hit the "Random Face Materials" button.

Note: as of this revision, it works best on just one object.
It works slightly less well when colorizing multiple scene objects.
"""

import bpy
import time
from random import random, seed

# start simple be just generating random colors
def getRandomColor():
    seed( time.time() )
    red = random()
    green = random()
    blue = random()
    return red, green, blue


def makeMaterials( ob ):
    
    for face in ob.data.faces:
        randcolor = getRandomColor()
        mat = bpy.data.materials.new( "randmat" )
        mat.diffuse_color = randcolor


def assignMats2Ob( ob ):
    
    mats = bpy.data.materials
    
    # load up the materials into the material slots
    for mat in mats:
        bpy.ops.object.material_slot_add()
        ob.active_material = mat
    
    # tie the loaded up materials o each of the faces
    i=0
    faces = ob.data.faces
    while i < len( faces ):
        faces[i].material_index = i
        i+=1

getUnusedRandoms = lambda : [ x for x in bpy.data.materials 
                   if x.name.startswith( "randmat" ) and x.users == 0 ]

def clearMaterialSlots( ob ):
    while len( ob.material_slots ) > 0:
        bpy.ops.object.material_slot_remove()
         
def removeUnusedRandoms():
    unusedRandoms = getUnusedRandoms()
    
    for mat in unusedRandoms:
        bpy.data.materials.remove( mat )
        
class RemoveUnusedRandomOp( bpy.types.Operator ):
    bl_label = "Remove Unused Randoms"
    bl_options = { 'REGISTER'}
    bl_idname = "material.remove_unusedmats"
    
    def execute( self, context ):
        removeUnusedRandoms()
        return {'FINISHED'}

class RandomMatOp( bpy.types.Operator ):
    
    bl_label = "Random Face Materials"
    bl_idname = "material.randommat"
    bl_options = { 'REGISTER', 'UNDO' }
    
    
    def execute( self, context ):
        ob = context.active_object
        clearMaterialSlots( ob )
        removeUnusedRandoms()
        makeMaterials( ob )
        assignMats2Ob( ob )
        return {'FINISHED'}
    
    @classmethod    
    def poll( self, context ):
        ob = context.active_object
        return ob != None and ob.select
       


class RandomMatPanel( bpy.types.Panel ):
    bl_label = "Random Mat Panel"
    bl_region_type = "TOOLS"
    bl_space_type = "VIEW_3D"
    
    def draw( self, context ):
        self.layout.row().operator( "material.randommat" )
        row = self.layout.row()
        self.layout.row().operator( "material.remove_unusedmats" )
        
        matCount = len( getUnusedRandoms() )
        countLabel = "Unused Random Materials: %d" % matCount
        self.layout.row().label( countLabel )
        
    
def register():
    bpy.utils.register_class( RemoveUnusedRandomOp )
    bpy.utils.register_class( RandomMatOp )
    bpy.utils.register_class( RandomMatPanel )

def unregister():
    bpy.utils.unregister_class( RandomMatPanel )
    bpy.utils.unregister_class( RandomMatOp )
    bpy.utils.unregister_class( RemoveUnusedRandomOp )

if __name__ == '__main__':
    register()

Thats pretty cool, is there a way to animate the random instancing over time? So that a surface could flash random variations over time. And can you constrain the color range? So I could only have a blend range, say black to white for example.

All interesting ideas. 3pointedit. I’ll look into it and post if I come up with something.
Thanks.

Okay, did most of the things you suggested. Didn’t get to the animation part. I figure I only have so much time before the hurricane hits and knocks out my power. Here it is.


# random_face_color.py (c) 2011 Phil Cote (cotejrp1)
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
bl_info = {
    'name': 'Random Face Color',
    'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
    'version': (0,3),
    "blender": (2, 5, 9),
    "api": 39307,
    'location': '',
    'description': 'Generate random diffuse faces on each face of a mesh',
    'warning': 'Don\'t use on meshes that have a large number of faces.',
    'category': 'Add Material'}

"""
How to use:
- Select a material with no more than one material on it.
- Hit "t" to open the toolbar.
- Set desired options for color min and max intensity as well as whether or not to gray scale it.
- Under "Random Mat Panel", hit the "Random Face Materials" button.

Note: as of this revision, it works best on just one object.
It works slightly less well when colorizing multiple scene objects.
"""

import bpy
import time
from random import random, seed

# start simple be just generating random colors
def getRandomColor( gray_scale, color_min, color_max ):
    seed( time.time() )
    
    # if the min and max don't make sense, just ignore it.
    if color_min > color_max:
        color_min, color_max = 0, 1
    
    new_color = lambda : color_min + random() * ( color_max - color_min )
    
    if gray_scale:
        val = new_color()
        green = blue = red = val
    else:
        red = new_color()
        green = new_color()
        blue = new_color()
    
    
    return red, green, blue


def makeMaterials( ob, gray_scale, color_min, color_max ):
    
    for face in ob.data.faces:
        randcolor = getRandomColor( gray_scale, color_min, color_max )
        mat = bpy.data.materials.new( "randmat" )
        mat.diffuse_color = randcolor


def assignMats2Ob( ob ):
    
    mats = bpy.data.materials
    
    # load up the materials into the material slots
    for mat in mats:
        bpy.ops.object.material_slot_add()
        ob.active_material = mat
    
    # tie the loaded up materials o each of the faces
    i=0
    faces = ob.data.faces
    while i < len( faces ):
        faces[i].material_index = i
        i+=1

getUnusedRandoms = lambda : [ x for x in bpy.data.materials 
                   if x.name.startswith( "randmat" ) and x.users == 0 ]


def clearMaterialSlots( ob ):
    while len( ob.material_slots ) > 0:
        bpy.ops.object.material_slot_remove()
         
         
def removeUnusedRandoms():
    unusedRandoms = getUnusedRandoms()
    for mat in unusedRandoms:
        bpy.data.materials.remove( mat )
        
        
class RemoveUnusedRandomOp( bpy.types.Operator ):
    bl_label = "Remove Unused Randoms"
    bl_options = { 'REGISTER'}
    bl_idname = "material.remove_unusedmats"
    
    def execute( self, context ):
        removeUnusedRandoms()
        return {'FINISHED'}

class RandomMatOp( bpy.types.Operator ):
    
    bl_label = "Random Face Materials"
    bl_idname = "material.randommat"
    bl_options = { 'REGISTER', 'UNDO' }
    
    
    def execute( self, context ):
        ob = context.active_object
        scn = bpy.context.scene
        
        clearMaterialSlots( ob )
        removeUnusedRandoms()
        makeMaterials( ob, scn.gray_scale, scn.color_min, scn.color_max )
        assignMats2Ob( ob )
        return {'FINISHED'}
    
    @classmethod    
    def poll( self, context ):
        ob = context.active_object
        return ob != None and ob.select
       

class KeyRandomColorOp( bpy.types.Operator ):
    
    bl_idname = "anim.keyrandomcolor"
    bl_label = "unimplemented button"
    bl_description = "Not Yet Implemented"
    
    bl_options = { 'REGISTER', 'UNDO' }
    def execute( self, context ):        
        return { 'FINISHED'}
    
    @classmethod
    def poll( self, context ):
        return False #leaving it false til i'm ready to implement


class RandomMatPanel( bpy.types.Panel ):
    bl_label = "Random Mat Panel"
    bl_region_type = "TOOLS"
    bl_space_type = "VIEW_3D"
    
    def draw( self, context ):
        scn = context.scene
        new_row = self.layout.row
        
        new_row().prop( scn, "gray_scale" )
        new_row().prop( scn, "color_min" )
        new_row().prop( scn, "color_max" )
        new_row().operator( "material.randommat" )
        new_row().operator( "anim.keyrandomcolor" )
        new_row().operator( "material.remove_unusedmats" )
        
        matCount = len( getUnusedRandoms() )
        countLabel = "Unused Random Materials: %d" % matCount
        self.layout.row().label( countLabel )
        
from pdb import set_trace

def register():
    scn_type = bpy.types.Scene
    BoolProperty = bpy.props.BoolProperty
    FloatProperty = bpy.props.FloatProperty
    
    scn_type.gray_scale = BoolProperty( name="Gray Scale", default = False,
                                 description = "Gray scale random materials?")
                               
    scn_type.color_min = FloatProperty( name = "Color Min", default = 0, min=0,
                         max=1, description = "Extreme Min for R, G, and B" )
                         
    scn_type.color_max = FloatProperty( name = "Color Max", default = 1, min=0,
                         max=1, description = "Max Color for R, G, and B" )
    
    
    bpy.utils.register_class( KeyRandomColorOp )
    bpy.utils.register_class( RemoveUnusedRandomOp )
    bpy.utils.register_class( RandomMatOp )
    bpy.utils.register_class( RandomMatPanel )

def unregister():
    bpy.utils.unregister_class( RandomMatPanel )
    bpy.utils.unregister_class( RandomMatOp )
    bpy.utils.unregister_class( RemoveUnusedRandomOp )
    bpy.utils.unregister_class( KeyRandomColorOp )

if __name__ == '__main__':
    register()

cool thanks, be carefull of storm.

Key framing support added. Again, not a serious script and I certainly don’t advise using it on any hi poly meshes. I just wanted to have a little fun and learn a few things along the way.

Cheers.


# random_face_color.py (c) 2011 Phil Cote (cotejrp1)
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
bl_info = {
    'name': 'Random Face Color',
    'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
    'version': (0,3),
    "blender": (2, 5, 9),
    "api": 39307,
    'location': '',
    'description': 'Generate random diffuse faces on each face of a mesh',
    'warning': 'Don\'t use on meshes that have a large number of faces.',
    'category': 'Add Material'}

"""
How to use:
- Select a material with no more than one material on it.
- Hit "t" to open the toolbar.
- Set desired options for color min and max intensity as well as whether or not 
  to gray scale it.
- Under "Random Mat Panel", hit the "Random Face Materials" button.

Note: as of this revision, it works best on just one object.
It works slightly less well when colorizing multiple scene objects.
"""

import bpy
import time
from random import random, seed

# start simple be just generating random colors
def getRandomColor( gray_scale, color_min, color_max ):
    seed( time.time() )
    
    # if the min and max don't make sense, just ignore it.
    if color_min > color_max:
        color_min, color_max = 0, 1
    
    new_color = lambda : color_min + random() * ( color_max - color_min )
    
    if gray_scale:
        val = new_color()
        green = blue = red = val
    else:
        red = new_color()
        green = new_color()
        blue = new_color()
    
    
    return red, green, blue


def makeMaterials( ob, gray_scale, color_min, color_max ):
    
    for face in ob.data.faces:
        randcolor = getRandomColor( gray_scale, color_min, color_max )
        mat = bpy.data.materials.new( "randmat" )
        mat.diffuse_color = randcolor


def changeFaceMaterials( ob, gray_scale, color_min, color_max ):
    print( "call to chang face materials" )
    
    mats = ob.data.materials
    for face in ob.data.faces:
        randcolor = getRandomColor( gray_scale, color_min, color_max )
        mats[ face.material_index ].diffuse_color = randcolor
        
    
    
def assignMats2Ob( ob ):
    
    mats = [ mat for mat in bpy.data.materials if mat.name.startswith( "rand" )]
    
    # load up the materials into the material slots
    for mat in mats:
        bpy.ops.object.material_slot_add()
        ob.active_material = mat
    
    # tie the loaded up materials to each of the faces
    faces = ob.data.faces
    for i in range( len( faces ) ):
        faces[i].material_index = i

getUnusedRandoms = lambda : [ x for x in bpy.data.materials 
                   if x.name.startswith( "randmat" ) and x.users == 0 ]


def clearMaterialSlots( ob ):
    while len( ob.material_slots ) > 0:
        bpy.ops.object.material_slot_remove()
         
         
def removeUnusedRandoms():
    unusedRandoms = getUnusedRandoms()
    for mat in unusedRandoms:
        bpy.data.materials.remove( mat )
        
        
class RemoveUnusedRandomOp( bpy.types.Operator ):
    bl_label = "Remove Unused Randoms"
    bl_options = { 'REGISTER'}
    bl_idname = "material.remove_unusedmats"
    
    def execute( self, context ):
        removeUnusedRandoms()
        return {'FINISHED'}

            

class RandomMatOp( bpy.types.Operator ):
    
    bl_label = "Random Face Materials"
    bl_idname = "material.randommat"
    bl_options = { 'REGISTER', 'UNDO' }
    
    
    def execute( self, context ):
        ob = context.active_object
        scn = bpy.context.scene
        
        if len( ob.material_slots ) < len( ob.data.faces ):
            clearMaterialSlots( ob )
            removeUnusedRandoms()
            makeMaterials( ob, scn.gray_scale, scn.color_min, scn.color_max )
            assignMats2Ob( ob )
        else:
            changeFaceMaterials( ob, scn.gray_scale,
                                 scn.color_min, scn.color_max )
            
        return {'FINISHED'}
    
    @classmethod    
    def poll( self, context ):
        ob = context.active_object
        return ob != None and ob.select
       

class KeyRandomColorOp( bpy.types.Operator ):
    
    bl_idname = "anim.keyrandomcolor"
    bl_label = "Keyframe Colors"
    bl_description = "Not Yet Implemented"
    bl_options = { 'REGISTER', 'UNDO' }
    
    def execute( self, context ): 
        mats = context.object.data.materials
        scn = bpy.context.scene
        for mat in mats:
            mat.keyframe_insert( "diffuse_color" )
        return { 'FINISHED'}
    
    @classmethod
    def poll( self, context ):
        ob = context.active_object
        
        if ob == None:
            return False
        if len( ob.data.materials ) < len( ob.data.faces ):
            return False
        
        return ob.select

class RandomMatPanel( bpy.types.Panel ):
    bl_label = "Random Mat Panel"
    bl_region_type = "TOOLS"
    bl_space_type = "VIEW_3D"
    
    def draw( self, context ):
        scn = context.scene
        new_row = self.layout.row
        
        new_row().prop( scn, "gray_scale" )
        new_row().prop( scn, "color_min" )
        new_row().prop( scn, "color_max" )
        new_row().operator( "material.randommat" )
        new_row().operator( "anim.keyrandomcolor" )
        new_row().operator( "material.remove_unusedmats" )
        new_row().operator( "material.randommat" )
        
        matCount = len( getUnusedRandoms() )
        countLabel = "Unused Random Materials: %d" % matCount
        self.layout.row().label( countLabel )
        


def register():
    scn_type = bpy.types.Scene
    BoolProperty = bpy.props.BoolProperty
    FloatProperty = bpy.props.FloatProperty
    
    scn_type.gray_scale = BoolProperty( name="Gray Scale", default = False,
                                 description = "Gray scale random materials?")
                               
    scn_type.color_min = FloatProperty( name = "Color Min", default = 0, min=0,
                         max=1, description = "Extreme Min for R, G, and B" )
                         
    scn_type.color_max = FloatProperty( name = "Color Max", default = 1, min=0,
                         max=1, description = "Max Color for R, G, and B" )
    
    
    bpy.utils.register_class( KeyRandomColorOp )
    bpy.utils.register_class( RemoveUnusedRandomOp )
    bpy.utils.register_class( RandomMatOp )
    bpy.utils.register_class( RandomMatPanel )

def unregister():
    bpy.utils.unregister_class( RandomMatPanel )
    bpy.utils.unregister_class( RandomMatOp )
    bpy.utils.unregister_class( RemoveUnusedRandomOp )
    bpy.utils.unregister_class( KeyRandomColorOp )

if __name__ == '__main__':
    register()

Thats just what I asked for, thank you. I could then alter the curve type to get a more flickering or strobe like change. Excellent for use as a random pattern generator (motion graphics), i could imagine altering the mesh shape too with modifiers.

Great little tool cotejrp1

From the bottom of my heart, thank you for saying that. It means a lot.

I’m trying to use this plugin but getting an error when I click on Random Face Materials:

Traceback (most recent call last):
  File "/home/hellocatfood/.config/blender/2.69/scripts/addons/randomcolour.py", line 176, in poll
    if len( ob.data.materials ) < len( ob.data.faces ):
AttributeError: 'Mesh' object has no attribute 'faces'

location: <unknown location>:-1

Is there a working update to this script?

I just wrote a quick update to this. This should work now…


# random_face_color.py (c) 2011 Phil Cote (cotejrp1)
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
bl_info = {
    'name': 'Random Face Color',
    'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
    'version': (0,3),
    "blender": (2, 5, 9),
    "api": 39307,
    'location': '',
    'description': 'Generate random diffuse faces on each face of a mesh',
    'warning': 'Don\'t use on meshes that have a large number of faces.',
    'category': 'Add Material'}


"""
How to use:
- Select a material with no more than one material on it.
- Hit "t" to open the toolbar.
- Set desired options for color min and max intensity as well as whether or not 
  to gray scale it.
- Under "Random Mat Panel", hit the "Random Face Materials" button.


Note: as of this revision, it works best on just one object.
It works slightly less well when colorizing multiple scene objects.
"""


import bpy
import time
from random import random, seed


# start simple be just generating random colors
def getRandomColor( gray_scale, color_min, color_max ):
    seed( time.time() )
    
    # if the min and max don't make sense, just ignore it.
    if color_min > color_max:
        color_min, color_max = 0, 1
    
    new_color = lambda : color_min + random() * ( color_max - color_min )
    
    if gray_scale:
        val = new_color()
        green = blue = red = val
    else:
        red = new_color()
        green = new_color()
        blue = new_color()
    
    
    return red, green, blue




def makeMaterials( ob, gray_scale, color_min, color_max ):
    
    for face in ob.data.polygons:
        randcolor = getRandomColor( gray_scale, color_min, color_max )
        mat = bpy.data.materials.new( "randmat" )
        mat.diffuse_color = randcolor




def changeFaceMaterials( ob, gray_scale, color_min, color_max ):
    print( "call to chang face materials" )
    
    mats = ob.data.materials
    for face in ob.data.polygons:
        randcolor = getRandomColor( gray_scale, color_min, color_max )
        mats[ face.material_index ].diffuse_color = randcolor
        
    
    
def assignMats2Ob( ob ):
    
    mats = [ mat for mat in bpy.data.materials if mat.name.startswith( "rand" )]
    
    # load up the materials into the material slots
    for mat in mats:
        bpy.ops.object.material_slot_add()
        ob.active_material = mat
    
    # tie the loaded up materials to each of the faces
    polygons = ob.data.polygons
    for i in range( len( polygons ) ):
        polygons[i].material_index = i


getUnusedRandoms = lambda : [ x for x in bpy.data.materials 
                   if x.name.startswith( "randmat" ) and x.users == 0 ]




def clearMaterialSlots( ob ):
    while len( ob.material_slots ) > 0:
        bpy.ops.object.material_slot_remove()
         
         
def removeUnusedRandoms():
    unusedRandoms = getUnusedRandoms()
    for mat in unusedRandoms:
        bpy.data.materials.remove( mat )
        
        
class RemoveUnusedRandomOp( bpy.types.Operator ):
    bl_label = "Remove Unused Randoms"
    bl_options = { 'REGISTER'}
    bl_idname = "material.remove_unusedmats"
    
    def execute( self, context ):
        removeUnusedRandoms()
        return {'FINISHED'}


            


class RandomMatOp( bpy.types.Operator ):
    
    bl_label = "Random Face Materials"
    bl_idname = "material.randommat"
    bl_options = { 'REGISTER', 'UNDO' }
    
    
    def execute( self, context ):
        ob = context.active_object
        scn = bpy.context.scene
        
        if len( ob.material_slots ) < len( ob.data.polygons ):
            clearMaterialSlots( ob )
            removeUnusedRandoms()
            makeMaterials( ob, scn.gray_scale, scn.color_min, scn.color_max )
            assignMats2Ob( ob )
        else:
            changeFaceMaterials( ob, scn.gray_scale,
                                 scn.color_min, scn.color_max )
            
        return {'FINISHED'}
    
    @classmethod    
    def poll( self, context ):
        ob = context.active_object
        return ob != None and ob.select
       


class KeyRandomColorOp( bpy.types.Operator ):
    
    bl_idname = "anim.keyrandomcolor"
    bl_label = "Keyframe Colors"
    bl_description = "Not Yet Implemented"
    bl_options = { 'REGISTER', 'UNDO' }
    
    def execute( self, context ): 
        mats = context.object.data.materials
        scn = bpy.context.scene
        for mat in mats:
            mat.keyframe_insert( "diffuse_color" )
        return { 'FINISHED'}
    
    @classmethod
    def poll( self, context ):
        ob = context.active_object
        
        if ob == None:
            return False
        if len( ob.data.materials ) < len( ob.data.polygons ):
            return False
        
        return ob.select


class RandomMatPanel( bpy.types.Panel ):
    bl_label = "Random Mat Panel"
    bl_region_type = "TOOLS"
    bl_space_type = "VIEW_3D"
    
    def draw( self, context ):
        scn = context.scene
        new_row = self.layout.row
        
        new_row().prop( scn, "gray_scale" )
        new_row().prop( scn, "color_min" )
        new_row().prop( scn, "color_max" )
        new_row().operator( "material.randommat" )
        new_row().operator( "anim.keyrandomcolor" )
        new_row().operator( "material.remove_unusedmats" )
        new_row().operator( "material.randommat" )
        
        matCount = len( getUnusedRandoms() )
        countLabel = "Unused Random Materials: %d" % matCount
        self.layout.row().label( countLabel )
        




def register():
    scn_type = bpy.types.Scene
    BoolProperty = bpy.props.BoolProperty
    FloatProperty = bpy.props.FloatProperty
    
    scn_type.gray_scale = BoolProperty( name="Gray Scale", default = False,
                                 description = "Gray scale random materials?")
                               
    scn_type.color_min = FloatProperty( name = "Color Min", default = 0, min=0,
                         max=1, description = "Extreme Min for R, G, and B" )
                         
    scn_type.color_max = FloatProperty( name = "Color Max", default = 1, min=0,
                         max=1, description = "Max Color for R, G, and B" )
    
    
    bpy.utils.register_class( KeyRandomColorOp )
    bpy.utils.register_class( RemoveUnusedRandomOp )
    bpy.utils.register_class( RandomMatOp )
    bpy.utils.register_class( RandomMatPanel )


def unregister():
    bpy.utils.unregister_class( RandomMatPanel )
    bpy.utils.unregister_class( RandomMatOp )
    bpy.utils.unregister_class( RemoveUnusedRandomOp )
    bpy.utils.unregister_class( KeyRandomColorOp )


if __name__ == '__main__':
    register()







This is a fun script. But if I want to run it a second time on the same mesh, how do I delete all the material slots en masse? Because there may be over 100 material slots created.

Thx @cotejrp1!

@riveter > you can use the combined Code with delete slot materials if you want


bl_info = {
    "name": "Delete Slot Materials",
    "category": "3D View",
}

#Button
#layout.operator("material.remove", text="Remove all Slot Mat", icon='CANCEL')    


import bpy

class deleteMat(bpy.types.Operator):
    """delete materials with an value slider"""
    bl_idname = "material.remove"
    bl_label = "Delete all Material"
    bl_options = {'REGISTER', 'UNDO'}


    deleteMat = bpy.props.IntProperty(name="Delete all Material", description="How many times?", default=100, min=1, soft_max=500, step=1)
    
    def execute(self, context):        
        for i in range(self.deleteMat):      
            bpy.ops.object.material_slot_remove()
        return {'FINISHED'}


def register():
    bpy.utils.register_class(deleteMat)

def unregister():
    bpy.utils.unregister_class(deleteMat)

if __name__ == "__main__":
    register()

combined > new Button = Remove Slot Materials (with value slider)


# random_face_color.py (c) 2011 Phil Cote (cotejrp1)
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
bl_info = {
    'name': 'Random Face Color',
    'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
    'version': (0,3),
    "blender": (2, 5, 9),
    "api": 39307,
    'location': '',
    'description': 'Generate random diffuse faces on each face of a mesh',
    'warning': 'Don\'t use on meshes that have a large number of faces.',
    'category': 'Add Material'}


"""
How to use:
- Select a material with no more than one material on it.
- Hit "t" to open the toolbar.
- Set desired options for color min and max intensity as well as whether or not 
  to gray scale it.
- Under "Random Mat Panel", hit the "Random Face Materials" button.


Note: as of this revision, it works best on just one object.
It works slightly less well when colorizing multiple scene objects.
"""


import bpy
import time
from random import random, seed


# start simple be just generating random colors
def getRandomColor( gray_scale, color_min, color_max ):
    seed( time.time() )
    
    # if the min and max don't make sense, just ignore it.
    if color_min > color_max:
        color_min, color_max = 0, 1
    
    new_color = lambda : color_min + random() * ( color_max - color_min )
    
    if gray_scale:
        val = new_color()
        green = blue = red = val
    else:
        red = new_color()
        green = new_color()
        blue = new_color()
    
    
    return red, green, blue




def makeMaterials( ob, gray_scale, color_min, color_max ):
    
    for face in ob.data.polygons:
        randcolor = getRandomColor( gray_scale, color_min, color_max )
        mat = bpy.data.materials.new( "randmat" )
        mat.diffuse_color = randcolor




def changeFaceMaterials( ob, gray_scale, color_min, color_max ):
    print( "call to chang face materials" )
    
    mats = ob.data.materials
    for face in ob.data.polygons:
        randcolor = getRandomColor( gray_scale, color_min, color_max )
        mats[ face.material_index ].diffuse_color = randcolor
        
    
    
def assignMats2Ob( ob ):
    
    mats = [ mat for mat in bpy.data.materials if mat.name.startswith( "rand" )]
    
    # load up the materials into the material slots
    for mat in mats:
        bpy.ops.object.material_slot_add()
        ob.active_material = mat
    
    # tie the loaded up materials to each of the faces
    polygons = ob.data.polygons
    for i in range( len( polygons ) ):
        polygons[i].material_index = i


getUnusedRandoms = lambda : [ x for x in bpy.data.materials 
                   if x.name.startswith( "randmat" ) and x.users == 0 ]




def clearMaterialSlots( ob ):
    while len( ob.material_slots ) > 0:
        bpy.ops.object.material_slot_remove()
         
         
def removeUnusedRandoms():
    unusedRandoms = getUnusedRandoms()
    for mat in unusedRandoms:
        bpy.data.materials.remove( mat )
        
        
class RemoveUnusedRandomOp( bpy.types.Operator ):
    bl_label = "Remove Unused Randoms"
    bl_options = { 'REGISTER'}
    bl_idname = "material.remove_unusedmats"
    
    def execute( self, context ):
        removeUnusedRandoms()
        return {'FINISHED'}


            


class RandomMatOp( bpy.types.Operator ):
    
    bl_label = "Random Face Materials"
    bl_idname = "material.randommat"
    bl_options = { 'REGISTER', 'UNDO' }
    
    
    def execute( self, context ):
        ob = context.active_object
        scn = bpy.context.scene
        
        if len( ob.material_slots ) < len( ob.data.polygons ):
            clearMaterialSlots( ob )
            removeUnusedRandoms()
            makeMaterials( ob, scn.gray_scale, scn.color_min, scn.color_max )
            assignMats2Ob( ob )
        else:
            changeFaceMaterials( ob, scn.gray_scale,
                                 scn.color_min, scn.color_max )
            
        return {'FINISHED'}
    
    @classmethod    
    def poll( self, context ):
        ob = context.active_object
        return ob != None and ob.select
       


class KeyRandomColorOp( bpy.types.Operator ):
    
    bl_idname = "anim.keyrandomcolor"
    bl_label = "Keyframe Colors"
    bl_description = "Not Yet Implemented"
    bl_options = { 'REGISTER', 'UNDO' }
    
    def execute( self, context ): 
        mats = context.object.data.materials
        scn = bpy.context.scene
        for mat in mats:
            mat.keyframe_insert( "diffuse_color" )
        return { 'FINISHED'}
    
    @classmethod
    def poll( self, context ):
        ob = context.active_object
        
        if ob == None:
            return False
        if len( ob.data.materials ) < len( ob.data.polygons ):
            return False
        
        return ob.select


class RandomMatPanel( bpy.types.Panel ):
    bl_label = "Random Mat Panel"
    bl_region_type = "TOOLS"
    bl_space_type = "VIEW_3D"
    
    def draw( self, context ):
        scn = context.scene
        new_row = self.layout.row
        
        new_row().prop( scn, "gray_scale" )
        new_row().prop( scn, "color_min" )
        new_row().prop( scn, "color_max" )
        new_row().operator( "material.randommat" )
        new_row().operator( "anim.keyrandomcolor" )
        new_row().operator( "material.remove_unusedmats" )
        new_row().operator( "material.randommat" )
        new_row().operator("material.remove", text="Remove Slot Materials")    
        
        
        matCount = len( getUnusedRandoms() )
        countLabel = "Unused Random Materials: %d" % matCount
        self.layout.row().label( countLabel )
        

class deleteMat(bpy.types.Operator):
    """delete materials with an value slider"""
    bl_idname = "material.remove"
    bl_label = "Delete all Material"
    bl_options = {'REGISTER', 'UNDO'}


    deleteMat = bpy.props.IntProperty(name="Delete all Material", description="How many times?", default=100, min=1, soft_max=5000, step=1)
    
    def execute(self, context):        
        for i in range(self.deleteMat):      
            bpy.ops.object.material_slot_remove()
        return {'FINISHED'}


def register():
    scn_type = bpy.types.Scene
    BoolProperty = bpy.props.BoolProperty
    FloatProperty = bpy.props.FloatProperty
    
    scn_type.gray_scale = BoolProperty( name="Gray Scale", default = False,
                                 description = "Gray scale random materials?")
                               
    scn_type.color_min = FloatProperty( name = "Color Min", default = 0, min=0,
                         max=1, description = "Extreme Min for R, G, and B" )
                         
    scn_type.color_max = FloatProperty( name = "Color Max", default = 1, min=0,
                         max=1, description = "Max Color for R, G, and B" )
    
    
    bpy.utils.register_class( KeyRandomColorOp )
    bpy.utils.register_class( RemoveUnusedRandomOp )
    bpy.utils.register_class( RandomMatOp )
    bpy.utils.register_class( RandomMatPanel )
    bpy.utils.register_class(deleteMat)

def unregister():
    bpy.utils.unregister_class( RandomMatPanel )
    bpy.utils.unregister_class( RandomMatOp )
    bpy.utils.unregister_class( RemoveUnusedRandomOp )
    bpy.utils.unregister_class( KeyRandomColorOp )
    bpy.utils.unregister_class(deleteMat)

if __name__ == '__main__':
    register()

The removal code works great @mkbreuer. Thank you.