0
$\begingroup$

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). enter image description here

Thanks.

$\endgroup$
0
$\begingroup$

This is just a guess, I have not verified this since I am not able to run the code myself without the objects referred from it.

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?

Lastly, (in case you are unaware of this) there's an easier way to get the rotation matrix, namely:
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.

$\endgroup$
  • $\begingroup$ Thank you very much! Everything works smoothly after I moved all the render commands in the main loop and delete repeated one. It turns out I was trapped in those handlers, which caused me a lot of troubles. Appreciate again. $\endgroup$ – Leonardo.Li Nov 20 '18 at 12:52
  • $\begingroup$ You are welcome :) Glad that I could be of help. $\endgroup$ – Blender Dadaist Nov 20 '18 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.