mcjMergeSelectedObjectsMats



Introduction

Blender Python Script to combine materials with the same diffuse texture map and the same diffuse color

for all the selected objects

This was done very quickly and may be improved in the future

namely the "signature" of each material needs to include things like opacity

if bad luck has it, all your skin materials may be replaced by the one skin material which happens to be fully transparent



Use

In Blender, following the Import of an .obj file

change one of the Blender panels to a Text Editor

do a Text / Load Text

load mcjMergeSelectedObjectsMats

select objects in the scenes for which you want materials to be combined

click in the Run Script button



Grosso modo

first it collects all the materials for the selected objects

then

for each material in that list, ( which we will call the reference mat )
for each object,
for each material slot
if that slot has the same diffuse texture and the same diffuse color as the reference mat
it makes this material slot share the reference material

note that this is based on the premise that the diffuse_color texture map is prefixed with “kd”
which is the case for objects imported from .obj files

one nice feature is that it should work for non-node-based materials too ( blender internal etc )

when i select Aiko3, most of the skin materials were made to share the ‘SkinHands’ material




import bpy

materials = []

#---------- getMap ----------
def getMap( mat, key, keydot ):
texSlots = mat.texture_slots
for t in texSlots:
if t:
if ( t.name == key ) or ( t.name.startswith(keydot) ):
return( t.texture )
return 0

#---------- getImage ----------
def getMaterialUID( mat ):
    KdMap = getMap( mat, 'Kd', 'Kd.' )
    im = 0;
    if KdMap:
        im = KdMap.image.filepath
    return( [im, mat.diffuse_color] )

#---------- getMap ----------
def swapDuplicates( refmat, slots, refUID ):
for slot in slots:
myUID = getMaterialUID( slot.material )
if ( myUID[0] == refUID[0] ):
if ( myUID[1] == refUID[1] ):
slot.material = refmat

#---------- mergeSelectedObjectsMats ----------
def collectMats( o ):
for slot in o.material_slots:
materials.append( slot.material )

#---------- mergeSelectedObjectsMats ----------
def mergeSelectedObjectsMats( o ):
slots = []
for slot in o.material_slots:
slots.append( slot )
for mat in materials:
myUID = getMaterialUID( mat )
swapDuplicates( mat, slots, myUID )

objects = bpy.context.selected_objects

for obj in objects:
    collectMats( obj )

for obj in objects:
    mergeSelectedObjectsMats( obj )
   


License

// by mCasual/Jacques
// You can use this software freely for personal or commercial use.
// You may not resell, sub-license or rent this software in any way.
// You may credit this software to mCasual/Jacques
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
// PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


ċ
mCasual Jacques,
Jul 3, 2014, 6:58 AM
Comments