object_find, didnt get images from an objects material textures
[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         
65         # Now get material images
66         for mat in me.materials:
67                 if mat:
68                         for mtex in mat.getTextures():
69                                 if mtex:
70                                         tex = mtex.tex
71                                         i = tex.getImage()
72                                         if i: unique_images[i.name] = i
73         
74         return unique_images.values()
75         
76         
77         
78         # Todo, support other object types, materials
79         return []
80         
81         
82
83 def main():
84         
85         NAME_DATA= Draw.Create('')
86         NAME_INGROUP= Draw.Create('')
87         NAME_DUPGROUP= Draw.Create('')
88         NAME_IMAGE= Draw.Create('')
89         NAME_MATERIAL= Draw.Create('')
90         NAME_TEXTURE= Draw.Create('')
91         
92         
93         PREF_CASESENS= Draw.Create(False)
94         PREF_PART_MATCH= Draw.Create(True)
95         
96         
97         # Get USER Options
98         pup_block= [\
99         ('ObData:', NAME_DATA, 0, 32, 'Match with the objects data name'),\
100         ('InGroup:', NAME_INGROUP, 0, 32, 'Match with the group name to find one of its objects'),\
101         ('DupGroup:', NAME_DUPGROUP, 0, 32, 'Match with the group name to find an object that instances this group'),\
102         ('Image:', NAME_IMAGE, 0, 32, 'Match with the image name to find an object that uses this image'),\
103         ('Material:', NAME_MATERIAL, 0, 32, 'Match with the material name to find an object that uses this material'),\
104         ('Texture:', NAME_TEXTURE, 0, 32, 'Match with the texture name to find an object that uses this texture'),\
105         ('Case Sensitive', PREF_CASESENS, 'Do a case sensitive comparison?'),\
106         ('Partial Match', PREF_PART_MATCH, 'Match when only a part of the text is in the data name'),\
107         ]
108         
109         if not Draw.PupBlock('Find object using dataname...', pup_block):
110                 return
111         
112         NAME_DATA = NAME_DATA.val
113         NAME_INGROUP = NAME_INGROUP.val
114         NAME_DUPGROUP = NAME_DUPGROUP.val
115         NAME_IMAGE = NAME_IMAGE.val
116         NAME_MATERIAL = NAME_MATERIAL.val
117         NAME_TEXTURE = NAME_TEXTURE.val
118         
119         PREF_CASESENS = PREF_CASESENS.val
120         PREF_PART_MATCH = PREF_PART_MATCH.val
121         
122         if not PREF_CASESENS:
123                 NAME_DATA = NAME_DATA.lower()
124                 NAME_INGROUP = NAME_INGROUP.lower()
125                 NAME_DUPGROUP = NAME_DUPGROUP.lower()
126                 NAME_IMAGE = NAME_IMAGE.lower()
127                 NAME_MATERIAL = NAME_MATERIAL.lower()
128                 NAME_TEXTURE = NAME_TEXTURE.lower()
129         
130         def activate(ob, scn):
131                 bpy.data.scenes.active = scn
132                 scn.objects.selected = []
133                 scn.Layers = ob.Layers & (1<<20)-1
134                 ob.sel = 1
135         
136         def name_cmp(name_search, name_found):
137                 if name_found == None: return False
138                 if not PREF_CASESENS: name_found = name_found.lower()
139                 if PREF_PART_MATCH:
140                         if name_search in name_found:
141                                 # print name_found, name_search
142                                 return True
143                 else:
144                         if name_found == name_search:
145                                 # print name_found, name_search
146                                 return True
147                 
148                 return False
149         
150         
151         if NAME_INGROUP:
152                 # Best we speed this up.
153                 bpy.data.objects.tag = False
154                 
155                 ok = False
156                 for group in bpy.data.groups:
157                         if name_cmp(NAME_INGROUP, group.name):
158                                 for ob in group.objects:
159                                         ob.tag = True
160                                         ok = True
161                 if not ok:
162                         Draw.PupMenu('No Objects Found')
163                         return
164         
165         for scn in bpy.data.scenes:
166                 for ob in scn.objects:
167                         if NAME_DATA:
168                                 if name_cmp(NAME_DATA, ob.getData(1)):
169                                         activate(ob, scn)
170                                         return
171                         if NAME_INGROUP:
172                                 # Crap and slow but not much we can do about that
173                                 '''
174                                 for group in bpy.data.groups:
175                                         if name_cmp(NAME_INGROUP, group.name):
176                                                 for ob_group in group.objects:
177                                                         if ob == ob_group:
178                                                                 activate(ob, scn)
179                                                                 return
180                                 '''
181                                 # Use speedup, this is in a group whos name matches.
182                                 if ob.tag:
183                                         activate(ob, scn)
184                                         return
185                         
186                         if NAME_DUPGROUP:
187                                 if ob.DupGroup and name_cmp(NAME_DUPGROUP, ob.DupGroup.name):
188                                         activate(ob, scn)
189                                         return
190                         
191                         if NAME_IMAGE:
192                                 for img in get_object_images(ob):
193                                         if name_cmp(NAME_IMAGE, img.name) or name_cmp(NAME_IMAGE, img.filename.split('\\')[-1].split('/')[-1]):
194                                                 activate(ob, scn)
195                                                 return
196                         if NAME_MATERIAL or NAME_TEXTURE:
197                                 try:    materials = ob.getData(mesh=1).materials
198                                 except: materials = []
199                                 
200                                 # Add object materials
201                                 materials.extend(ob.getMaterials())
202                                 
203                                 for mat in materials:
204                                         if mat:
205                                                 if NAME_MATERIAL:
206                                                         if name_cmp(NAME_MATERIAL, mat.name):
207                                                                 activate(ob, scn)
208                                                                 return
209                                                 if NAME_TEXTURE:
210                                                         for mtex in mat.getTextures():
211                                                                 if mtex:
212                                                                         tex = mtex.tex
213                                                                         if tex:
214                                                                                 if name_cmp(NAME_TEXTURE, tex.name):
215                                                                                         activate(ob, scn)
216                                                                                         return
217         
218         
219         Draw.PupMenu('No Objects Found')
220
221 if __name__ == '__main__':
222         main()