I'm having an application where I want to draw a 3-dimensional track that extends with every frame. Something like this here:
This is based on Blender 3.1.2, btw.
From the screenshot it might appear that I did achieve what I wanted. However, there are some issues....
Essentially, this (yellow) track is based on a path with a bezier-circle as bevel. So far I did this in a script where I create a new path with each new frame within a frame-change handler. One issue here is that the complete path needs to be re-created with every frame, and considering that we are talking about several 10000 track points, this is taking longer and longer the further the animation goes. But anyway, it is working essentially. However, what I did is working only during editing. When I render the animation, Blender is crashing with a segmentation fault after a couple of frames.
So how did I do this?
My frame-change handler is looking like this:
def draw_track(): current_frame = bpy.context.scene.frame_current
# Delete the old track path
old_object = bpy.context.scene.objects.get('TrackPath')
if old_object:
bpy.data.objects.remove(old_object)
make a new curve
crv = bpy.data.curves.new('crv', 'CURVE')
crv.dimensions = '3D'
make a new spline in that curve
spline = crv.splines.new(type='NURBS')
a spline point for each point
spline.points.add(current_frame)
for i in range(current_frame+1):
<determine x, y, z>
spline.points[i].co = [x,y,z] + [1.0]
make a new object with the curve
obj = bpy.data.objects.new('TrackPath', crv)
bpy.context.scene.collection.objects.link(obj)
bpy.data.objects['TrackPath'].data.bevel_object = bpy.data.objects["TrackCircle"]
bpy.data.objects['TrackPath'].data.bevel_mode = 'OBJECT'
bpy.data.objects['TrackPath'].data.use_fill_caps = True
material = bpy.data.materials["TrackMaterial"]
bpy.data.objects['TrackPath'].data.materials.append(material)
So essentially, the object "TrackPath" is being removed and recreated for each frame. There is also an object "TrackCircle" which is persistent and associated with the "TrackPath" object. Same for "TrackMaterial".
As pointed out earlier, this method is working fine during editing. I can click around in the time line and I see what I expect to see. However, Blender crashes during rendering the animation.
One thing that might be an issue here is that the created curve appears not to be deleted with the deletion of the old TrackPath. I'm seeing this in the scene object browser of Blender. The script is creating a new curve with the name "crv". However, what I see in the browser is something like "crv.10" and counting up. Blender does this when one is using a name that is already present.
I'm not sure whether this is the reason for the crash of Blender during rendering the animation. Unfortunately, I was not yet able to delete the created curve object. So first question is: How can I delete it?
Another point is my general procedure. It appears to be not a very good practice to delete the objects and recreate them over and over again. It seems to be better to have a persistent TrackPath object with a more or less persistent curve where points are added and removed on demand depending on the current frame number. In some sort of pseudo-code something like:
<if there are too less points in the curve, add the according points> <if there are too much points in the curve, delete the according points>
Unfortunately, I was not able yet to figure out how I can do this.
Thanks for any hints!
Mario
An update on that matter: I found another potentially better way to deal with that. It would assume that the path resp. curve is statically present. In fact, it could be created by a script at the beginning. This appears to work as planned. Now, in the Object Data Properties of a path there is a "Start & End Mapping". The allows to cut or better said ignore parts of the path at the beginning or the end. In fact, only the end-cut is needed here. In theory, it would be sufficient to interpolate the end-mapping linearly from a value of 0.0 at the very first frame to a value of 1.0 at the very last frame. It is important to switch the interpolation to linear here, because Blender uses a non-linear interpolation by default when setting keyframes.
So, this would be some really nice way to handle this task. However, obviously it is too nice to be true.... There is some issue that the path is falling short here. For instance, when I set the current frame to half of the total frame count and set the end-mapping to 0.5, one would suppose that the track ends exactly after half of its points. However, it does not. It is falling short visibly. Things change slightly when I change these other mapping settings between "Resolution", "Segments", and "Spline", but there is not really a constant behavior. Depending on the track situation and position, things are sometimes getting more worse and sometimes less worse. However, according to the Blender documentation the setting "Resolution" appears to be the only correct one anyway for that use.
So what can be wrong here now? I'm having some suspicion here that Blender does collapse curve points with more or less the same coordinates. Might this be the case? If yes, can it be avoided?




