[Bf-extensions-cvs] [abc7a079] master: Materials Utils: Update to version 1.0.4

lijenstina noreply at git.blender.org
Sat Feb 24 22:45:23 CET 2018


Commit: abc7a07914f3b7273ca7717d2691ac2b8dec2de4
Author: lijenstina
Date:   Sat Feb 24 22:44:17 2018 +0100
Branches: master
https://developer.blender.org/rBAabc7a07914f3b7273ca7717d2691ac2b8dec2de4

Materials Utils: Update to version 1.0.4

Bump version to 1.0.4
Some style tweaks
Refactor some of the if - else loops
Correct some of the tooltips
Various UI tweaks

Improvements:
- Introduce a pop-up menu for assigning and selecting materials
- Add support for removing empty material slots for non mesh objects
- Activate the material slot more reliably after creation, applying
- Texture Renamer: add option for rename all objects in the data
- Warning Messages: better formatting of console prints

===================================================================

M	materials_utils/__init__.py
M	materials_utils/material_converter.py
M	materials_utils/materials_cycles_converter.py
M	materials_utils/texture_rename.py
M	materials_utils/warning_messages_utils.py

===================================================================

diff --git a/materials_utils/__init__.py b/materials_utils/__init__.py
index 3bc94ddf..19be24d2 100644
--- a/materials_utils/__init__.py
+++ b/materials_utils/__init__.py
@@ -26,7 +26,7 @@
 bl_info = {
     "name": "Materials Utils Specials",
     "author": "Community",
-    "version": (1, 0, 3),
+    "version": (1, 0, 4),
     "blender": (2, 77, 0),
     "location": "Materials Properties Specials > Shift Q",
     "description": "Materials Utils and Convertors",
@@ -34,7 +34,7 @@ bl_info = {
     "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
                 "Scripts/3D_interaction/Materials_Utils",
     "category": "Material"
-    }
+}
 
 if "bpy" in locals():
     import importlib
@@ -51,27 +51,35 @@ else:
 import bpy
 import os
 from os import (
-        path as os_path,
-        access as os_access,
-        remove as os_remove,
-        )
+    path as os_path,
+    access as os_access,
+    remove as os_remove,
+)
 from bpy.props import (
-        StringProperty,
-        BoolProperty,
-        EnumProperty,
-        PointerProperty,
-        )
+    BoolProperty,
+    CollectionProperty,
+    EnumProperty,
+    IntProperty,
+    StringProperty,
+    PointerProperty,
+)
 from bpy.types import (
-        Menu,
-        Operator,
-        Panel,
-        AddonPreferences,
-        PropertyGroup,
-        )
+    AddonPreferences,
+    Menu,
+    Operator,
+    Panel,
+    PropertyGroup,
+    UIList,
+)
 from .warning_messages_utils import (
-        warning_messages,
-        c_data_has_materials,
-        )
+    warning_messages,
+    c_data_has_materials,
+    c_obj_data_has_materials,
+)
+
+# Globals
+UNDO_MESSAGE = "*Only Undo is available*"
+COLUMN_SPLIT = 20
 
 
 # Functions
@@ -146,7 +154,7 @@ def replace_material(m1, m2, all_objects=False, update_selection=False, operator
                     if m.material == matorg:
                         m.material = matrep
                         # don't break the loop as the material can be
-                        # ref'd more than once
+                        # referenced more than once
 
                         # Indicate which objects were affected
                         if update_selection:
@@ -169,7 +177,7 @@ def select_material_by_name(find_mat_name):
     if find_mat is None:
         return
 
-    # check for editmode
+    # check for edit mode
     editmode = False
 
     scn = bpy.context.scene
@@ -200,7 +208,7 @@ def select_material_by_name(find_mat_name):
             else:
                 ob.select = False
     else:
-        # it's editmode, so select the polygons
+        # it's edit mode, so select the polygons
         ob = actob
         ms = ob.material_slots
 
@@ -227,7 +235,7 @@ def select_material_by_name(find_mat_name):
 
 def mat_to_texface(operator=None):
     # assigns the first image in each material to the polygons in the active
-    # uvlayer for all selected objects
+    # uv layer for all selected objects
 
     # check for editmode
     editmode = False
@@ -282,7 +290,7 @@ def mat_to_texface(operator=None):
                 bpy.ops.mesh.uv_texture_add()
                 scn.objects.active = actob
 
-            # get active uvlayer
+            # get active uv layer
             for t in me.uv_textures:
                 if t.active:
                     uvtex = t.data
@@ -316,7 +324,7 @@ def assignmatslots(ob, matlist):
     scn.objects.active = ob
 
     for s in ob.material_slots:
-        bpy.ops.object.material_slot_remove()
+        remove_material_slot()
 
     # re-add them and assign material
     if matlist:
@@ -330,7 +338,7 @@ def assignmatslots(ob, matlist):
                 # to face indices, mat tries to get an '' as mat index
                 pass
 
-    # restore active object:
+    # restore active object
     scn.objects.active = ob_active
 
 
@@ -352,65 +360,97 @@ def cleanmatslots(operator=None):
     objs = bpy.context.selected_editable_objects
     # collect all object names for warning_messages
     message_a = []
-    # Flag if there are non MESH objects selected
-    mixed_obj = False
+    # Flags if there are non MESH objects selected
+    mixed_obj, mixed_obj_slot = False, False
 
     for ob in objs:
-        if ob.type == 'MESH':
-            mats = ob.material_slots.keys()
-
-            # if mats is empty then mats[faceindex] will be out of range
-            if mats:
-                # check the polygons on the mesh to build a list of used materials
-                usedMatIndex = []  # we'll store used materials indices here
-                faceMats = []
-                me = ob.data
-                for f in me.polygons:
-                    # get the material index for this face...
-                    faceindex = f.material_index
-
-                    # indices will be lost: Store face mat use by name
-                    currentfacemat = mats[faceindex]
-                    faceMats.append(currentfacemat)
-
-                    # check if index is already listed as used or not
-                    found = False
-                    for m in usedMatIndex:
-                        if m == faceindex:
-                            found = True
-                            # break
-
-                    if found is False:
-                        # add this index to the list
-                        usedMatIndex.append(faceindex)
-
-                # re-assign the used mats to the mesh and leave out the unused
-                ml = []
-                mnames = []
-                for u in usedMatIndex:
-                    ml.append(mats[u])
-                    # we'll need a list of names to get the face indices...
-                    mnames.append(mats[u])
-
-                assignmatslots(ob, ml)
-
-                # restore face indices:
-                i = 0
-                for f in me.polygons:
-                    matindex = mnames.index(faceMats[i])
-                    f.material_index = matindex
-                    i += 1
-            else:
-                message_a.append(getattr(ob, "name", "NO NAME"))
-                continue
-        else:
+        if ob.type != 'MESH':
+            mat_empty = []
             message_a.append(getattr(ob, "name", "NO NAME"))
             if mixed_obj is False:
                 mixed_obj = True
+
+            # at least try to remove empty material slots
+            if ob.type in {'CURVE', 'SURFACE', 'FONT', 'META'}:
+                mats = ob.material_slots
+                mat_empty = [i for i, slot in enumerate(mats) if not slot.material]
+
+                if not mat_empty:
+                    continue
+
+                if mixed_obj_slot is False:
+                    mixed_obj_slot = True
+
+                # Ctx - copy the context for operator override
+                Ctx = bpy.context.copy()
+                # for this operator it needs only the active object replaced
+                Ctx['object'] = ob
+
+                for index in mat_empty:
+                    try:
+                        ob.active_material_index = index
+                        bpy.ops.object.material_slot_remove(Ctx)
+                    except:
+                        continue
+            continue
+
+        mats = ob.material_slots.keys()
+        maxindex = len(mats) - 1  # indices start from zero
+
+        # if mats is empty then mats[faceindex] will be out of range
+        if not mats:
+            message_a.append(getattr(ob, "name", "NO NAME"))
             continue
 
+        # check the polygons on the mesh to build a list of used materials
+        usedMatIndex = []   # we'll store used materials indices here
+        faceMats = []
+        badIndices = set()  # collect face indices that are out material slot's range
+        me = ob.data
+        for f in me.polygons:
+            # get the material index for this face...
+            faceindex = f.material_index
+            # check if the mats[faceindex] is not out of range
+            if faceindex > maxindex:
+                badIndices.add(faceindex)
+                continue
+
+            # indices will be lost: Store face mat use by name
+            currentfacemat = mats[faceindex]
+            faceMats.append(currentfacemat)
+
+            # check if index is already listed as used or not
+            found = False
+            for m in usedMatIndex:
+                if m == faceindex:
+                    found = True
+
+            if found is False:
+                # add this index to the list
+                usedMatIndex.append(faceindex)
+
+        # re-assign the used mats to the mesh and leave out the unused
+        ml = []
+        mnames = []
+        for u in usedMatIndex:
+            if u not in badIndices:
+                ml.append(mats[u])
+                # we'll need a list of names to get the face indices...
+                mnames.append(mats[u])
+
+        assignmatslots(ob, ml)
+
+        # restore face indices:
+        i = 0
+        for f in me.polygons:
+            if i not in badIndices:
+                matindex = mnames.index(faceMats[i])
+                f.material_index = matindex
+                i += 1
+
     if message_a and operator:
-        warn_mess = ('C_OB_MIX_NO_MAT' if mixed_obj is True else 'C_OB_NO_MAT')
+        warn_s = 'C_OB_MIX_NO_MAT' if mixed_obj is True else 'C_OB_NO_MAT'
+        warn_mess = 'C_OB_MIX_SLOT_MAT' if mixed_obj_slot else warn_s
         warning_messages(operator, warn_mess, message_a)
 
     if actob:
@@ -426,12 +466,11 @@ def cleanmatslots(operator=None):
 def assign_mat_mesh_edit(matname="Default", operator=None):
     actob = bpy.context.active_object
     found = False
-    for m in bpy.data.materials:
-        if m.name == matname:
-            target = m
-            found = True
-            break
-    if not found:
+
+    # check if material exists, if it doesn't then create it
+    target = bpy.data.materials.get(matname)
+
+    if not target:
         target = bpy.data.materials.new(matname)
 
     if (actob.type in {'MESH'} and actob.mode in {'EDIT'}):
@@ -447,8 +486,8 @@ def assign_mat_mesh_edit(matname="Default", operator=None):
                 break
             i += 1
 
+        # the material is not attached

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list