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