added many checks to uvcopy so it dosnt raise errors.
[blender.git] / release / scripts / obdatacopier.py
1 #!BPY
2
3 """ Registration info for Blender menus: <- these words are ignored
4 Name: 'Data Copier'
5 Blender: 232
6 Group: 'Object'
7 Tip: 'Copy data from active object to other selected ones.'
8 """
9
10 __author__ = "Jean-Michel Soler (jms), Campbell Barton (Ideasman42)"
11 __url__ = ("blender", "elysiun",
12 "Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_lampdatacopier.htm",
13 "Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
14 __version__ = "0.1.2"
15
16 __bpydoc__ = """\
17 Use "Data Copier" to copy attributes from the active object to other selected ones of
18 its same type.
19
20 This script is still in an early version but is already useful for copying
21 attributes for some types of objects like lamps and cameras.
22
23 Usage:
24
25 Select the objects that will be updated, select the object whose data will
26 be copied (they must all be of the same type, of course), then run this script.
27 Toggle the buttons representing the attributes to be copied and press "Copy".
28 """
29
30 # ----------------------------------------------------------
31 # Object DATA copier 0.1.2
32 # (c) 2004 jean-michel soler
33 # -----------------------------------------------------------
34 #----------------------------------------------
35 # Page officielle/official page du blender python Object DATA copier:
36 #   http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_lampdatacopier.htm
37 # Communiquer les problemes et erreurs sur:
38 # To Communicate problems and errors on:
39 #   http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
40 #---------------------------------------------
41 # Blender Artistic License
42 # http://download.blender.org/documentation/html/x21254.html
43 #---------------------------------------------
44
45 import Blender
46 from Blender import *
47 from Blender.Draw import *
48 from Blender.BGL import *
49
50
51 scn= Blender.Scene.GetCurrent()
52
53 type_func_method= type(dir)
54 type_func= type(lambda:i)
55 type_dict= type({})
56 # type_list= type([])
57
58 IGNORE_VARS = 'users', 'fakeUser', 'edges', 'faces', 'verts',  'elements'
59
60 def renew():
61         scn= Blender.Scene.GetCurrent()
62         act_ob= scn.objects.active
63         if act_ob==None:
64                 return {}
65
66         act_ob_type= act_ob.getType()
67         act_ob_data= act_ob.getData(mesh=1)
68
69         if act_ob_data==None: # Surf?
70                 return {}
71         
72         PARAM={}
73         evt=4
74         doc='doc' 
75         
76         for prop_name in dir(act_ob_data):
77                 if not prop_name.startswith('__') and prop_name not in IGNORE_VARS:
78                         # Get the type
79                         try:            exec 'prop_type= type(act_ob_data.%s)' % prop_name
80                         except:         prop_type= None
81                         
82                         if prop_type != None and prop_type not in (type_func_method, type_func, type_dict):
83                                 
84                                 # Now we know that the attribute can be listed in the UI Create a button and tooltip.
85                                 
86                                 # Tooltip
87                                 try:
88                                         if prop_name=='mode':
89                                                 try:
90                                                         exec "doc=str(%s.Modes)+' ; value : %s'"%( act_ob_type, str(act_ob_data.mode) )
91                                                 except:
92                                                         exec """doc= '%s'+' value = '+ str(act_ob.getData(mesh=1).%s)"""%(prop_name, prop_name) 
93                                         elif prop_name=='type':
94                                                 try:
95                                                         exec "doc=str(%s.Types)+' ; value : %s'"%( act_ob_type, str(act_ob_data.type) )
96                                                 except:
97                                                         exec """doc= '%s'+' value = '+ str(act_ob.getData(mesh=1).%s)"""%(prop_name, prop_name) 
98                                         else:
99                                                 exec """doc= '%s'+' value = '+ str(act_ob_data.%s)"""%(prop_name, prop_name)
100                                                 if doc.find('built-in')!=-1:
101                                                         exec """doc= 'This is a function ! Doc = '+ str(act_ob_data.%s.__doc__)"""% prop_name
102                                 except:    
103                                          doc='Doc...' 
104                                 
105                                 # Button
106                                 PARAM[prop_name]= [Create(0), evt, doc]
107                                 evt+=1
108
109         return PARAM
110
111 def copy():
112         global PARAM
113         
114         scn= Blender.Scene.GetCurrent()
115         act_ob= scn.getActiveObject()
116         if act_ob==None:
117                 Blender.Draw.PupMenu('Error|No Active Object.')
118                 return
119         
120         act_ob_type= act_ob.getType()
121         
122         if act_ob_type in ('Empty', 'Surf'):
123                 Blender.Draw.PupMenu('Error|Copying Empty or Surf object data isnt supported.')
124                 return   
125         
126         act_ob_data= act_ob.getData(mesh=1)
127         
128         print '\n\nStarting copy for object "%s"' % act_ob.name
129         some_errors= False
130         for ob in scn.objects.context:
131                 if ob != act_ob and ob.getType() == act_ob_type:
132                         ob_data= None
133                         for prop_name, value in PARAM.iteritems():
134                                 if value[0].val==1:
135                                         
136                                         # Init the object data if we havnt alredy
137                                         if ob_data==None:
138                                                 ob_data= ob.getData(mesh=1)
139                                         
140                                         try:
141                                                 exec "ob_data.%s = act_ob_data.%s"%(prop_name, prop_name) 
142                                         except:
143                                                 some_errors= True
144                                                 print 'Cant copy property "%s" for type "%s"' % (prop_name, act_ob_type)
145         if some_errors:
146                 Blender.Draw.PupMenu('Some attributes could not be copied, see console for details.')
147         
148 PARAM= renew()
149
150 def EVENT(evt,val):
151    pass
152
153 def BUTTON(evt):
154         global PARAM   
155         if (evt==1):
156                 Exit()
157
158         if (evt==2):
159                 copy()
160                 Blender.Redraw()
161
162         if (evt==3):
163                 PARAM= renew()
164                 Blender.Redraw()
165
166 def DRAW():
167         global PARAM
168         
169         scn= Blender.Scene.GetCurrent()
170         act_ob= scn.objects.active
171         
172         glColor3f(0.7, 0.7, 0.7)
173         glClear(GL_COLOR_BUFFER_BIT)
174         glColor3f(0.1, 0.1, 0.15)    
175
176         size=Buffer(GL_FLOAT, 4)
177         glGetFloatv(GL_SCISSOR_BOX, size)
178         size= size.list
179         for s in [0,1,2,3]: size[s]=int(size[s])
180         ligne=20
181
182         Button("Exit",1,20,4,80,ligne)
183         Button("Copy",2,102,4,80,ligne)
184         Button("Renew",3,184,4,80,ligne)
185
186         glRasterPos2f(20, ligne*2-8)
187         if act_ob:
188                 Text(act_ob.getType()+" DATA copier")
189         else:
190                 Text("Please select an object")
191
192
193         max=size[3] / 22 -2
194         pos   = 0
195         decal = 20
196         key=PARAM.keys()
197         key.sort()
198         for p in key:
199                 if  pos==max:
200                         decal+=102
201                         pos=1
202                 else:
203                         pos+=1       
204                 
205                 PARAM[p][0]=Toggle(p,
206                         PARAM[p][1],
207                         decal,
208                         pos*22+22,
209                         100,
210                         20, 
211                         PARAM[p][0].val,
212                         str(PARAM[p][2]))
213
214   
215 Register(DRAW,EVENT,BUTTON)