Closed f588ca1e-f96a-4dea-804d-c55eab873dab closed 4 years ago
Description changed:
Changed keywords from none to threejs camera persist
I wonder if it would be better to actually change default behaviour to be persistent. If there is an easy to discover way to reset the camera, I don't see any drawbacks.
Dependencies: #28672
Joshua, while I certainly appreciate all of the effort you put into this feature, there is a much simpler approach. #28672 already makes the camera viewpoint available on the clipboard. This can simply be passed into the plot through a new keyword named viewpoint
which will keep the camera at that set position on regeneration. That's how I'm setting the camera in my own JavaScript library that embeds virtually the same viewer in web pages.
While this approach requires a manual step, it avoids the overhead of local storage and the dependence you note on the future structure of Jupyter notebooks. As soon as #28672 is merged, then either you or I can add the new keyword. Please be aware that I handle aspect multipliers a bit differently in my library. I left them more explicit in this viewer so that they don't get forgotten.
Hi Paul!
Yes, a viewpoint
option does seem like it would solve the use case I mentioned (keeping a fixed camera with interact
).
Another reason I implemented this feature is because I've been experimenting with adding support for three.js-based animation to Sage: discrete keyframes like the existing animate
function at present, with the goal of adding some interpolation or image morphing between the frames later on. I'd like to be able to persist the playback state of the animation as well, preferably tied to the same persist
option.
Laying the foundation with a persistent camera first seemed the way to go. With the animation state changing on its own every frame, a manual approach similar to viewpoint
would be more cumbersome.
I'm open to scrapping persistence for the camera and re-introducing it for the animation. Of course, that presumes that the animation stuff gets accepted later on; there may be better alternatives that I'm unaware of. Or perhaps a hybrid approach: if a viewpoint
has been provided, then ignore persist
as regards the initial camera state?
Thanks for taking a look at this. :)
Replying to @novoselt:
I wonder if it would be better to actually change default behaviour to be persistent. If there is an easy to discover way to reset the camera, I don't see any drawbacks.
I don't speed a lot of time in the Jupyter notebook, preferring the console, except recently in order to use interact
, so I wasn't sure what the commons workflows in it might be and whether this change could interfere with them. So, I opted for the cautious route.
Joshua, just took a look at your animation branch on GitLab. Looks like you're deep into it! Are there any active examples online? And don't forget that Three.js has an animation system already, which you don't appear to be using.
Although keyframes are one way to approach the topic, keep in mind that we can manipulate data directly using JavaScript. We haven't yet added a basic spin animation, but that's easily done by updating the rotation parameters of the object. If the object is to be moved along a trajectory, we could pass in a line or function describing the location of its center over time. For more complex alterations, we could pass in a function describing the locations of all vertices over time. Lots of possibilities without thinking in terms of saving a movie frame by frame.
Please also try not to add anything to the viewer that will be dependent on a given environment, in this case a Jupyter notebook. I'd rather the viewer be as portable as possible.
Paul, I gathered the examples I've put in my documentation so far and thrown them up on GitHub pages:
https://jcamp0x2a.github.io/threejs-animation-example/
I opted not to use Three.js's animation system since I wanted to support multiple "times", one per variable being animated. Three.js would allow me to use multiple mixers to blend linearly between several sets of keyframes, but that wouldn't be appropriate for plotting a function f(x,y,...) that's not some linear combination c1f1(x)+c2f2(y)+...
Agreed that keyframes aren't necessarily the best approach, but it has two enourmous benefits:
It was quite easy to work into the existing Graphics3d system. No need to, for example, go into the implicit_plot3d code and modify the algorithm (marching cubes I think) to produce a mesh suitable for morphing. Nor worrying about topological changes like holes forming or components pinching off. I love math, but I'm a software developer, not a mathematician! So that kind of stuff is beyond my paygrade. :) Instead, I just plot the keyframes, sum them all up into a single Graphics3d object, attach some metadata as to when each object should be visible, and voila!: animation.
It's very general: it can animate a rigidbody moving along a trajectory up to a vector field representing fluid flow with the same amount of code on both the back- and front-ends.
Perhaps I should create a new ticket for the animation to continue the conversation there? I'll hold off on the persistence stuff then if it's not desired.
Thanks!
Joshua, the animations are great! Definitely new ticket for that. Will study the code more in the near future.
Rather than inspecting the notebook for a unique ID, why not generate a random large number? That's what I've done in my library and haven't had any problems yet, even with pages with lots of embedded content.
Changed dependencies from #28672 to #28672 #29250
Batch modifying tickets that will likely not be ready for 9.1, based on a review of the ticket title, branch/review status, and last modification date.
Changed branch from u/galois/mrs/41/threejs-persist-camera to u/paulmasson/mrs/41/threejs-persist-camera
Changed author from Joshua Campbell to Paul Masson
Joshua, here at long last is the viewpoint
option we discussed above. Use the 'Get Viewpoint' menu option to obtain the value that is passed as a string in the graphic object.
New commits:
66d3471 | Add viewpoint option |
Hi Paul, I've verified that setting the viewpoint
option to a string containing the output of Get Viewpoint correctly re-creates that camera orientation in the new plot.
I'm wary of passing structured data like this as a string parameter, though. It works fine for the Get Viewpoint use case, but one may imagine wanting to set the viewpoint to a specific axis-angle or have the axis-angle computed in some way. In the former case a typo (like forgetting a comma) would produce a blank plot instead of a syntax error, and in the latter case you'd have to take the extra step of building up a string.
As Get Viewpoint is currently implemented, we have to surround its output with something to avoid a syntax error, but why not parentheses instead of quotes? ([x,y,z],angle)
opposed to "[x,y,z],angle"
. That way Python can validate the syntax, and we can validate the types/contents.
While testing, I forgot to surround the output with quotes a... non-zero... number of times. Ideally, and I apologize for not thinking of this when reviewing the code that introduced it, Get Viewpoint would do the surrounding for us to avoid this perhaps not uncommon occurrence among some subset of users ;)
Also, do we want the zoom / camera distance to be included as well? Perhaps by letting the length of the axis vector represent the zoom/distance?
Many thanks!
The Get Viewpoint feature was added to support how TikZ interfaces with Sage: see this tutorial for more information. See also the general rotate command in the base class for 3D objects. Adding anything else to the string here might require changes to other interfaces, so I don't think we should do that.
I agree that requiring a structured string for input is not ideal, and I like the idea of using parentheses or square brackets. That is a better way to structure the input for later handling and either can be used in Python. I'll put together a version for testing.
Branch pushed to git repo; I updated commit sha1. New commits:
37b0c87 | Update viewpoint option |
Here's a more stable version, where viewpoint
must be a list of the form [[x,y,z],angle] or it will raise a warning. Couple questions:
1) Lots of Sage inputs are allowed to be either lists or tuples, but need to be converted to lists for the JSONing lines. Do we want to allow tuples here?
2) The angle value for TikZ is in degrees, while the angle for the base-class rotate()
is in radians. Not sure how to reconcile the two. Maybe just document what's happening?
Branch pushed to git repo; I updated commit sha1. New commits:
f96ccdc | Further refine viewpoint option |
Added support for tuples and clarified angle variable in documentation.
Let's add the zoom feature once we get some feedback from users.
I checked that the viewpoint is still set correctly, that lists/tuples are both supported, and that a helpful warning message is displayed if the viewpoint
option is not of the correct form.
One very minor note: the documentation still states "string of the form...". Otherwise looks good and can give positive review.
Thank you for adding this option. Will make using interact
in notebooks with three.js plots much more convenient.
Branch pushed to git repo; I updated commit sha1. New commits:
850c59a | Update documentation |
Branch pushed to git repo; I updated commit sha1. New commits:
3b7fc0c | Update documentation |
Replying to @jcamp0x2a:
One very minor note: the documentation still states "string of the form...". Otherwise looks good and can give positive review.
Done!
Thanks!
Reviewer: Joshua Campbell
These have been merged into 9.2.beta4
Joshua Campbell (@jcamp0x2a) opened a merge request at https://gitlab.com/sagemath/sage/-/merge_requests/41:
Depends on #28672 Depends on #29250
CC: @paulmasson
Component: graphics
Keywords: threejs camera persist
Author: Paul Masson
Branch/Commit: u/paulmasson/mrs/41/threejs-persist-camera @
3b7fc0c
Reviewer: Joshua Campbell
Issue created by migration from https://trac.sagemath.org/ticket/29192