[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [4503] trunk/py/scripts/addons/ space_view3d_materials_utils.py: Addons: Material Utils - Revised code, added descriptions, fixed error if material slot is empty, made Material Replace operator a popup and added feature to update selection based on affected objects .

Sebastian Nell codemanx at gmx.de
Sun May 5 01:25:40 CEST 2013


Revision: 4503
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=4503
Author:   codemanx
Date:     2013-05-04 23:25:39 +0000 (Sat, 04 May 2013)
Log Message:
-----------
Addons: Material Utils - Revised code, added descriptions, fixed error if material slot is empty, made Material Replace operator a popup and added feature to update selection based on affected objects. As the dropdown of prop_search may reach over the borders of the popup, 2.66.6 is required, as the entire popup was closing before this version (now the click is only handled by the dropdown list, see bug #35154).

Modified Paths:
--------------
    trunk/py/scripts/addons/space_view3d_materials_utils.py

Modified: trunk/py/scripts/addons/space_view3d_materials_utils.py
===================================================================
--- trunk/py/scripts/addons/space_view3d_materials_utils.py	2013-05-04 15:56:12 UTC (rev 4502)
+++ trunk/py/scripts/addons/space_view3d_materials_utils.py	2013-05-04 23:25:39 UTC (rev 4503)
@@ -23,8 +23,8 @@
 bl_info = {
     "name": "Material Utils",
     "author": "michaelw",
-    "version": (1, 4),
-    "blender": (2, 62, 0),
+    "version": (1, 5),
+    "blender": (2, 66, 6),
     "location": "View3D > Q key",
     "description": "Menu of material tools (assign, select..)  in the 3D View",
     "warning": "Buggy, Broken in Cycles mode",
@@ -35,7 +35,8 @@
     "category": "Material"}
 
 """
-This script has several functions and operators... grouped for convenience
+This script has several functions and operators, grouped for convenience:
+
 * assign material:
     offers the user a list of ALL the materials in the blend file and an
     additional "new" entry the chosen material will be assigned to all the
@@ -63,15 +64,32 @@
     for all selected objects any empty material slots or material slots with
     materials that are not used by the mesh polygons will be removed.
 
-* Any un-used materials and slots will be removed
+* remove material slots
+    removes all material slots of the active object.
+
+* material to texface
+    transfers material assignments to the UV editor. This is useful if you
+    assigned materials in the properties editor, as it will use the already
+    set up materials to assign the UV images per-face. It will use the first
+    enabled image texture it finds.
+
+* texface to materials
+    creates texture materials from images assigned in UV editor.
+
+* replace materials
+    lets your replace one material by another. Optionally for all objects in
+    the blend, otherwise for selected editable objects only. An additional
+    option allows you to update object selection, to indicate which objects
+    were affected and which not.
+
 """
 
 
 import bpy
-from bpy.props import*
+from bpy.props import StringProperty, BoolProperty
 
 
-def replace_material(m1, m2, all_objects=False):
+def replace_material(m1, m2, all_objects=False, update_selection=False):
     # replace material named m1 with material named m2
     # m1 is the name of original material
     # m2 is the name of the material to replace it with
@@ -80,10 +98,9 @@
     matorg = bpy.data.materials.get(m1)
     matrep = bpy.data.materials.get(m2)
 
-    if matorg and matrep:
+    if matorg != matrep and None not in (matorg, matrep):
         #store active object
         scn = bpy.context.scene
-        ob_active = bpy.context.active_object
 
         if all_objects:
             objs = bpy.data.objects
@@ -93,18 +110,27 @@
 
         for ob in objs:
             if ob.type == 'MESH':
-                scn.objects.active = ob
 
-                for m in ob.material_slots.values():
+                match = False
+
+                for m in ob.material_slots:
                     if m.material == matorg:
                         m.material = matrep
                         # don't break the loop as the material can be
                         # ref'd more than once
 
-    else:
-        print('no match to replace')
+                        # Indicate which objects were affected
+                        if update_selection:
+                            ob.select = True
+                            match = True
 
+                if update_selection and not match:
+                    ob.select = False
 
+    #else:
+    #    print('Replace material: nothing to replace')
+
+
 def select_material_by_name(find_mat_name):
     #in object mode selects all objects with material find_mat_name
     #in edit mode selects all polygons with material find_mat_name
@@ -131,7 +157,7 @@
         objs = bpy.data.objects
         for ob in objs:
             if ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
-                ms = ob.material_slots.values()
+                ms = ob.material_slots
                 for m in ms:
                     if m.material == find_mat:
                         ob.select = True
@@ -149,7 +175,7 @@
     else:
         #it's editmode, so select the polygons
         ob = actob
-        ms = ob.material_slots.values()
+        ms = ob.material_slots
 
         #same material can be on multiple slots
         slot_indeces = []
@@ -186,23 +212,24 @@
     for ob in bpy.context.selected_editable_objects:
         if ob.type == 'MESH':
             #get the materials from slots
-            ms = ob.material_slots.values()
+            ms = ob.material_slots
 
             #build a list of images, one per material
             images = []
             #get the textures from the mats
             for m in ms:
+                if m.material is None:
+                    continue
                 gotimage = False
-                textures = m.material.texture_slots.values()
-                if len(textures) >= 1:
-                    for t in textures:
-                        if t != None:
-                            tex = t.texture
-                            if tex.type == 'IMAGE':
-                                img = tex.image
-                                images.append(img)
-                                gotimage = True
-                                break
+                textures = zip(m.material.texture_slots, m.material.use_textures)
+                for t, enabled in textures:
+                    if enabled and t is not None:
+                        tex = t.texture
+                        if tex.type == 'IMAGE':
+                            img = tex.image
+                            images.append(img)
+                            gotimage = True
+                            break
 
                 if not gotimage:
                     print('noimage on', m.name)
@@ -222,10 +249,10 @@
             #get active uvlayer
             for t in  me.uv_textures:
                 if t.active:
-                    uvtex = t.data.values()
+                    uvtex = t.data
                     for f in me.polygons:
                         #check that material had an image!
-                        if images[f.material_index] != None:
+                        if images[f.material_index] is not None:
                             uvtex[f.index].image = images[f.material_index]
                         else:
                             uvtex[f.index].image = None
@@ -473,7 +500,7 @@
 
         i = 0
         for f in faceindex:
-            if f != None:
+            if f is not None:
                 me.polygons[i].material_index = f
             i += 1
     if editmode:
@@ -494,12 +521,12 @@
 class VIEW3D_OT_texface_to_material(bpy.types.Operator):
     """Create texture materials for images assigned in UV editor"""
     bl_idname = "view3d.texface_to_material"
-    bl_label = "MW Texface Images to Material/Texture"
+    bl_label = "Texface Images to Material/Texture (Material Utils)"
     bl_options = {'REGISTER', 'UNDO'}
 
     @classmethod
     def poll(cls, context):
-        return context.active_object != None
+        return context.active_object is not None
 
     def execute(self, context):
         if context.selected_editable_objects:
@@ -514,7 +541,7 @@
 class VIEW3D_OT_assign_material(bpy.types.Operator):
     """Assign a material to the selection"""
     bl_idname = "view3d.assign_material"
-    bl_label = "MW Assign Material"
+    bl_label = "Assign Material (Material Utils)"
     bl_options = {'REGISTER', 'UNDO'}
 
     matname = StringProperty(
@@ -526,7 +553,7 @@
 
     @classmethod
     def poll(cls, context):
-        return context.active_object != None
+        return context.active_object is not None
 
     def execute(self, context):
         mn = self.matname
@@ -541,12 +568,12 @@
     """Removes any material slots from selected objects """ \
     """that are not used by the mesh"""
     bl_idname = "view3d.clean_material_slots"
-    bl_label = "MW Clean Material Slots"
+    bl_label = "Clean Material Slots (Material Utils)"
     bl_options = {'REGISTER', 'UNDO'}
 
     @classmethod
     def poll(cls, context):
-        return context.active_object != None
+        return context.active_object is not None
 
     def execute(self, context):
         cleanmatslots()
@@ -556,12 +583,12 @@
 class VIEW3D_OT_material_to_texface(bpy.types.Operator):
     """Transfer material assignments to UV editor"""
     bl_idname = "view3d.material_to_texface"
-    bl_label = "MW Material Images to Texface"
+    bl_label = "Material Images to Texface (Material Utils)"
     bl_options = {'REGISTER', 'UNDO'}
 
     @classmethod
     def poll(cls, context):
-        return context.active_object != None
+        return context.active_object is not None
 
     def execute(self, context):
         mat_to_texface()
@@ -570,12 +597,12 @@
 class VIEW3D_OT_material_remove(bpy.types.Operator):
     """Remove all material slots from active objects"""
     bl_idname = "view3d.material_remove"
-    bl_label = "Remove All Material Slots"
+    bl_label = "Remove All Material Slots (Material Utils)"
     bl_options = {'REGISTER', 'UNDO'}
 
     @classmethod
     def poll(cls, context):
-        return context.active_object != None
+        return context.active_object is not None
 
     def execute(self, context):
         remove_materials()
@@ -585,7 +612,7 @@
 class VIEW3D_OT_select_material_by_name(bpy.types.Operator):
     """Select geometry with this material assigned to it"""
     bl_idname = "view3d.select_material_by_name"
-    bl_label = "MW Select Material By Name"
+    bl_label = "Select Material By Name (Material Utils)"
     bl_options = {'REGISTER', 'UNDO'}
     matname = StringProperty(
             name='Material Name',
@@ -595,7 +622,7 @@
 
     @classmethod
     def poll(cls, context):
-        return context.active_object != None
+        return context.active_object is not None
 
     def execute(self, context):
         mn = self.matname
@@ -606,16 +633,16 @@
 class VIEW3D_OT_replace_material(bpy.types.Operator):
     """Replace a material by name"""
     bl_idname = "view3d.replace_material"
-    bl_label = "MW Replace Material"
+    bl_label = "Replace Material (Material Utils)"
     bl_options = {'REGISTER', 'UNDO'}
 
     matorg = StringProperty(
-            name='Material to Replace',
-            description="Name of Material to Assign",

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list