Scripts:
[blender.git] / release / scripts / bvh2arm.py
1 #!BPY
2 """
3 Name: 'Empties to Armature'
4 Blender: 241
5 Group: 'Animation'
6 Tooltip: 'Create Armature from a parented-empties chain'
7 """
8 __author__ = " Jean-Baptiste PERIN (jb_perin(at)yahoo.fr) with valuable help from Vincent BILLET "
9 __url__ = ("blender", "elysiun",
10 "BVH 2 ARMATURE, http://perso.wanadoo.fr/jb.perin/",
11 "Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") 
12
13 __version__ = "2.42"
14
15 __bpydoc__ = """ BVH2ARM.py 
16
17 Script for generating armature on BVH empties.
18
19 This script generates an armature upon an empty-made parented chain, 
20 and make the armature follow the empties 
21
22 Usage:<br>
23  - Import a bvh in Blender (File->Import->BVH);<br>
24  - Rotate some empties to match your model and insert Rot key for them. <br>
25  - Select the root empty of the hierarchical chain.<br>
26  - Launch this script ;<br>
27  - Set up variables:<br>
28    "hipbonename": the name of the main bone (automatically set to the selected empty).<br>
29    "startframe":  the first frame of your anim;<br>
30    "endframe":  the last frame of your anim;<br>
31    "decimation": the frequency (in number of frame) to which the armature's pos is updated;<br>
32 - Press "Create Armature".
33 Notes: <br>
34 - The start frame configuration is used as the rest pose for the armature.<br>
35 - If the armature already exists when script is launched, the current armature is re-used.
36 """
37 # -------------------------------------------------------------------------- 
38 # BVH2ARM.py 
39 # -------------------------------------------------------------------------- 
40 # ***** BEGIN GPL LICENSE BLOCK ***** 
41
42 # This program is free software; you can redistribute it and/or 
43 # modify it under the terms of the GNU General Public License 
44 # as published by the Free Software Foundation; either version 2 
45 # of the License, or (at your option) any later version. 
46
47 # This program is distributed in the hope that it will be useful, 
48 # but WITHOUT ANY WARRANTY; without even the implied warranty of 
49 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
50 # GNU General Public License for more details. 
51
52 # You should have received a copy of the GNU General Public License 
53 # along with this program; if not, write to the Free Software Foundation, 
54 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
55
56 # ***** END GPL LICENCE BLOCK ***** 
57 # -------------------------------------------------------------------------- 
58
59
60
61 import Blender
62 from Blender import Mathutils
63 import math
64
65 dicEmptiesRestMatrix= {}
66 dicEmptiesInvRestMatrix= {}
67 dicBoneRestMatrix= {}
68 dicBone={}
69 dicEmptyChild={}
70 dicBoneRestInvEmpRest={}
71 dicEmpRestInvBoneRest={}
72 restFrame = 1
73 bonerest={}
74 emprest={}
75 emp2bone={}
76
77 ########################################################################
78 #
79 #          UTILITY FUNCTIONS FOR HANDLING BONES AND EMPTIES
80 #
81 ########################################################################
82
83 def names(ob): return ob.getName()
84
85 #########
86 # Cette fonction renvoie la liste des empties attaches a root
87 # in  : 
88 # out : emp_list (List of Object) la liste des objets de type "Empty"
89 #########
90 def getTree(emp_list, root):
91         empties=getAllEmpties()
92         chlds = getChildren(root, empties)
93         dicEmptyChild[root.getName()]=chlds
94         for ch in chlds:
95                 emp_list.append(ch)
96                 getTree(emp_list,ch)
97
98 #########
99 # Cette fonction renvoie la liste des empties attaches a root
100 # in  : 
101 # out : emp_list (List of Object) la liste des objets de type "Empty"
102 #########
103 def getEmpties():
104         global hipbonename
105         emp_list = []
106         root = Blender.Object.Get(hipbonename)
107         emp_list.append(root)
108         getTree(emp_list, root)
109         return emp_list
110
111 #########
112 # Cette fonction renvoie la liste des empties
113 # in  : 
114 # out : emp_list (List of Object) la liste des objets de type "Empty"
115 #########
116 def getAllEmpties():
117         emp_list = []
118         objs = Blender.Object.Get()
119         for o in objs:
120                 if o.getType()=="Empty":
121                         emp_list.append(o)
122         return emp_list
123
124 #########
125 # Cette fonction renvoie la liste des empties
126 # in  : 
127 # out : emp_list (List of Object) la liste des objets de type "Empty"
128 #########
129 def getEmpty(name):
130         p = None
131         objs = Blender.Object.Get()
132         for o in objs:
133                 if o.getType()=="Empty" and o.getName()==name:
134                         p = o
135         return p
136
137 ##def getChild(emp, emp_list):
138 ##      return dicEmptyChild[emp.getName()]
139
140
141 #########
142 # Cette fonction fournit la liste des enfants d'un empty
143 # in  : emp (Object) un empty
144 #       emp_list (List of Object) la liste des empties
145 # out : children (List of Object) la liste des empties enfants de 'empty'
146 #########
147 def getChildren(emp, emp_list):
148         children = []
149         root_emp = getRootEmpties(emp_list)
150         for em in emp_list:
151                 if (em.getName() != emp.getName()) and (em not in root_emp):
152                         if (em.getParent().getName() == emp.getName()):
153                                 children.append(em)
154         return children
155
156
157
158 #########
159 # Cette fonction renvoie la liste des empties n'ayant pas de parent
160 # in  : emp_list (List) une liste d'empties
161 # out : root (List) le (ou les) empty n'ayant pas de parent
162 #########
163 def getRootEmpties(emp_list):
164         root = []
165         for em in emp_list:
166                 if em.getParent() == None:
167                         root.append(em)
168         return root
169
170
171 #########
172 # Cette fonction renvoie le bone de nom 'name' dans l'armature 'armature'
173 # in  : armature (Armature) l'armature dans laquelle cherchait le bone
174 #       name (String) le nom de l'os a chercher
175 # out : p (Bone) 
176 #########
177 #def getBone(armature, name):
178 #       return (dicBone[name])
179         #p = None
180         #bones = armature.getBones()
181         #for i in bones:
182         #       if i.getName() == name:
183         #               p = i
184         #               break
185         #return p
186
187
188 def eraseIPO (objectname):
189         object = Blender.Object.Get(objectname)
190         lIpo = object.getIpo()
191         if lIpo != None:
192                 nbCurves = lIpo.getNcurves()
193                 for i in range(nbCurves):
194                         nbBezPoints = lIpo.getNBezPoints(i)
195                         for j in range(nbBezPoints):
196                                 lIpo.delBezPoint(i)
197
198
199
200
201 def GetOrCreateIPO(name):
202
203         ipos = Blender.Ipo.Get()
204         if name in map(names,ipos):
205                 myipo = Blender.Ipo.Get(name)
206                 print name+' exists'
207         else:
208                 myipo = Blender.Ipo.New('Object',name)
209                 print name+' was created'
210         return myipo
211
212
213 def GetOrCreateCurve(ipo, curvename):
214         curves = ipo.getCurves()
215         if curvename in map(names,curves):
216                 mycurve = ipo.getCurve(curvename)
217                 print curvename+' exists'
218         else:
219                 mycurve = ipo.addCurve(curvename)
220                 print curvename+' was created'
221         return mycurve
222
223
224
225
226 ########################################################################
227 #
228 # FUNCTIONS FOR COMPUTING POSITION AND ROTATION OF BONES 
229 #
230 ########################################################################
231
232
233
234 #########
235 # Cette fonction 
236 # in  : 
237 # out : 
238 #########
239 def computeScaledPos(vec):
240         global scalef
241         vec2 = Mathutils.Vector([vec[0]*scalef, vec[1]*scalef, vec[2]*scalef])
242         return vec2
243
244 ########################################################################
245 #
246 #            FUNCTIONS FOR CREATING AND MOVING ARMATURES
247 #
248 ########################################################################
249
250 #########
251 # Cette fonction 
252 # in  : 
253 # out : 
254 #########
255 def createBone (armature, empty, bone, empties):
256         global bonerest, emprest
257         children = getChildren(empty, empties)
258         if len(children) != 0:
259           for ch in children:
260                 if len(children) >= 2:
261                         bonename = empty.getName()[1:len(empty.getName())]+'_'+ch.getName()[1:len(ch.getName())]
262                 else :
263                         bonename = empty.getName()[1:len(empty.getName())]
264                 print "creating Bone %s"%(bonename)
265                 b=Blender.Armature.Editbone()
266                 b.head = (computeScaledPos(empty.getMatrix('worldspace').translationPart()))
267                 b.tail = (computeScaledPos(ch.getMatrix('worldspace').translationPart()))
268                 b.parent = bone
269                 # armature.makeEditable()  should already be editable????
270                 armature.bones[bonename] = b
271                 #print b.matrix
272                 bonerest[bonename]=Blender.Mathutils.Matrix(b.matrix).resize4x4()
273                 emprest[empty.getName()]=Blender.Mathutils.Matrix(empty.getMatrix('localspace')).resize4x4()
274                 #M = Blender.Mathutils.Matrix(emprest[empty.getName()])
275                 #emp2bone[bonename] =  Blender.Mathutils.Matrix(M.invert().rotationPart()*bonerest[bonename].rotationPart()).resize4x4()
276                 #print emp2bone[bonename].rotationPart().toEuler()
277                 dicBone[b.name]=b
278                 createBone(armature, ch, b, empties)
279
280 #########
281 # Cette fonction 
282 # in  : 
283 # out : 
284 #########
285 def f_createBone (armData, empty, bone, empties):
286         bones = armData.bones.values()
287         def getBone(bonename):
288                 bone = None
289                 for b in bones:
290                         #print b.getName()
291                         if b.name == bonename:
292                                 bone = b
293                 return bone
294
295         children = getChildren(empty, empties)
296         for ch in children:
297                 if len(children) >= 2:
298                         bonename = empty.getName()[1:len(empty.getName())]+'_'+ch.getName()[1:len(ch.getName())]
299                 else :
300                         bonename = empty.getName()[1:len(empty.getName())]
301                 #b=Blender.Armature.Bone.New(bonename)
302                 b=getBone(bonename)
303                 b.head = (computeScaledPos(empty.getMatrix('worldspace').translationPart()))
304                 b.tail = (computeScaledPos(ch.getMatrix('worldspace').translationPart()))
305                 b.parent = bone
306                 bonerest[bonename]=Blender.Mathutils.Matrix(b.matrix).resize4x4()
307                 emprest[empty.getName()]=Blender.Mathutils.Matrix(empty.getMatrix('localspace')).resize4x4()
308                 dicBone[b.name]=b
309                 #print "Ajout de ", b.getName(),"  au dictionnaire"
310                 f_createBone(armData, ch, b, empties)
311         
312 #########
313 # Cette fonction fabrique une arma
314 # in  : 
315 # out : 
316 #########
317 def createArmature (armObj, rootEmpty, empties):
318         global bonerest, emprest
319         armData=Blender.Armature.Armature('monArmature')
320         children = getChildren(rootEmpty, empties)
321         armObj.link(armData)
322         armData.makeEditable()
323         for ch in children:
324                 b=Blender.Armature.Editbone()
325                 bonename = rootEmpty.getName()[1:len(rootEmpty.getName())] + ch.getName()[1:len(ch.getName())]
326                 print "creating Bone %s"%(bonename)
327
328                 #print b, dir([b])
329                 b.head=(computeScaledPos(rootEmpty.getMatrix('worldspace').translationPart()))
330                 b.tail=(computeScaledPos(ch.getMatrix('worldspace').translationPart()))
331                 
332                 bonerest[bonename]=Blender.Mathutils.Matrix(b.matrix).resize4x4()
333                 emprest[rootEmpty.getName()]=Blender.Mathutils.Matrix(rootEmpty.getMatrix('localspace')).resize4x4()
334                 armData.bones[bonename] = b
335                 dicBone[b.name]=b
336                 createBone(armData, ch, b, empties)
337         armData.update()
338         return armData
339
340
341
342 #########
343 # Cette fonction fabrique une arma
344 # in  : 
345 # out : 
346 #########
347 def f_createArmature (rootEmpty, empties, armData):
348         armData.makeEditable()
349         bones = armData.bones.values()
350
351         def getBone(bonename):
352                 bone = None
353                 for b in bones:
354                         #print b.getName()
355                         if b.name == bonename:
356                                 bone = b
357                 return bone
358
359         children = getChildren(rootEmpty, empties)
360         for ch in children:
361                 b=getBone(rootEmpty.getName()[1:len(rootEmpty.getName())] + ch.getName()[1:len(ch.getName())])
362                 dicBone[b.name]=b
363                 #print "Ajout de ", b.getName(),"  au dictionnaire"
364                 bonerest[b.name]=Blender.Mathutils.Matrix(b.matrix).resize4x4()
365                 emprest[rootEmpty.getName()]=Blender.Mathutils.Matrix(rootEmpty.getMatrix('localspace')).resize4x4()
366                 f_createBone(armData, ch, b, empties)
367
368         armData.update()
369
370
371 #########
372 # Cette fonction 
373 # in  : 
374 # out : 
375 #########
376 def moveBones(larmature, empty, empties):
377         #print "move bones"
378         global bonerest, emprest
379         children = dicEmptyChild[empty.getName()]
380         thepose = larmature.getPose()
381         for ch in children:
382                 if len(children) >= 2:
383                         bonename = empty.getName()[1:len(empty.getName())]+'_'+ch.getName()[1:len(ch.getName())]
384                 else :
385                         bonename = empty.getName()[1:len(empty.getName())]
386                 thebone = thepose.bones[bonename]
387                 trMatrix = empty.getMatrix('localspace')
388                 bonerestmat = Blender.Mathutils.Matrix(bonerest[bonename])
389                 invbonerestmat = Blender.Mathutils.Matrix(bonerest[bonename])
390                 invbonerestmat.invert()
391                 trMatrix[3][0] = 0.0
392                 trMatrix[3][1] = 0.0
393                 trMatrix[3][2] = 0.0
394                 invemprestmat = Blender.Mathutils.Matrix(emprest[empty.getName()].rotationPart()).resize4x4()
395                 invemprestmat.invert()
396                 emprestmat = Blender.Mathutils.Matrix(emprest[empty.getName()].rotationPart()).resize4x4()
397                 thebone.localMatrix = bonerestmat* invemprestmat *trMatrix * invbonerestmat 
398                 thepose.update()
399                 thebone.insertKey(larmature, Blender.Get('curframe'), [Blender.Object.Pose.ROT, Blender.Object.Pose.LOC])
400                 thepose.update()
401                 chch = dicEmptyChild[ch.getName()]
402                 if len(chch) >= 1:
403                         moveBones(larmature, ch, empties)
404
405
406 #########
407 # Cette fonction 
408 # in  : 
409 # out : 
410 #########
411 def moveArmature (larmature, empties):
412         global bonerest, emprest
413         #print "move armature"
414         thepose = larmature.getPose()
415         #armature.makeEditable()
416         root = Blender.Object.Get(hipbonename)
417         children = dicEmptyChild[hipbonename]
418         for ch in children:
419                 b=dicBone[hipbonename[1:len(hipbonename)] + ch.getName()[1:len(ch.getName())]]
420                 
421                 moveBones(larmature, ch, empties)
422         #armature.update()
423
424
425
426
427 ########################################################################
428 #
429 #                  MAIN PROGRAM
430 #
431 ########################################################################
432
433 def RemoveEmpties():
434
435         global endframe, startframe,hipbonename
436
437         lesEmpties = getEmpties()
438         scn = Blender.Scene.getCurrent()
439         #scn.link (armObj)
440         for em in lesEmpties:
441                 eraseIPO (em.getName())
442                 scn.unlink(em)
443         Blender.Redraw()
444
445
446 def Main():
447
448         global endframe, startframe,hipbonename, framedecimation
449
450
451         print "*****START*****"
452
453         Blender.Set("curframe",restFrame)
454
455         ##-----------
456         ## Positionnement des empties
457         ##-----------
458         em0 = Blender.Object.Get(hipbonename)
459
460         Blender.Redraw()
461
462
463
464         ##-----------
465         ## Creation de l'armature et des os
466         ##-----------
467
468         lesEmpties = getEmpties()
469         #print dicEmptyChild    
470         print "creating armature"
471         #armData = createArmature(em0, lesEmpties)
472         objects = Blender.Object.Get()
473         if 'OBArmature' in map(names,objects):
474                 armObj = Blender.Object.Get('OBArmature')
475                 armData = armObj.getData()
476                 print 'OBArmature'+' exists'
477                 eraseIPO ('OBArmature')
478                 #print armData.getBones()
479                 f_createArmature(em0, lesEmpties, armData)
480         else:
481                 armObj=Blender.Object.New('Armature', 'OBArmature')
482                 armData= createArmature(armObj, em0, lesEmpties)
483                 #armObj.link(armData)
484                 scn = Blender.Scene.getCurrent()
485                 scn.link (armObj)
486
487                 print 'OBArmature'+' was created'
488         #return myobj
489         print emprest
490         armData.drawType = Blender.Armature.STICK 
491         ##-----------
492         ## Creation de l'ipo de l'armature
493         ##-----------
494         lipo = GetOrCreateIPO('BVHIpo')
495         armObj.setIpo(lipo)
496         curvX =  GetOrCreateCurve(lipo, 'LocX')
497         curvY =  GetOrCreateCurve(lipo, 'LocY')
498         curvZ =  GetOrCreateCurve(lipo, 'LocZ')
499         curvrX =  GetOrCreateCurve(lipo, 'RotX')
500         curvrY =  GetOrCreateCurve(lipo, 'RotY')
501         curvrZ =  GetOrCreateCurve(lipo, 'RotZ')
502
503         print "animating armature"
504
505         #armData.drawAxes(1)
506         #armData.drawNames(1)
507
508         
509
510         Blender.Redraw()
511
512         action = Blender.Armature.NLA.NewAction()
513         action.setActive(armObj)
514
515
516
517         ##-----------
518         ## Enregistrement de la position  de l'armature
519         ##-----------
520
521         bones = armData.bones.values()
522
523         curvX.addBezier((Blender.Get("curframe"), getEmpty(hipbonename).getMatrix('worldspace').translationPart()[0]*scalef))
524         curvY.addBezier((Blender.Get("curframe"), getEmpty(hipbonename).getMatrix('worldspace').translationPart()[1]*scalef))
525         curvZ.addBezier((Blender.Get("curframe"), getEmpty(hipbonename).getMatrix('worldspace').translationPart()[2]*scalef))
526         curvX.setInterpolation('Linear')
527         curvX.setExtrapolation('Constant')
528         curvY.setInterpolation('Linear')
529         curvY.setExtrapolation('Constant')
530         curvZ.setInterpolation('Linear')
531         curvZ.setExtrapolation('Constant')
532         curvrX.setInterpolation('Linear')
533         curvrX.setExtrapolation('Constant')
534         curvrY.setInterpolation('Linear')
535         curvrY.setExtrapolation('Constant')
536         curvrZ.setInterpolation('Linear')
537         curvrZ.setExtrapolation('Constant')
538
539         Blender.Redraw()
540
541         Blender.Set("curframe",startframe)
542         while endframe >= Blender.Get("curframe"):
543
544                 ##-----------
545                 ## Positionnement des os
546                 ##-----------
547
548                 moveArmature(armObj, lesEmpties)
549
550
551                 ##-----------
552                 ## Enregistrement de la position  de l'armature
553                 ##-----------
554
555                 curvX.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').translationPart()[0])*scalef))
556                 curvY.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').translationPart()[1])*scalef))
557                 curvZ.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').translationPart()[2])*scalef))
558                 curvrX.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').rotationPart().toEuler()[0])*scalef/10))
559                 curvrY.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').rotationPart().toEuler()[1])*scalef/10))
560                 curvrZ.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').rotationPart().toEuler()[2])*scalef/10))
561
562                 ##-----------
563                 ## Passage a la frame suivante
564                 ##-----------
565                 num_frame = Blender.Get("curframe")+framedecimation
566                 print num_frame
567                 Blender.Set("curframe", num_frame)
568
569         curvX.Recalc()
570         curvY.Recalc()
571         curvZ.Recalc()
572         curvrX.Recalc()
573         curvrY.Recalc()
574         curvrZ.Recalc()
575         Blender.Set("curframe",startframe)
576         Blender.Redraw()
577
578         print "*****END*****"
579
580
581 ########################################################################
582 #
583 #            GUI FUNCTIONS AND VARIABLES
584 #
585 ########################################################################
586
587 EFrame = Blender.Draw.Create(5)
588 IFrame = Blender.Draw.Create(6)
589 SFrame2 = Blender.Draw.Create(5)
590 HBName = Blender.Draw.Create(0)
591 FrameDecimation = Blender.Draw.Create(5)
592 ScaleF =  Blender.Draw.Create(0)
593
594 Msg = ' '
595
596 def event (evt, val):
597         if evt == Blender.Draw.ESCKEY:
598                 Blender.Draw.Exit()
599         return
600
601 def button_event(evt):
602         global EFrame, IFrame, SFrame2, HBName, Msg , FrameDecimation, ScaleF
603         global endframe, startframe, insertionframe, hipbonename, framedecimation , scalef
604         if evt==1:
605                 startframe = SFrame2.val
606                 insertionframe = 100 #IFrame.val
607                 endframe =  EFrame.val
608                 hipbonename = HBName.val
609                 framedecimation = FrameDecimation.val
610                 scalef= 1.0 #eval(str(ScaleF.val))
611                 #print "scalef = ", scalef
612                 if startframe>=endframe:
613                         Msg = 'Start frame must be lower than End frame'
614                         error_txt = "Error|Start frame must be lower than End frame"
615                         Blender.Draw.PupMenu(error_txt)
616                 else:
617                         ob = getEmpty(hipbonename)
618                         if (ob!=None): 
619                                 if ob.getParent()!=None:
620                                         Msg = 'Empty '+hipbonename+ ' is not a root bone.'
621                                         error_txt = "Error|Empty %s is not a root bone"%hipbonename
622                                         Blender.Draw.PupMenu(error_txt)
623                                 else:  
624                                         if (0.0 > scalef):
625                                                 Msg = 'Scale factor must be greater than 0'
626                                                 error_txt = "Error|Scale factor must be greater than 0"
627                                                 Blender.Draw.PupMenu(error_txt)
628                                         else:
629                                                 #Blender.Draw.Exit()
630                                                 Main()
631                                 #Main()
632                         else:
633                                 error_txt = "Error|Empty %s not found"%hipbonename
634                                 Blender.Draw.PupMenu(error_txt)
635                                 Msg = 'Empty '+ hipbonename+ ' not found'
636                                 
637                 #Blender.Draw.Redraw(1)
638         elif evt==2:
639                 hipbonename = HBName.val
640                 ob = getEmpty(hipbonename)
641                 if (ob!=None): 
642                         if ob.getParent()!=None:
643                                 error_txt = "Error|Empty %s is not a root bone"%hipbonename
644                                 Blender.Draw.PupMenu(error_txt)
645
646                                 Msg = 'Empty '+hipbonename+ ' is not a root bone.'
647                         else:  
648                                 #Blender.Draw.Exit()
649                                 RemoveEmpties()
650                 else:
651                         Msg = 'Empty '+ hipbonename+ ' not found'
652
653         #else:
654         #       print "evt = ",evt
655
656 def GUI():
657         global EFrame, SFrame2, HBName, Msg , ScaleF, FrameDecimation
658         Blender.BGL.glClearColor(0,0,1,1)
659         Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)
660         Blender.BGL.glColor3f(1,1,1)
661         Blender.BGL.glRasterPos2i(20,200)
662         selobj = Blender.Object.GetSelected()
663         if len(selobj) == 1 and type (selobj[0]) == Blender.Types.ObjectType:
664                 hipname = selobj[0].getName()
665         else:
666                 hipname = '_Hips'
667         Blender.Draw.Text ("BVH 2 ARMATURE v%s by %s"%(__version__, __author__), 'normal')
668         HBName = Blender.Draw.String("HipBoneName: ", 0, 20, 175, 250, 20, hipname, 100)
669         SFrame2 = Blender.Draw.Number("Startframe: ", 0, 20, 150, 250, 20, 1, 1,3000,"Start frame of anim")
670         EFrame = Blender.Draw.Number("Endframe: ", 0, 20, 125, 250, 20, Blender.Get("endframe"), 1,3000,"Last frame of anim")
671         FrameDecimation = Blender.Draw.Number("FrameDecimation: ", 0, 20, 75, 250, 20,1, 1,10,'number of frame to skip between two action keys')
672         Blender.Draw.Toggle("Create Armature", 1, 20, 10, 100, 20, 0, "Create Armature")
673         Blender.BGL.glRasterPos2i(20,40)
674         Blender.Draw.Text (Msg, 'normal')
675
676
677 Blender.Draw.Register(GUI, event, button_event)