find objects by texture name raised a python error
[blender.git] / release / scripts / object_find.py
1 #!BPY
2 """
3 Name: 'Find by Data Use'
4 Blender: 242
5 Group: 'Object'
6 Tooltip: 'Find an object by the data it uses'
7 """
8 __author__= "Campbell Barton"
9 __url__= ["blender.org", "blenderartists.org"]
10 __version__= "1.0"
11
12 __bpydoc__= """
13 """
14
15 # --------------------------------------------------------------------------
16 # Find by Data Use v0.1 by Campbell Barton (AKA Ideasman42)
17 # --------------------------------------------------------------------------
18 # ***** BEGIN GPL LICENSE BLOCK *****
19 #
20 # This program is free software; you can redistribute it and/or
21 # modify it under the terms of the GNU General Public License
22 # as published by the Free Software Foundation; either version 2
23 # of the License, or (at your option) any later version.
24 #
25 # This program is distributed in the hope that it will be useful,
26 # but WITHOUT ANY WARRANTY; without even the implied warranty of
27 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 # GNU General Public License for more details.
29 #
30 # You should have received a copy of the GNU General Public License
31 # along with this program; if not, write to the Free Software Foundation,
32 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
33 #
34 # ***** END GPL LICENCE BLOCK *****
35 # --------------------------------------------------------------------------
36
37 from Blender import Image, sys, Draw, Window, Scene, Group
38 import bpy
39 import BPyMessages
40
41
42 def get_object_images(ob):
43         # Could optimize this
44         if ob.type != 'Mesh':
45                 return []
46         
47         me = ob.getData(mesh=1)
48
49         if not me.faceUV:
50                 return []
51
52         unique_images = {}
53         
54         orig_uvlayer = me.activeUVLayer 
55         
56         for uvlayer in me.getUVLayerNames():
57                 me.activeUVLayer = uvlayer
58                 for f in me.faces:
59                         i = f.image
60                         if i: unique_images[i.name] = i
61         
62         me.activeUVLayer = orig_uvlayer
63         
64         return unique_images.values()
65         
66         # Todo, support other object types, materials
67         return []
68         
69         
70
71 def main():
72         
73         NAME_DATA= Draw.Create('')
74         NAME_INGROUP= Draw.Create('')
75         NAME_DUPGROUP= Draw.Create('')
76         NAME_IMAGE= Draw.Create('')
77         NAME_MATERIAL= Draw.Create('')
78         NAME_TEXTURE= Draw.Create('')
79         
80         
81         PREF_CASESENS= Draw.Create(False)
82         PREF_PART_MATCH= Draw.Create(True)
83         
84         
85         # Get USER Options
86         pup_block= [\
87         ('ObData:', NAME_DATA, 0, 32, 'Match with the objects data name'),\
88         ('InGroup:', NAME_INGROUP, 0, 32, 'Match with the group name to find one of its objects'),\
89         ('DupGroup:', NAME_DUPGROUP, 0, 32, 'Match with the group name to find an object that instances this group'),\
90         ('Image:', NAME_IMAGE, 0, 32, 'Match with the image name to find an object that uses this image'),\
91         ('Material:', NAME_MATERIAL, 0, 32, 'Match with the material name to find an object that uses this material'),\
92         ('Texture:', NAME_TEXTURE, 0, 32, 'Match with the texture name to find an object that uses this texture'),\
93         ('Case Sensitive', PREF_CASESENS, 'Do a case sensitive comparison?'),\
94         ('Partial Match', PREF_PART_MATCH, 'Match when only a part of the text is in the data name'),\
95         ]
96         
97         if not Draw.PupBlock('Find object using dataname...', pup_block):
98                 return
99         
100         NAME_DATA = NAME_DATA.val
101         NAME_INGROUP = NAME_INGROUP.val
102         NAME_DUPGROUP = NAME_DUPGROUP.val
103         NAME_IMAGE = NAME_IMAGE.val
104         NAME_MATERIAL = NAME_MATERIAL.val
105         NAME_TEXTURE = NAME_TEXTURE.val
106         
107         PREF_CASESENS = PREF_CASESENS.val
108         PREF_PART_MATCH = PREF_PART_MATCH.val
109         
110         if not PREF_CASESENS:
111                 NAME_DATA = NAME_DATA.lower()
112                 NAME_INGROUP = NAME_INGROUP.lower()
113                 NAME_DUPGROUP = NAME_DUPGROUP.lower()
114                 NAME_IMAGE = NAME_IMAGE.lower()
115                 NAME_MATERIAL = NAME_MATERIAL.lower()
116                 NAME_TEXTURE = NAME_TEXTURE.lower()
117         
118         def activate(ob, scn):
119                 bpy.data.scenes.active = scn
120                 scn.objects.selected = []
121                 scn.Layers = ob.Layers
122                 ob.sel = 1
123         
124         def name_cmp(name_search, name_found):
125                 if name_found == None: return False
126                 if not PREF_CASESENS: name_found = name_found.lower()
127                 if PREF_PART_MATCH:
128                         if name_search in name_found:
129                                 # print name_found, name_search
130                                 return True
131                 else:
132                         if name_found == name_search:
133                                 # print name_found, name_search
134                                 return True
135                 
136                 return False
137         
138         
139         if NAME_INGROUP:
140                 # Best we speed this up.
141                 bpy.data.objects.tag = False
142                 
143                 ok = False
144                 for group in bpy.data.groups:
145                         if name_cmp(NAME_INGROUP, group.name):
146                                 for ob in group.objects:
147                                         ob.tag = True
148                                         ok = True
149                 if not ok:
150                         Draw.PupMenu('No Objects Found')
151                         return
152         
153         for scn in bpy.data.scenes:
154                 for ob in scn.objects:
155                         if NAME_DATA:
156                                 if name_cmp(NAME_DATA, ob.getData(1)):
157                                         activate(ob, scn)
158                                         return
159                         if NAME_INGROUP:
160                                 # Crap and slow but not much we can do about that
161                                 '''
162                                 for group in bpy.data.groups:
163                                         if name_cmp(NAME_INGROUP, group.name):
164                                                 for ob_group in group.objects:
165                                                         if ob == ob_group:
166                                                                 activate(ob, scn)
167                                                                 return
168                                 '''
169                                 # Use speedup, this is in a group whos name matches.
170                                 if ob.tag:
171                                         activate(ob, scn)
172                                         return
173                         
174                         if NAME_DUPGROUP:
175                                 if ob.DupGroup and name_cmp(NAME_DUPGROUP, ob.DupGroup.name):
176                                         activate(ob, scn)
177                                         return
178                         
179                         if NAME_IMAGE:
180                                 for img in get_object_images(ob):
181                                         if name_cmp(NAME_IMAGE, img.name) or name_cmp(NAME_IMAGE, img.filename.split('\\')[-1].split('/')[-1]):
182                                                 activate(ob, scn)
183                                                 return
184                         if NAME_MATERIAL or NAME_TEXTURE:
185                                 try:    materials = ob.getData(mesh=1).materials
186                                 except: materials = []
187                                 
188                                 # Add object materials
189                                 materials.extend(ob.getMaterials())
190                                 
191                                 for mat in materials:
192                                         if mat:
193                                                 if NAME_MATERIAL:
194                                                         if name_cmp(NAME_MATERIAL, mat.name):
195                                                                 activate(ob, scn)
196                                                                 return
197                                                 if NAME_TEXTURE:
198                                                         for mtex in mat.getTextures():
199                                                                 if mtex:
200                                                                         tex = mtex.tex
201                                                                         if tex:
202                                                                                 if name_cmp(NAME_TEXTURE, tex.name):
203                                                                                         activate(ob, scn)
204                                                                                         return
205         
206         
207         Draw.PupMenu('No Objects Found')
208
209 if __name__ == '__main__':
210         main()