# render multiple frames using a for loop, stack overflow after one image. Is there anyway to avoid stacking while rendering?

I am trying to move the camera around an interested object, and then render frames along the camera trajectory. The trajectory part worked well, but when I tried to render frames and save the depth map from a node (see the attached code), I have overstack issue. Is there anyway to solve the problem?

PS: I am a newbie in Blender, so I don't even know if I did it completely wrong in the very beginning. Any suggestion would be appreciated, thanks.

SCENE_NAME='123'
viewCount = 0
stepSize=12
scene = bpy.context.scene
stickGroup = list(i for i in bpy.data.objects if 'stick' in i.name)
camera = scene.objects['Camera']

def getPath():
myPath = savePathConfigure();
myPath.gtSaveDIR =
os.path.join(os.path.dirname(bpy.data.filepath), 'Dataset/'+SCENE_NAME+'/')
myPath.outRGBpath = os.path.join(myPath.gtSaveDIR, 'RGB/')
myPath.outDepPath = os.path.join(myPath.gtSaveDIR, 'Depth/')

if myPath.pathConfig()=={'FINISHED'}:
print(myPath.gtSaveDIR)

return myPath

class getRGBHandler:
def __init__(self, path_in):
self.base_path = path_in

@persistent
def __call__(self, scene):
bpy.context.scene.node_tree.nodes['File Output'].base_path = self.base_path
bpy.ops.render.render(write_still=True)

class getDepthHandler:
def __init__(self, path_in):
self.base_path = path_in

@persistent
def __call__(self, scene):
pixels = bpy.data.images['Viewer Node'].pixels
np.save(os.path.join(self.base_path, str(viewCount)+'.npy'), pixels)

def moveCamHandler(scene):
cameraOrigin = camera.location
newTheta = stepSize* (math.pi/180)  # rotate the camera completely around the focused point
# This rotating is in global coordinate system
rotationMatrix =np.array([  [math.cos(newTheta), -math.sin(newTheta), 0.],\
[math.sin(newTheta), math.cos(newTheta), 0.],\
[0., 0., 1.]  ])
goal = Vector(np.dot(cameraOrigin, rotationMatrix))
gaze = Vector(np.array([0,0,0], dtype=np.double))  # look at the origin
camera.location = goal

gazeRay = gaze - camera.location
camEulerAng = gazeRay.to_track_quat('-Z', 'Y').to_euler()
camera.rotation_euler = camEulerAng

def callMyHandlers():
saveDIR =getPath()
myGT = groundTruthStruct(whatScene= SCENE_NAME, objectGroup = stickGroup)

bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(getRGBHandler(saveDIR.outRGBpath))
bpy.app.handlers.render_post.append(getDepthHandler(saveDIR.outDepPath))

# Main loop
callMyHandlers()

for i in range(30):
scene.frame_set(i*stepSize+1)
viewCount+=1
scn.render.filepath = '/outputDIR/'+str(viewCount)+'.png'
bpy.ops.render.render(write_still=True,use_viewport=True)
scene.update()


I have a node tree like this (see image), what I want is the depth value. Directly adding a File Out Node will lose some accuracy (double -> int16).

Thanks.

The frame_change_pre handler is the method getRGBHandler.__call__, which is making a call to bpy.ops.render.render. The render call, however, in its turn calls frame_change_pre handler triggering a call to getRGBHandler.__call__, which again calls render. This is causing an infinite recursion, resulting in stack overflow.
It may not be a good idea to call render from within the frame_change_pre handler. You might want to try and move it to the main code. I didn't quite get the logic, so I am unable to suggest where it should be. But am tempted to observe: main is already calling render, is there a need for another render in the handler?
mathutils.Euler([0, 0, newTheta], 'XYZ').to_matrix(). And newTheta can be caluclated only once, since it depends solely on stepSize (math.radians(stepSize))? mathutils.Vector has methods for dot and cross products.