this is a script I used while we produced this opensource game : www.powerofwill.cz
it’s a simple script which is suitable for various ipo operations, like setting interpolation and extrapolation for all curves in all ipos on all selected objects. It also features a cleaning alglofithm which is tiny bit better than the one in blender, and works for all ipos also in actions, so it is good cleaning actions after baking or after import.
enjoy
#!BPY
""" Registration info for Blender menus: <- these words are ignored
Name: 'Ipo tools'
Blender: 234
Group: 'Animation'
Tip: 'tools for batch operations on ipos of objects and armatures, also for cleaning data.'
"""
#
#===============================================#
# ipo cleanup script by Vilem Novak #
# #
# if you have any questions about this script #
# email me pildanovak at post dot cz #
# #
#===============================================#
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
import Blender
from Blender import *
#from Blender.Armature import *
#from Blender.Armature.Bone import *
from Blender.Object import*
from Blender.Scene import *
from Blender.Mathutils import*
from Blender.NMesh import FaceModes,FaceTranspModes
print FaceModes
print FaceTranspModes
scn= Scene.GetCurrent()
ctx= scn.getRenderingContext()
theresold=Draw.Create(0.00001)
onlySlopes=Draw.Create(1)
def interface():
global theresold,onlySlopes
BGL.glClearColor(0.5, 0.5, 0.5, 1)
BGL.glColor3f(1.,1.,1.)
BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)
####buttons
Draw.Button("clearIpos", 4, 110, 10, 60, 25,"clear all ipo curves in selected object's Ipos (not in actions)")
Draw.Button("Exit", 1, 170, 10, 40, 25)
BGL.glRasterPos2i(150,190)
Draw.Text("set interpolation:")
Draw.Button("Linear", 6, 150, 160, 70, 25)
Draw.Button("Bezier", 7, 150, 130, 70, 25)
Draw.Button("Constant", 8, 150, 100, 70, 25)
BGL.glRasterPos2i(10,190)
Draw.Text("set extrapolation:")
Draw.Button("Constant", 11, 10, 170, 120, 18)
Draw.Button("Extrapolation", 12, 10, 150, 120, 18)
Draw.Button("Cyclic", 13, 10, 130, 120, 18)
Draw.Button("Cyclic_extrapolation", 14, 10, 110, 120, 18)
Draw.Button("CleanupIpos", 10, 10, 10, 100, 25,"Removes redundant points in the ipo curves using the theresold value (for armatures also for associated actions)")
theresold = Blender.Draw.Number("theresold", 2, 10, 60, 210, 18, theresold.val, .0000, 10, "differences smaller than this will be cleaned")
onlySlopes=Draw.Toggle("only slopes", 1000, 10, 40, 100, 18,onlySlopes.val,"if turned on, only points on the slopes of ipocurves will be filtered.")
def exit(evt, val):
if evt == Blender.Draw.ESCKEY and not val: Blender.Draw.Exit()
def events(event):
if event==1:
Draw.Exit()
if event==4:
clearIpos()
if event ==6:
setType('Linear')
if event ==7:
setType('Bezier')
if event ==8:
setType('Constant')
if event ==10:
cleanupIpos()
if event ==11:
setExt('Constant')
if event ==12:
setExt('Extrapolation')
if event ==13:
setExt('Cyclic')
if event ==14:
setExt('Cyclic_extrapolation')
if event==1000:
print onlySlopes.val
def extractCurves():#get cruves from all selected objects and armatures
obj=GetSelected()
curves=[]
print 'anikurvy'
for ob in obj:
ipo=ob.getIpo()
if ipo!=None:
curves.extend(ipo.getCurves())
#print ob.getType
if ob.getType()=='Armature':
print 'object is an armature'
a = ob.getAction()
aipos = a.getAllChannelIpos()
print aipos
for key in aipos.keys():
curves.extend(aipos[key].getCurves())
print 'asponkurvy'
return curves
def cleanupIpos():
global fsold,onlySlopes
scn= Scene.GetCurrent()
oi=0
curves=extractCurves()
i=0
print 'starting cleanup'
total=0
totalp=0
for c in curves:
t=theresold.val
if c.name[:4]=='Quat':
t=t/2.0####quaternions get more care in actions, since they are only from -1 to 1 representing 360 degrees
points= c.bezierPoints
erase=[]
##########################
#stats
##########################
beginarea=0
arealen=0
peaks=0
threses=0
lthreses=0
##########################
#cleaning
#############################
for a in range(1,len(points)-1):
pt=points[a].pt
# pt1=points[a-1].pt
pt1=points[beginarea].pt
pt2=points[a+1].pt
# the supercondition for distance from slope
dif=abs((pt1[1]+(pt2[1]-pt1[1])*((pt[0]-pt1[0])/(pt2[0]-pt1[0])))-pt[1])
#print dif
thres = dif<t
littlethres = dif<t/10###littlethres is for very small peaks on straight curves
peak = (onlySlopes.val) and ((pt1[1]<=pt[1] and pt2[1]<=pt[1]) or (pt1[1]>=pt[1] and pt2[1]>=pt[1]))
threses+=thres
lthreses+=littlethres
peaks+=peak
if (thres and not peak) or littlethres:
erase.append(a)
else:
beginarea=a
erase.reverse()
total+=len(erase)
totalp+=len(points)
for p in erase:
c.delBezier(p)
c.interpolation=IpoCurve.InterpTypes.LINEAR
c.recalc()
scn.update()
print 'cleaned up %d out of %d points in %d curves' % (total,totalp,len(curves))
Blender.Window.RedrawAll()
def clearIpos():
obj=GetSelected()
for ob in obj:
ipo=Blender.Ipo.New('Object',ob.name)
ob.setIpo(ipo)
Blender.Window.RedrawAll()
def setType(type):
curves=extractCurves()
for c in curves:
c.setInterpolation(type)
c.recalc()
Blender.Window.RedrawAll()
class emp:
pass
def setExt(ext):
curves=extractCurves()
for c in curves:
c.setExtrapolation(ext)
c.recalc()
#print 'e'
Blender.Window.RedrawAll()
Draw.Register(interface,exit,events)