New issue 1279: Non-intuitive, undocumented methods for 3D volume rendering https://bitbucket.org/yt_analysis/yt/issues/1279/non-intuitive-undocumented-...
Scene's functionality on 3D volume rendering and camera rendering in 'perspective' lens mode is not well-documented for users.
## Two bugs:
In perspective lens mode, the typical use is moving the camera position by cam.set_camera_position([x,y,z]) and pointing the camera by cam.set_camera_focus([x,y,z]). Calling these functions automatically adjusts the lens viewpoint appropriately. However, functions like cam.roll(), cam.rotate() etc. currently change the viewpoint of the lens independently of camera position. How confusing! Also, cam.zoom() doesn't "zoom" the image as you'd expect.
When following the Volume Rendering example, it seems like modifying the colormap is performed by "source.tfh.set_bounds((3e-35, 5e-27))" (where source is a reference to the scene's main source) should update the scene rendering, but it isn't. On all but the first render, many more steps are involved (see below!)
## Action items:
(Easy) The volume rendering examples posted prominently on the yt website should include examples of how to update a scene, including changing colormap, camera angle, etc. for a perspective lens. Nathan has already written up an example such as this in response to my question to the yt-users list. (http://paste.yt-project.org/show/6823/)
(Harder) The scene.render() and scene.save() should know not to render the scene without updating the transfer function. Why should it take four steps?
#!python # This method works only for the first render, and is given in the Volume Renderer example source.tfh.set_bounds((3e-35, 5e-27)) ... sc.render()
#!python # This method is what actually works after the first render source.tfh.set_bounds((3e-35, 5e-27)) source.tfh.build_transfer_function() source.tfh.setup_default() source.transfer_function = source.tfh.tf ... sc.render()
Intuitively, it should take one or two steps:
#!python # Something like this is what I'm suggesting source.tfh.set_bounds((3e-35, 5e-27)) source.update() # for example, does all three steps above (and possibly more) ... sc.render()
(Harder) cam.roll(), cam.rotate(), etc. should change the camera position when the camera is in perspective mode, I believe, rather than the viewpoint. cam.zoom() should change the position, as well.
(Harder) The Camera and Lens documentation can be expanded to reflect the complexity of the problem, and clearly address which settings are relevant under which lenses. (e.g. the fact that set_width() doesn't do what you might think in perspective mode). The main user documentation page especially on Camera and Lenses (http://yt-project.org/doc/visualizing/volume_rendering.html#camera-lenses) is where I'd expect to find a clear explanation of the various types of lenses with good usage examples on how to move around the camera, aim it places, zoom in, etc. in each case.
The rest of this bug report contains the contextual description of problem from emails on yt-users that led to this bug report:
While working through examples, I hit a roadblock, and I've had some difficulty finding good documentation on the what the "Scene.save()" function actually does; specifically, why it does different things on the first and second call. The first example in the user tutorial page for 3D volume rendering (http://yt-project.org/doc/visualizing/volume_rendering.html) looks something like this:
#!python ... sc = yt.create_scene(ds, lens_type='perspective') ... source = sc source.tfh.set_bounds((3e-31, 5e-27)) ... sc.save('rendering.png', sigma_clip=6.0)
And, voila, volume rendering saved to png.
However, if I naively continue the script to re-render with new settings:
#!python source.tfh.set_bounds((3e-35, 5e-27)) sc.camera.zoom(2.0) sc.save('rendering2.png', sigma_clip=6.0)
I find that none of my new settings are reflected in "rendering2.png" -- it's just a duplicate of "rendering.png"! But if I start again from scratch with a new scene, the settings take hold. This leaves me (a new user) scratching my head.
So I posed the question to yt-users: Once you've created and saved a scene once, how do you change scene settings like colormap and camera angle?
Nathan Golbaum kindly responded with the following:
So this is really two issues.
The first, is that the camera.zoom() function doesn't really zoom in on the image, instead it decreases the "width" the volume rendering region by the zoom factor. This makes a lot of sense for plane-parallel volume renderings (the default), but not so much for perspective lenses as you saw. For a perspective lens you should instead reposition the camera to be closer to the focus to get the same effect.
Next, you also saw that manipulating the TransferFunctionHelper object (source.tfh) after you've already done a volume rendering doesn't update the transfer function. That's because the TransferFunctionHelper object is only used to generate the transfer function (source.transfer_function) if it isn't set yet. If it's already set, it reuses it. So in your example the first time you called save(), the VolumeSource saw that no one had manually created a transfer function, and used the TransferFunctionHelper object to build one. Then, when you asked it for the second rendering, it just reused the same one because right now the VolumeSource doesn't track if the TransferFunctionHelper has been updated. To do what you mean, you need to manually set the transfer function to be the one generated by the TransferFunctionHelper:
source.tfh.build_transfer_function() source.tfh.setup_default() source.transfer_function = source.tfh.tf
After manipulating source.tfh.
Using as an example the script from the docs, here's how to make the second image come out as you would expect for the perspective lens:
Which makes these two images:
I think we could probably do a better job of detecting that the TransferFunctionHelper has been manipulated and avoid this confusion, if you'd like I invite you to open an issue about this on our issue tracker. One might also argue that the zoom function should adjust the camera position for perspective lenses.
Sorry the volume renderer isn't totally intuitive for this use case. I did some work before the yt 3.3.1 release to improve things, but it's still definitely not perfect. I think there's a lot of power there but it also really needs some love from someone who is willing to think about corner cases and interactive workflows.