[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