~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to release/scripts/addons/space_view3d_materials_utils.py

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#
23
23
# ##### END GPL LICENSE BLOCK #####
24
24
 
25
 
bl_addon_info = {
 
25
bl_info = {
26
26
    "name": "Material Utils",
27
27
    "author": "michaelw",
28
 
    "version": (1,3),
29
 
    "blender": (2, 5, 3),
30
 
    "api": 31965,
 
28
    "version": (1, 4),
 
29
    "blender": (2, 6, 2),
31
30
    "location": "View3D > Q key",
32
 
    "description": "Menu of material tools (assign, select by etc)  in the 3D View",
33
 
    "warning": "",
34
 
    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
35
 
        "Scripts/3D interaction/Materials Utils",
36
 
    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
37
 
        "func=detail&aid=22140&group_id=153&atid=469",
 
31
    "description": "Menu of material tools (assign, select..)  in the 3D View",
 
32
    "warning": "Buggy, Broken in Cycles mode",
 
33
    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
 
34
                "Scripts/3D interaction/Materials Utils",
 
35
    "tracker_url": "https://projects.blender.org/tracker/index.php?"
 
36
                   "func=detail&aid=22140",
38
37
    "category": "3D View"}
39
38
 
40
39
"""
41
40
This script has several functions and operators... grouped for convenience
42
41
* assign material:
43
 
    offers the user a list of ALL the materials in the blend file and an additional "new" entry
44
 
    the chosen material will be assigned to all the selected objects in object mode.
45
 
    
46
 
    in edit mode the selected faces get the selected material applied.
47
 
 
48
 
    if the user chose "new" the new material can be renamed using the "last operator" section of the toolbox
49
 
    After assigning the material "clean material slots" and "material to texface" are auto run to keep things tidy (see description bellow)
 
42
    offers the user a list of ALL the materials in the blend file and an
 
43
    additional "new" entry the chosen material will be assigned to all the
 
44
    selected objects in object mode.
 
45
 
 
46
    in edit mode the selected polygons get the selected material applied.
 
47
 
 
48
    if the user chose "new" the new material can be renamed using the
 
49
    "last operator" section of the toolbox.
 
50
    After assigning the material "clean material slots" and
 
51
    "material to texface" are auto run to keep things tidy
 
52
    (see description bellow)
50
53
 
51
54
 
52
55
* select by material
53
 
    in object mode this offers the user a menu of all materials in the blend file
54
 
    any objects using the selected material will become selected, any objects without the material will be removed from selection.
55
 
    
56
 
    in edit mode:  the menu offers only the materials attached to the current object. It will select the faces that use the material and deselect those that do not.
 
56
    in object mode this offers the user a menu of all materials in the blend
 
57
    file any objects using the selected material will become selected, any
 
58
    objects without the material will be removed from selection.
 
59
 
 
60
    in edit mode:  the menu offers only the materials attached to the current
 
61
    object. It will select the polygons that use the material and deselect those
 
62
    that do not.
57
63
 
58
64
* clean material slots
59
 
    for all selected objects any empty material slots or material slots with materials that are not used by the mesh faces will be removed.
 
65
    for all selected objects any empty material slots or material slots with
 
66
    materials that are not used by the mesh polygons will be removed.
60
67
 
61
 
* Any un-used materials and slots will be removed 
 
68
* Any un-used materials and slots will be removed
62
69
"""
63
70
 
64
71
 
66
73
from bpy.props import*
67
74
 
68
75
 
69
 
def replace_material(m1 , m2, all_objects = False):
70
 
    #replace material named m1 with material named m2
71
 
    #m1 is the name of original material
72
 
    #m2 is the name of the material to replace it with
73
 
    #'all' will replace throughout the blend file
74
 
    try:
75
 
        matorg = bpy.data.materials[m1]
76
 
        matrep = bpy.data.materials[m2]
77
 
        
78
 
        
 
76
def replace_material(m1, m2, all_objects=False):
 
77
    # replace material named m1 with material named m2
 
78
    # m1 is the name of original material
 
79
    # m2 is the name of the material to replace it with
 
80
    # 'all' will replace throughout the blend file
 
81
 
 
82
    matorg = bpy.data.materials.get(m1)
 
83
    matrep = bpy.data.materials.get(m2)
 
84
 
 
85
    if matorg and matrep:
79
86
        #store active object
80
87
        scn = bpy.context.scene
81
88
        ob_active = bpy.context.active_object
82
 
        
 
89
 
83
90
        if all_objects:
84
91
            objs = bpy.data.objects
85
 
        
 
92
 
86
93
        else:
87
94
            objs = bpy.context.selected_editable_objects
88
 
        
 
95
 
89
96
        for ob in objs:
90
97
            if ob.type == 'MESH':
91
98
                scn.objects.active = ob
92
 
                print(ob.name)   
93
 
                ms = ob.material_slots.values()
94
 
            
95
 
                for m in ms:
 
99
 
 
100
                for m in ob.material_slots.values():
96
101
                    if m.material == matorg:
97
102
                        m.material = matrep
98
 
                        #don't break the loop as the material can be 
 
103
                        # don't break the loop as the material can be
99
104
                        # ref'd more than once
100
 
        
101
 
        #restore active object
102
 
        scn.objects.active = ob_active
103
 
    except:
 
105
 
 
106
    else:
104
107
        print('no match to replace')
105
108
 
106
 
def select_material_by_name(find_mat):
107
 
    #in object mode selects all objects with material find_mat
108
 
    #in edit mode selects all faces with material find_mat
109
 
    
 
109
 
 
110
def select_material_by_name(find_mat_name):
 
111
    #in object mode selects all objects with material find_mat_name
 
112
    #in edit mode selects all polygons with material find_mat_name
 
113
 
 
114
    find_mat = bpy.data.materials.get(find_mat_name)
 
115
 
 
116
    if find_mat is None:
 
117
        return
 
118
 
110
119
    #check for editmode
111
120
    editmode = False
112
121
 
113
122
    scn = bpy.context.scene
 
123
 
 
124
    #set selection mode to polygons
 
125
    scn.tool_settings.mesh_select_mode = False, False, True
 
126
 
114
127
    actob = bpy.context.active_object
115
128
    if actob.mode == 'EDIT':
116
 
        editmode =True
 
129
        editmode = True
117
130
        bpy.ops.object.mode_set()
118
 
    
119
 
    
 
131
 
120
132
    if not editmode:
121
 
        objs = bpy.data.objects 
 
133
        objs = bpy.data.objects
122
134
        for ob in objs:
123
 
            if ob.type == 'MESH':
 
135
            if ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
124
136
                ms = ob.material_slots.values()
125
137
                for m in ms:
126
 
                    if m.material.name == find_mat:
 
138
                    if m.material == find_mat:
127
139
                        ob.select = True
128
 
                        #the active object may not have the mat!
129
 
                        #set it to one that does!
 
140
                        # the active object may not have the mat!
 
141
                        # set it to one that does!
130
142
                        scn.objects.active = ob
131
143
                        break
132
144
                    else:
133
145
                        ob.select = False
134
 
                            
135
 
            #deselect non-meshes                
 
146
 
 
147
            #deselect non-meshes
136
148
            else:
137
149
                ob.select = False
138
 
    
 
150
 
139
151
    else:
140
 
        #it's editmode, so select the faces
 
152
        #it's editmode, so select the polygons
141
153
        ob = actob
142
154
        ms = ob.material_slots.values()
143
 
    
 
155
 
144
156
        #same material can be on multiple slots
145
 
        slot_indeces =[]
 
157
        slot_indeces = []
146
158
        i = 0
147
 
        found = False
 
159
        # found = False  # UNUSED
148
160
        for m in ms:
149
 
            if m.material.name == find_mat:
 
161
            if m.material == find_mat:
150
162
                slot_indeces.append(i)
151
 
                found = True
 
163
                # found = True  # UNUSED
152
164
            i += 1
153
165
        me = ob.data
154
 
        for f in me.faces:
 
166
        for f in me.polygons:
155
167
            if f.material_index in slot_indeces:
156
168
                f.select = True
157
169
            else:
158
170
                f.select = False
159
 
        me.update   
 
171
        me.update()
160
172
    if editmode:
161
 
        bpy.ops.object.mode_set(mode = 'EDIT')
 
173
        bpy.ops.object.mode_set(mode='EDIT')
 
174
 
162
175
 
163
176
def mat_to_texface():
164
 
    #assigns the first image in each material to the faces in the active uvlayer
165
 
    #for all selected objects
166
 
    
 
177
    # assigns the first image in each material to the polygons in the active
 
178
    # uvlayer for all selected objects
 
179
 
167
180
    #check for editmode
168
181
    editmode = False
169
 
    
 
182
 
170
183
    actob = bpy.context.active_object
171
184
    if actob.mode == 'EDIT':
172
 
        editmode =True
 
185
        editmode = True
173
186
        bpy.ops.object.mode_set()
174
 
    
 
187
 
175
188
    for ob in bpy.context.selected_editable_objects:
176
 
        #get the materials from slots
177
 
        ms = ob.material_slots.values()
178
 
        
179
 
        #build a list of images, one per material
180
 
        images=[]
181
 
        #get the textures from the mats
182
 
        for m in ms:
183
 
            gotimage = False
184
 
            textures = m.material.texture_slots.values()
185
 
            if len(textures) >= 1:
186
 
                for t in textures:
187
 
                    if t != None:
188
 
                        tex = t.texture
189
 
                        if tex.type == 'IMAGE':
190
 
                            img = tex.image
191
 
                            images.append(img)
192
 
                            gotimage =True
193
 
                            break
194
 
    
195
 
            if not gotimage:
196
 
                print('noimage on', m.name)
197
 
                images.append(None)
198
 
    
199
 
        #now we have the images
200
 
        #applythem to the uvlayer
201
 
    
202
 
        
203
 
        me = ob.data
204
 
        #got uvs?
205
 
        if not me.uv_textures:
206
 
            scn = bpy.context.scene
207
 
            scn.objects.active = ob
208
 
            bpy.ops.mesh.uv_texture_add()
209
 
            scn.objects.active = actob
210
 
        
211
 
        #get active uvlayer
212
 
        for t in  me.uv_textures:
213
 
            if t.active:
214
 
                uvtex = t.data.values()
215
 
                for f in me.faces:
216
 
                    #check that material had an image!
217
 
                    if images[f.material_index] != None:
218
 
                        uvtex[f.index].image = images[f.material_index]
219
 
                        uvtex[f.index].use_image = True
220
 
                    else:
221
 
                        uvtex[f.index].use_image = False
222
 
 
223
 
        me.update()
224
 
        
225
 
    
 
189
        if ob.type == 'MESH':
 
190
            #get the materials from slots
 
191
            ms = ob.material_slots.values()
 
192
 
 
193
            #build a list of images, one per material
 
194
            images = []
 
195
            #get the textures from the mats
 
196
            for m in ms:
 
197
                gotimage = False
 
198
                textures = m.material.texture_slots.values()
 
199
                if len(textures) >= 1:
 
200
                    for t in textures:
 
201
                        if t != None:
 
202
                            tex = t.texture
 
203
                            if tex.type == 'IMAGE':
 
204
                                img = tex.image
 
205
                                images.append(img)
 
206
                                gotimage = True
 
207
                                break
 
208
 
 
209
                if not gotimage:
 
210
                    print('noimage on', m.name)
 
211
                    images.append(None)
 
212
 
 
213
            # now we have the images
 
214
            # applythem to the uvlayer
 
215
 
 
216
            me = ob.data
 
217
            #got uvs?
 
218
            if not me.uv_textures:
 
219
                scn = bpy.context.scene
 
220
                scn.objects.active = ob
 
221
                bpy.ops.mesh.uv_texture_add()
 
222
                scn.objects.active = actob
 
223
 
 
224
            #get active uvlayer
 
225
            for t in  me.uv_textures:
 
226
                if t.active:
 
227
                    uvtex = t.data.values()
 
228
                    for f in me.polygons:
 
229
                        #check that material had an image!
 
230
                        if images[f.material_index] != None:
 
231
                            uvtex[f.index].image = images[f.material_index]
 
232
                        else:
 
233
                            uvtex[f.index].image = None
 
234
 
 
235
            me.update()
 
236
 
226
237
    if editmode:
227
 
        bpy.ops.object.mode_set(mode = 'EDIT')
228
 
                    
229
 
        
 
238
        bpy.ops.object.mode_set(mode='EDIT')
 
239
 
230
240
 
231
241
def assignmatslots(ob, matlist):
232
242
    #given an object and a list of material names
241
251
    for s in ob.material_slots:
242
252
        bpy.ops.object.material_slot_remove()
243
253
 
244
 
 
245
 
    #re-add them and assign material
 
254
    # re-add them and assign material
246
255
    i = 0
247
256
    for m in matlist:
248
257
        mat = bpy.data.materials[m]
249
 
        bpy.ops.object.material_slot_add()
250
 
        ob.material_slots.values()[i].material = mat
 
258
        ob.data.materials.append(mat)
251
259
        i += 1
252
260
 
253
 
    #restore active object:
 
261
    # restore active object:
254
262
    scn.objects.active = ob_active
255
263
 
256
264
 
259
267
    editmode = False
260
268
    actob = bpy.context.active_object
261
269
    if actob.mode == 'EDIT':
262
 
        editmode =True
 
270
        editmode = True
263
271
        bpy.ops.object.mode_set()
264
272
 
265
 
 
266
273
    objs = bpy.context.selected_editable_objects
267
 
    
 
274
 
268
275
    for ob in objs:
269
 
        print(ob.name)    
270
 
        mats = ob.material_slots.keys()
271
 
    
272
 
        #check the faces on the mesh to build a list of used materials
273
 
        usedMatIndex =[]        #we'll store used materials indices here
274
 
        faceMats =[]    
275
 
        me = ob.data
276
 
        for f in me.faces:
277
 
            #get the material index for this face...
278
 
            faceindex = f.material_index
279
 
                    
280
 
            #indices will be lost: Store face mat use by name
281
 
            currentfacemat = mats[faceindex]
282
 
            faceMats.append(currentfacemat)
283
 
                    
284
 
                    
285
 
            #check if index is already listed as used or not
286
 
            found = 0
287
 
            for m in usedMatIndex:
288
 
                if m == faceindex:
289
 
                    found = 1
290
 
                    #break
291
 
                        
292
 
            if found == 0:
293
 
            #add this index to the list     
294
 
                usedMatIndex.append(faceindex)
295
 
    
296
 
        #re-assign the used mats to the mesh and leave out the unused
297
 
        ml = []
298
 
        mnames = []
299
 
        for u in usedMatIndex:
300
 
            ml.append( mats[u] )
301
 
            #we'll need a list of names to get the face indices...
302
 
            mnames.append(mats[u])
303
 
                    
304
 
        assignmatslots(ob, ml)
305
 
        
306
 
                
307
 
        #restore face indices:
308
 
        i = 0
309
 
        for f in me.faces:
310
 
            matindex = mnames.index(faceMats[i])
311
 
            f.material_index = matindex
312
 
            i += 1
313
 
        print('Done')
 
276
        if ob.type == 'MESH':
 
277
            mats = ob.material_slots.keys()
 
278
 
 
279
            #check the polygons on the mesh to build a list of used materials
 
280
            usedMatIndex = []  # we'll store used materials indices here
 
281
            faceMats = []
 
282
            me = ob.data
 
283
            for f in me.polygons:
 
284
                #get the material index for this face...
 
285
                faceindex = f.material_index
 
286
 
 
287
                #indices will be lost: Store face mat use by name
 
288
                currentfacemat = mats[faceindex]
 
289
                faceMats.append(currentfacemat)
 
290
 
 
291
                # check if index is already listed as used or not
 
292
                found = 0
 
293
                for m in usedMatIndex:
 
294
                    if m == faceindex:
 
295
                        found = 1
 
296
                        #break
 
297
 
 
298
                if found == 0:
 
299
                #add this index to the list
 
300
                    usedMatIndex.append(faceindex)
 
301
 
 
302
            #re-assign the used mats to the mesh and leave out the unused
 
303
            ml = []
 
304
            mnames = []
 
305
            for u in usedMatIndex:
 
306
                ml.append(mats[u])
 
307
                #we'll need a list of names to get the face indices...
 
308
                mnames.append(mats[u])
 
309
 
 
310
            assignmatslots(ob, ml)
 
311
 
 
312
            # restore face indices:
 
313
            i = 0
 
314
            for f in me.polygons:
 
315
                matindex = mnames.index(faceMats[i])
 
316
                f.material_index = matindex
 
317
                i += 1
 
318
 
314
319
    if editmode:
315
 
        bpy.ops.object.mode_set(mode = 'EDIT')
316
 
 
317
 
 
318
 
 
319
 
 
320
 
 
321
 
def assign_mat(matname="Default"): 
322
 
    #get active object so we can restore it later
 
320
        bpy.ops.object.mode_set(mode='EDIT')
 
321
 
 
322
 
 
323
def assign_mat(matname="Default"):
 
324
    # get active object so we can restore it later
323
325
    actob = bpy.context.active_object
324
 
    
325
 
    #check if material exists, if it doesn't then create it
326
 
    mats =bpy.data.materials
 
326
 
 
327
    # check if material exists, if it doesn't then create it
327
328
    found = False
328
 
    for m in mats:
 
329
    for m in bpy.data.materials:
329
330
        if m.name == matname:
330
331
            target = m
331
332
            found = True
332
333
            break
333
334
    if not found:
334
335
        target = bpy.data.materials.new(matname)
335
 
    
336
 
    
337
 
    #if objectmodeset all faces
 
336
 
 
337
    # if objectmode then set all polygons
338
338
    editmode = False
339
 
    allfaces = True
 
339
    allpolygons = True
340
340
    if actob.mode == 'EDIT':
341
 
        editmode =True
342
 
        allfaces = False    
 
341
        editmode = True
 
342
        allpolygons = False
343
343
        bpy.ops.object.mode_set()
344
 
    
 
344
 
345
345
    objs = bpy.context.selected_editable_objects
346
 
    
347
 
    for ob in objs:    
348
 
        #set the active object to our object
 
346
 
 
347
    for ob in objs:
 
348
        # set the active object to our object
349
349
        scn = bpy.context.scene
350
350
        scn.objects.active = ob
351
 
        
352
 
    
353
 
        #check if the material is on the object already
354
 
        if ob.type =='MESH':
355
 
            #check material slots for matname material
356
 
            found=False
 
351
 
 
352
        if ob.type in {'CURVE', 'SURFACE', 'FONT', 'META'}:
 
353
            found = False
 
354
            i = 0
 
355
            for m in bpy.data.materials:
 
356
                if m.name == matname:
 
357
                    found = True
 
358
                    index = i
 
359
                    break
 
360
                i += 1
 
361
                if not found:
 
362
                    index = i - 1
 
363
            targetlist = [index]
 
364
            assignmatslots(ob, targetlist)
 
365
 
 
366
        elif ob.type == 'MESH':
 
367
            # check material slots for matname material
 
368
            found = False
357
369
            i = 0
358
370
            mats = ob.material_slots
359
371
            for m in mats:
360
372
                if m.name == matname:
361
 
                    found =True
 
373
                    found = True
362
374
                    index = i
363
375
                    #make slot active
364
376
                    ob.active_material_index = i
365
377
                    break
366
378
                i += 1
367
 
            
 
379
 
368
380
            if not found:
369
 
                index=i
370
 
                #the material is not attached to the object 
371
 
                #so attach it!
372
 
    
373
 
                #add a material slot
374
 
                bpy.ops.object.material_slot_add()
375
 
    
376
 
                #make  slot active
377
 
                ob.active_material_index = i
378
 
    
379
 
                #and assign material to slot
380
 
                ob.material_slots.values()[i].material = target
 
381
                index = i
 
382
                #the material is not attached to the object
 
383
                ob.data.materials.append(target)
 
384
 
381
385
            #now assign the material:
382
 
            me =ob.data
383
 
            if allfaces:
384
 
                for f in me.faces:
 
386
            me = ob.data
 
387
            if allpolygons:
 
388
                for f in me.polygons:
385
389
                    f.material_index = index
386
 
            elif allfaces == False:
387
 
                for f in me.faces:
 
390
            elif allpolygons == False:
 
391
                for f in me.polygons:
388
392
                    if f.select:
389
393
                        f.material_index = index
390
 
            me.update
 
394
            me.update()
391
395
 
392
396
    #restore the active object
393
397
    bpy.context.scene.objects.active = actob
394
398
    if editmode:
395
 
        bpy.ops.object.mode_set(mode = 'EDIT')
396
 
 
397
 
 
398
 
 
399
 
def check_texture(img,mat):
 
399
        bpy.ops.object.mode_set(mode='EDIT')
 
400
 
 
401
 
 
402
def check_texture(img, mat):
400
403
    #finds a texture from an image
401
404
    #makes a texture if needed
402
405
    #adds it to the material if it isn't there already
421
424
        mtex.texture_coords = 'UV'
422
425
        mtex.use_map_color_diffuse = True
423
426
 
 
427
 
424
428
def texface_to_mat():
425
429
    # editmode check here!
426
430
    editmode = False
427
431
    ob = bpy.context.object
428
 
    if ob.mode =='EDIT':
 
432
    if ob.mode == 'EDIT':
429
433
        editmode = True
430
434
        bpy.ops.object.mode_set()
431
435
 
433
437
 
434
438
        faceindex = []
435
439
        unique_images = []
436
 
        
 
440
 
437
441
        # get the texface images and store indices
438
442
        if (ob.data.uv_textures):
439
443
            for f in ob.data.uv_textures.active.data:
440
 
                if f.image: 
 
444
                if f.image:
441
445
                    img = f.image
442
446
                    #build list of unique images
443
447
                    if img not in unique_images:
446
450
 
447
451
                else:
448
452
                    img = None
449
 
                    faceindex.append(None)   
450
 
      
451
 
        
 
453
                    faceindex.append(None)
452
454
 
453
 
        #check materials for images exist; create if needed
 
455
        # check materials for images exist; create if needed
454
456
        matlist = []
455
457
        for i in unique_images:
456
458
            if i:
457
 
                print(i.name)
458
459
                try:
459
460
                    m = bpy.data.materials[i.name]
460
 
    
461
461
                except:
462
 
                    m = bpy.data.materials.new(name = i.name)
 
462
                    m = bpy.data.materials.new(name=i.name)
463
463
                    continue
464
464
 
465
465
                finally:
466
466
                    matlist.append(m.name)
467
467
                    # add textures if needed
468
 
                    check_texture(i,m)
 
468
                    check_texture(i, m)
469
469
 
470
 
        #set up the object material slots
 
470
        # set up the object material slots
471
471
        assignmatslots(ob, matlist)
472
 
        
 
472
 
473
473
        #set texface indices to material slot indices..
474
474
        me = ob.data
475
475
 
476
476
        i = 0
477
477
        for f in faceindex:
478
478
            if f != None:
479
 
                me.faces[i].material_index = f
 
479
                me.polygons[i].material_index = f
480
480
            i += 1
481
481
    if editmode:
482
 
        bpy.ops.object.mode_set(mode = 'EDIT')
483
 
 
484
 
 
485
 
#operator classes:
486
 
#---------------------------------------------------------------------
 
482
        bpy.ops.object.mode_set(mode='EDIT')
 
483
 
 
484
 
 
485
# -----------------------------------------------------------------------------
 
486
# operator classes:
487
487
 
488
488
class VIEW3D_OT_texface_to_material(bpy.types.Operator):
489
 
    ''''''
490
 
    bl_idname = "texface_to_material"
 
489
    '''Create texture materials for images assigned in UV editor'''
 
490
    bl_idname = "view3d.texface_to_material"
491
491
    bl_label = "MW Texface Images to Material/Texture"
492
492
    bl_options = {'REGISTER', 'UNDO'}
493
493
 
500
500
            texface_to_mat()
501
501
            return {'FINISHED'}
502
502
        else:
503
 
            self.report({'WARNING'}, "No editable selected objects, could not finish")
 
503
            self.report({'WARNING'},
 
504
                        "No editable selected objects, could not finish")
504
505
            return {'CANCELLED'}
505
506
 
 
507
 
506
508
class VIEW3D_OT_assign_material(bpy.types.Operator):
507
 
    '''assign a material to the selection'''
508
 
    bl_idname = "assign_material"
 
509
    '''Assign a material to the selection'''
 
510
    bl_idname = "view3d.assign_material"
509
511
    bl_label = "MW Assign Material"
510
512
    bl_options = {'REGISTER', 'UNDO'}
511
513
 
512
 
    matname = StringProperty(name = 'Material Name', 
513
 
        description = 'Name of Material to Assign', 
514
 
        default = "", maxlen = 21)
515
 
    
 
514
    matname = StringProperty(
 
515
            name='Material Name',
 
516
            description='Name of Material to Assign',
 
517
            default="",
 
518
            maxlen=63,
 
519
            )
 
520
 
516
521
    @classmethod
517
522
    def poll(cls, context):
518
523
        return context.active_object != None
525
530
        mat_to_texface()
526
531
        return {'FINISHED'}
527
532
 
 
533
 
528
534
class VIEW3D_OT_clean_material_slots(bpy.types.Operator):
529
 
    '''removes any material slots from the 
530
 
    selected objects that are not used by the mesh'''
531
 
    bl_idname = "clean_material_slots"
 
535
    '''Removes any material slots from selected objects '''\
 
536
    '''that are not used by the mesh'''
 
537
    bl_idname = "view3d.clean_material_slots"
532
538
    bl_label = "MW Clean Material Slots"
533
539
    bl_options = {'REGISTER', 'UNDO'}
534
540
 
540
546
        cleanmatslots()
541
547
        return {'FINISHED'}
542
548
 
 
549
 
543
550
class VIEW3D_OT_material_to_texface(bpy.types.Operator):
544
 
    ''''''
545
 
    bl_idname = "material_to_texface"
 
551
    '''Transfer material assignments to UV editor'''
 
552
    bl_idname = "view3d.material_to_texface"
546
553
    bl_label = "MW Material Images to Texface"
547
554
    bl_options = {'REGISTER', 'UNDO'}
548
555
 
554
561
        mat_to_texface()
555
562
        return {'FINISHED'}
556
563
 
 
564
 
557
565
class VIEW3D_OT_select_material_by_name(bpy.types.Operator):
558
 
    ''''''
559
 
    bl_idname = "select_material_by_name"
 
566
    '''Select geometry with this material assigned to it'''
 
567
    bl_idname = "view3d.select_material_by_name"
560
568
    bl_label = "MW Select Material By Name"
561
569
    bl_options = {'REGISTER', 'UNDO'}
562
 
    matname = StringProperty(name = 'Material Name', 
563
 
        description = 'Name of Material to Select', 
564
 
        default = "", maxlen = 21)
 
570
    matname = StringProperty(
 
571
            name='Material Name',
 
572
            description='Name of Material to Select',
 
573
            maxlen=63,
 
574
            )
565
575
 
566
576
    @classmethod
567
577
    def poll(cls, context):
574
584
 
575
585
 
576
586
class VIEW3D_OT_replace_material(bpy.types.Operator):
577
 
    '''assign a material to the selection'''
578
 
    bl_idname = "replace_material"
 
587
    '''Replace a material by name'''
 
588
    bl_idname = "view3d.replace_material"
579
589
    bl_label = "MW Replace Material"
580
590
    bl_options = {'REGISTER', 'UNDO'}
581
591
 
582
 
    matorg = StringProperty(name = 'Material to Replace', 
583
 
        description = 'Name of Material to Assign', 
584
 
        default = "", maxlen = 21)
585
 
 
586
 
    matrep = StringProperty(name = 'Replacement material', 
587
 
        description = 'Name of Material to Assign', 
588
 
        default = "", maxlen = 21)
589
 
 
590
 
    all_objects = BoolProperty(name ='all_objects',
591
 
        description="replace for all objects in this blend file",
592
 
        default = True)
593
 
    
 
592
    matorg = StringProperty(
 
593
            name='Material to Replace',
 
594
            description="Name of Material to Assign",
 
595
            maxlen=63,
 
596
            )
 
597
    matrep = StringProperty(name="Replacement material",
 
598
            description='Name of Material to Assign',
 
599
            maxlen=63,
 
600
            )
 
601
    all_objects = BoolProperty(
 
602
            name="All objects",
 
603
            description="Replace for all objects in this blend file",
 
604
            default=True,
 
605
            )
 
606
 
594
607
    @classmethod
595
608
    def poll(cls, context):
596
609
        return context.active_object != None
599
612
        m1 = self.matorg
600
613
        m2 = self.matrep
601
614
        all = self.all_objects
602
 
        replace_material(m1,m2,all)
 
615
        replace_material(m1, m2, all)
603
616
        return {'FINISHED'}
604
617
 
605
 
#menu classes
606
 
#-------------------------------------------------------------------------------
 
618
 
 
619
# -----------------------------------------------------------------------------
 
620
# menu classes
 
621
 
607
622
class VIEW3D_MT_master_material(bpy.types.Menu):
608
 
    bl_label = "Master Material Menu"
 
623
    bl_label = "Material Utils Menu"
609
624
 
610
625
    def draw(self, context):
611
626
        layout = self.layout
614
629
        layout.menu("VIEW3D_MT_assign_material", icon='ZOOMIN')
615
630
        layout.menu("VIEW3D_MT_select_material", icon='HAND')
616
631
        layout.separator()
617
 
        layout.operator("clean_material_slots", 
618
 
            text = 'Clean Material Slots', icon='CANCEL')
619
 
        layout.operator("material_to_texface",
620
 
            text = 'Material to Texface',icon='FACESEL_HLT')
621
 
        layout.operator("texface_to_material",
622
 
            text = 'Texface to Material',icon='FACESEL_HLT')
 
632
        layout.operator("view3d.clean_material_slots",
 
633
                        text='Clean Material Slots',
 
634
                        icon='CANCEL')
 
635
        layout.operator("view3d.material_to_texface",
 
636
                        text='Material to Texface',
 
637
                        icon='polygonsEL_HLT')
 
638
        layout.operator("view3d.texface_to_material",
 
639
                        text="Texface to Material",
 
640
                        icon='polygonsEL_HLT')
623
641
 
624
642
        layout.separator()
625
 
        layout.operator("replace_material", 
626
 
            text = 'Replace Material', icon='ARROW_LEFTRIGHT')
627
 
       
 
643
        layout.operator("view3d.replace_material",
 
644
                        text='Replace Material',
 
645
                        icon='ARROW_LEFTRIGHT')
628
646
 
629
647
 
630
648
class VIEW3D_MT_assign_material(bpy.types.Menu):
633
651
    def draw(self, context):
634
652
        layout = self.layout
635
653
        layout.operator_context = 'INVOKE_REGION_WIN'
636
 
 
637
 
        ob = context
638
 
        layout.label
639
 
        for i in range (len(bpy.data.materials)):
640
 
    
641
 
            layout.operator("assign_material",
642
 
                text=bpy.data.materials[i].name, 
643
 
                icon='MATERIAL_DATA').matname = bpy.data.materials[i].name
644
 
 
645
 
        layout.operator("assign_material",text="Add New", 
646
 
                icon='ZOOMIN')
 
654
        for material_name in bpy.data.materials.keys():
 
655
            layout.operator("view3d.assign_material",
 
656
                text=material_name,
 
657
                icon='MATERIAL_DATA').matname = material_name
 
658
 
 
659
        layout.operator("view3d.assign_material",
 
660
                        text="Add New",
 
661
                        icon='ZOOMIN')
 
662
 
647
663
 
648
664
class VIEW3D_MT_select_material(bpy.types.Menu):
649
665
    bl_label = "Select by Material"
655
671
        ob = context.object
656
672
        layout.label
657
673
        if ob.mode == 'OBJECT':
658
 
            #show all materials in entire blend file
659
 
            for i in range (len(bpy.data.materials)):
660
 
        
661
 
                layout.operator("select_material_by_name",
662
 
                    text=bpy.data.materials[i].name, 
663
 
                    icon='MATERIAL_DATA').matname = bpy.data.materials[i].name
664
 
 
 
674
            #show all used materials in entire blend file
 
675
            for material_name, material in bpy.data.materials.items():
 
676
                if material.users > 0:
 
677
                    layout.operator("view3d.select_material_by_name",
 
678
                                    text=material_name,
 
679
                                    icon='MATERIAL_DATA',
 
680
                                    ).matname = material_name
665
681
 
666
682
        elif ob.mode == 'EDIT':
667
683
            #show only the materials on this object
668
684
            mats = ob.material_slots.keys()
669
685
            for m in mats:
670
 
                layout.operator("select_material_by_name",
671
 
                    text=m, 
 
686
                layout.operator("view3d.select_material_by_name",
 
687
                    text=m,
672
688
                    icon='MATERIAL_DATA').matname = m
673
689
 
674
690
 
675
691
def register():
676
 
    km = bpy.context.window_manager.keyconfigs.default.keymaps['3D View']
677
 
    kmi = km.items.new('wm.call_menu', 'Q', 'PRESS')
678
 
    kmi.properties.name = "VIEW3D_MT_master_material"
 
692
    bpy.utils.register_module(__name__)
 
693
 
 
694
    kc = bpy.context.window_manager.keyconfigs.addon
 
695
    if kc:
 
696
        km = kc.keymaps.new(name="3D View", space_type="VIEW_3D")
 
697
        kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS')
 
698
        kmi.properties.name = "VIEW3D_MT_master_material"
 
699
 
679
700
 
680
701
def unregister():
681
 
    km = bpy.context.window_manager.keyconfigs.default.keymaps['3D View']
682
 
    for kmi in km.items:
683
 
        if kmi.idname == 'wm.call_menu':
684
 
            if kmi.properties.name ==  "VIEW3D_MT_master_material":
685
 
                km.items.remove(kmi)
686
 
                break
 
702
    bpy.utils.unregister_module(__name__)
 
703
 
 
704
    kc = bpy.context.window_manager.keyconfigs.addon
 
705
    if kc:
 
706
        km = kc.keymaps["3D View"]
 
707
        for kmi in km.keymap_items:
 
708
            if kmi.idname == 'wm.call_menu':
 
709
                if kmi.properties.name == "VIEW3D_MT_master_material":
 
710
                    km.keymap_items.remove(kmi)
 
711
                    break
687
712
 
688
713
if __name__ == "__main__":
689
714
    register()