# --------- # Tested in Blender 2.75a and 2.76 # Makes a Bezier-spline motion trail for an object. # Set the length of the tail in frames via the tail_length variable below. # To run, select object, generate a motion path for the object (Editor>Motion Paths) across the total desired frame range, and Run Script. # Warning: this can take a long time to run with long motion paths and long tail sizes # Once the spline has been generated, extrude and/or add bevel and taper objects to the Geometry settings of the spline. # Bret Battey / BatHatMedia.com September 2015 # --------- import bpy from bpy.props import * from mathutils import * from math import * import time # ----- FUNCTION DEFINITIONS ----- # Time utils thanks to http://blenderscripting.blogspot.co.uk/search/label/time def get_last_time(): if len(time_list) < 2: return "ERROR: must have two time entries to calculate the difference" return time_list[-1] - time_list[-2] def mark_time(): time_list.append(time.time()) time_list = [] ##------------------------------------------------------------ #### Curve creation functions # sets bezierhandles to auto def setBezierHandles(obj, mode = 'AUTOMATIC'): scene = bpy.context.scene if obj.type != 'CURVE': return scene.objects.active = obj bpy.ops.object.mode_set(mode='EDIT', toggle=True) bpy.ops.curve.select_all(action='SELECT') bpy.ops.curve.handle_type_set(type=mode) bpy.ops.object.mode_set(mode='OBJECT', toggle=True) # create new CurveObject def createCurve(verts, name): # create curve scene = bpy.context.scene newCurve = bpy.data.curves.new(name, type = 'CURVE') # curvedatablock newSpline = newCurve.splines.new(type = 'BEZIER') # spline # The new spline already has one point. Add the remaining needed. newSpline.bezier_points.add(verts-1) # set curveOptions newCurve.dimensions = '3D' # create object with newCurve new_obj = bpy.data.objects.new(name, newCurve) # object scene.objects.link(new_obj) # place in active scene new_obj.select = True # set as selected scene.objects.active = new_obj # set as active # set bezierhandles setBezierHandles(new_obj) return new_obj #based on animation_rotobezier.py def keyframeBezier(Obj, frame): Data = Obj.data for Spline in Data.splines: for CV in Spline.bezier_points: CV.keyframe_insert(data_path='co', frame = frame) CV.keyframe_insert(data_path='handle_left', frame = frame) CV.keyframe_insert(data_path='handle_right', frame = frame) # ------------- SCRIPT START tail_length = 60 # length of the spline in frames object = bpy.context.object path = object.motion_path frame_start = path.frame_start frame_end = path.frame_end path_length = path.length # --- create the Bezier curve trail = createCurve(tail_length,object.name+" motion_trail") mark_time() # start measuring elapsed time # --- key frame the curve at every frame in the motion path for i in range(tail_length-1,path_length): # motion path index print("Point "+str(i)) for j in range(tail_length): # curve point index trail.data.splines[0].bezier_points[j].co = path.points[(i-tail_length)+j].co # set the coordinates of the motion tail to the corresponding point on the motion path # keyframe it keyframeBezier(trail, frame_start+i) mark_time() print('The motion trail keyframing took {: 5g} seconds'.format(get_last_time()))
Bret Battey blogging sundry ideas, favorable events, works in progress, and miscellaneous solutions in digital music and video-music research and creation. I see this as a subsidiary of my web site, BatHatMedia.com.
Tuesday, February 16, 2016
Blender Script for creating animated motion-trail ribbon
Given an object for which a motion-path has been generated, will create a Beziér-spline ribbon that follows the motion of the object for a given tail length (designated in frames).
Subscribe to:
Post Comments (Atom)
This works perfectly up to 2.79, but not in 2.8. I'm still trying to figure out how to make it work properly, any ideas?
ReplyDeleteUnfortunately, no! I have not touched this (or even Blender much) since I completed the project I made this for.
ReplyDelete