[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20389] trunk/blender/release/scripts/ animation_clean.py: utility script for cleaning ipos animation curves,

joe joeedh at gmail.com
Tue May 26 05:32:22 CEST 2009


Yes! I've been wanting this!

Joe

On Sun, May 24, 2009 at 6:30 PM, Campbell Barton <ideasman42 at gmail.com> wrote:
> Revision: 20389
>          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20389
> Author:   campbellbarton
> Date:     2009-05-25 02:30:06 +0200 (Mon, 25 May 2009)
>
> Log Message:
> -----------
> utility script for cleaning ipos animation curves,
> used in YoFrankie to reduce file size for large actions
>
> Added Paths:
> -----------
>    trunk/blender/release/scripts/animation_clean.py
>
> Added: trunk/blender/release/scripts/animation_clean.py
> ===================================================================
> --- trunk/blender/release/scripts/animation_clean.py                            (rev 0)
> +++ trunk/blender/release/scripts/animation_clean.py    2009-05-25 00:30:06 UTC (rev 20389)
> @@ -0,0 +1,192 @@
> +#!BPY
> +
> +"""
> +Name: 'Clean Animation Curves'
> +Blender: 249
> +Group: 'Animation'
> +Tooltip: 'Remove unused keyframes for ipo curves'
> +"""
> +
> +# ***** BEGIN GPL LICENSE BLOCK *****
> +#
> +# Copyright (C) 2008-2009: Blender Foundation
> +#
> +# 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,
> +# --------------------------------------------------------------------------
> +
> +import bpy
> +from Blender import IpoCurve, Draw, Window
> +
> +def clean_ipos(ipos):
> +       eul = 0.001
> +
> +       def isflat(vec):
> +               prev_y = vec[0][1]
> +               mid_y = vec[1][1]
> +               next_y = vec[2][1]
> +
> +               # flat status for prev and next
> +               return abs(mid_y-prev_y) < eul, abs(mid_y-next_y) < eul
> +
> +
> +
> +       X=0
> +       Y=1
> +       PREV=0
> +       MID=1
> +       NEXT=2
> +
> +       LEFT = 0
> +       RIGHT = 1
> +
> +       TOT = 0
> +       TOTBEZ = 0
> +       # for ipo in bpy.data.ipos:
> +       for ipo in ipos:
> +               if ipo.lib:
> +                       continue
> +               # print ipo
> +               for icu in ipo:
> +                       interp = icu.interpolation
> +                       extend = icu.extend
> +
> +                       bezierPoints = icu.bezierPoints
> +                       bezierVecs = [bez.vec for bez in bezierPoints]
> +
> +                       l = len(bezierPoints)
> +
> +                       TOTBEZ += l
> +
> +                       # our aim is to simplify this ipo as much as possible!
> +                       if interp == IpoCurve.InterpTypes.BEZIER or interp == interp == IpoCurve.InterpTypes.LINEAR:
> +                               #print "Not yet supported"
> +
> +                               if interp == IpoCurve.InterpTypes.BEZIER:
> +                                       flats = [isflat(bez) for bez in bezierVecs]
> +                               else:
> +                                       # A bit of a waste but fake the locations for these so they will always be flats
> +                                       # IS better then too much duplicate code.
> +                                       flats = [(True, True)] * l
> +                                       for v in bezierVecs:
> +                                               v[PREV][Y] = v[NEXT][Y] = v[MID][Y]
> +
> +
> +                               # remove middle points
> +                               if l>2:
> +                                       done_nothing = False
> +
> +                                       while not done_nothing and len(bezierVecs) > 2:
> +                                               done_nothing = True
> +                                               i = l-2
> +
> +                                               while i > 0:
> +                                                       #print i
> +                                                       #print i, len(bezierVecs)
> +                                                       if flats[i]==(True,True)  and  flats[i-1][RIGHT]  and  flats[i+1][LEFT]:
> +
> +                                                               if abs(bezierVecs[i][MID][Y] - bezierVecs[i-1][MID][Y]) < eul   and   abs(bezierVecs[i][MID][Y] - bezierVecs[i+1][MID][Y]) < eul:
> +                                                                       done_nothing = False
> +
> +                                                                       del flats[i]
> +                                                                       del bezierVecs[i]
> +                                                                       icu.delBezier(i)
> +                                                                       TOT += 1
> +                                                                       l-=1
> +                                                       i-=1
> +
> +                               # remove endpoints
> +                               if extend == IpoCurve.ExtendTypes.CONST and len(bezierVecs) > 1:
> +                                       #print l, len(bezierVecs)
> +                                       # start
> +
> +                                       while l > 2 and (flats[0][RIGHT]  and  flats[1][LEFT] and (abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul)):
> +                                               print "\tremoving 1 point from start of the curve"
> +                                               del flats[0]
> +                                               del bezierVecs[0]
> +                                               icu.delBezier(0)
> +                                               TOT += 1
> +                                               l-=1
> +
> +
> +                                       # End
> +                                       while l > 2 and flats[-2][RIGHT]  and  flats[-1][LEFT] and (abs(bezierVecs[-2][MID][Y] - bezierVecs[-1][MID][Y]) < eul):
> +                                               print "\tremoving 1 point from end of the curve", l
> +                                               del flats[l-1]
> +                                               del bezierVecs[l-1]
> +                                               icu.delBezier(l-1)
> +                                               TOT += 1
> +                                               l-=1
> +
> +
> +
> +                               if l==2:
> +                                       if isflat( bezierVecs[0] )[RIGHT] and isflat( bezierVecs[1] )[LEFT] and abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul:
> +                                               # remove the second point
> +                                               print "\tremoving 1 point from 2 point bez curve"
> +                                               # remove the second point
> +                                               del flats[1]
> +                                               del bezierVecs[1]
> +                                               icu.delBezier(1)
> +                                               TOT+=1
> +                                               l-=1
> +
> +                               # Change to linear for faster evaluation
> +                               '''
> +                               if l==1:
> +                                       print 'Linear'
> +                                       icu.interpolation = IpoCurve.InterpTypes.LINEAR
> +                               '''
> +
> +
> +
> +
> +                       if interp== IpoCurve.InterpTypes.CONST:
> +                               print "Not yet supported"
> +
> +       print 'total', TOT, TOTBEZ
> +       return TOT, TOTBEZ
> +
> +def main():
> +       ret = Draw.PupMenu('Clean Selected Objects Ipos%t|Object IPO%x1|Object Action%x2|%l|All IPOs (be careful!)%x3')
> +
> +       sce = bpy.data.scenes.active
> +       ipos = []
> +
> +       if ret == 3:
> +               ipos.extend(list(bpy.data.ipos))
> +       else:
> +               for ob in sce.objects.context:
> +                       if ret == 1:
> +                               ipo = ob.ipo
> +                               if ipo:
> +                                       ipos.append(ipo)
> +
> +                       elif ret == 2:
> +                               action = ob.action
> +                               if action:
> +                                       ipos.extend([ipo for ipo in action.getAllChannelIpos().values() if ipo])
> +
> +
> +
> +       if not ipos:
> +               Draw.PupMenu('Error%t|No ipos found')
> +       else:
> +               total_removed, total = clean_ipos(ipos)
> +               Draw.PupMenu('Done!%t|Removed ' + str(total_removed) + ' of ' + str(total) + ' points')
> +
> +       Window.RedrawAll()
> +
> +
> +if __name__ == '__main__':
> +       main()
>
>
> _______________________________________________
> Bf-blender-cvs mailing list
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>


More information about the Bf-committers mailing list