No trajectory 3D placeholder
Description of work
- Create a VTK placeholder animation or object that will be shown in the trajectory 3D view when no trajectory is selected.
- The first idea was to have a rotating ball (similar to the disco ball logo of MDANSE_GUI) shown when no trajectory is open.
- The important aspect of this work will be to make sure that the view can be switched smoothly to a trajectory view and all the objects from the placeholder animation are cleaned up correctly.
With enough effort, I still managed to create some technical issues:
- At the moment, everything works fine if we have a single trajectory and delete it. However, if I load several trajectories, pick one and delete it, the perspective changes permanently. Here is an example where I load 3 trajectories and pick the first one. Initially, it looks like this:
Then I delete some other trajectory. The placeholder is shown then. (Maybe it should only be shown when there are no trajectories left?). If I go back to the first trajectory, it looks like this:
It looks like the projection gets reset. If the 3D model requires the parallel projection to be switched off, I would still like it go back to the previous settings once I pick a trajectory.
- Also, if the placeholder is present, the 'Toggle projection' button makes it disappear.
Now the subjective part of tuning the artistic effect: Yesterday, I asked a few people to look at the placeholder animation and tell me how they feel about it.
Overall, I think it would be good to tone it down a little:
- On my machine, I was more comfortable with
self.rotation_speed = 1instead of 10. - Would you consider making the objects smaller and less central to the screen? I tried adding a bit of translation and scaling like this:
def rotate_3D_model_actor(self, angle):
"""Rotates the given actor by the specified angle around axis."""
# different axis rotation for each actor in the assembly
for i, actor in enumerate(self._actors.GetParts()):
individual_transform = vtk.vtkTransform()
individual_transform.Translate(0.0, 0.5, 0.5)
individual_transform.Scale(0.5, 0.5, 0.5)
...
which made it appear like this on my screen:
One way to address the problem with the projection being changed is:
- In Controls.py L337 in toggle_projection(), replace
self._viewer.update_renderer()withself._viewer._iren.Render()This will stop the placeholder from disappearing when you click 'Toggle projection' in the GUI. - In View3D.py, L58 in update_panel() - can you remove
self._viewer._camera.SetParallelProjection(0)altogether? It does not seem to change all that much, and removing it would keep the projection set to the value last chosen by the user.
It does not really bother me that we can move the camera around the placeholder, or zoom in and out of it. If we wanted it to be static, we could have just rendered a short video and played it in a loop. However, if we wanted to stop specifically the zoom, I think it could be done by temporarily changing one of the methods of QVTKRendedWindowInteractor.
In the MolecularViewer.__init__ method, we could add
self._backup_wheel_method = copy.copy(self._iren.wheelEvent)
self._dummy_method = copy.copy(dummy_method)
to have the original method and a blank one both stored for later. Then, whenever we load the placeholder, we set
self._iren.wheelEvent = self._dummy_method
and when a trajectory is picked, we execute
self._iren.wheelEvent = self._backup_wheel_method
This would work. Is is a good/acceptable solution?
I mean, there's no real need for a manual backup. The class instance will still have a copy you can recover.
self._iren.wheel_method = type(self._iren).wheel_method
Or similar
On 5 Dec 2025 10:55, Maciej Bartkowiak @.***> wrote: [https://avatars.githubusercontent.com/u/108934199?s=20&v=4]MBartkowiakSTFC left a comment (ISISNeutronMuon/MDANSE#1067)https://github.com/ISISNeutronMuon/MDANSE/pull/1067#issuecomment-3616368750
It does not really bother me that we can move the camera around the placeholder, or zoom in and out of it. If we wanted it to be static, we could have just rendered a short video and played it in a loop. However, if we wanted to stop specifically the zoom, I think it could be done by temporarily changing one of the methods of QVTKRendedWindowInteractor.
In the MolecularViewer.init method, we could add
self._backup_wheel_method = copy.copy(self._iren.wheelEvent)
self._dummy_method = copy.copy(dummy_method)
to have the original method and a blank one both stored for later. Then, whenever we load the placeholder, we set self._iren.wheelEvent = self._dummy_method and when a trajectory is picked, we execute self._iren.wheelEvent = self._backup_wheel_method
This would work. Is is a good/acceptable solution?
— Reply to this email directly, view it on GitHubhttps://github.com/ISISNeutronMuon/MDANSE/pull/1067#issuecomment-3616368750, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ALDQM6F4PRD7YOTEX4VCJVT4AFQDTAVCNFSM6AAAAACMO2P74CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTMMJWGM3DQNZVGA. You are receiving this because your review was requested.Message ID: @.***>
I mean, there's no real need for a manual backup. The class instance will still have a copy you can recover.
self._iren.wheel_method = type(self._iren).wheel_methodOr similar On 5 Dec 2025 10:55, Maciej Bartkowiak @.> wrote: [https://avatars.githubusercontent.com/u/108934199?s=20&v=4]MBartkowiakSTFC left a comment (ISISNeutronMuon/MDANSE#1067)<#1067 (comment)> It does not really bother me that we can move the camera around the placeholder, or zoom in and out of it. If we wanted it to be static, we could have just rendered a short video and played it in a loop. However, if we wanted to stop specifically the zoom, I think it could be done by temporarily changing one of the methods of QVTKRendedWindowInteractor. In the MolecularViewer.init method, we could add self._backup_wheel_method = copy.copy(self._iren.wheelEvent) self._dummy_method = copy.copy(dummy_method) to have the original method and a blank one both stored for later. Then, whenever we load the placeholder, we set self._iren.wheelEvent = self._dummy_method and when a trajectory is picked, we execute self._iren.wheelEvent = self._backup_wheel_method This would work. Is is a good/acceptable solution? — Reply to this email directly, view it on GitHub<#1067 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ALDQM6F4PRD7YOTEX4VCJVT4AFQDTAVCNFSM6AAAAACMO2P74CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTMMJWGM3DQNZVGA. You are receiving this because your review was requested.Message ID: @.>
Hi Jacob. I went wit Maciej's suggestion. When I tried your suggestion, I got this error: TypeError: QVTKRenderWindowInteractor.wheelEvent() missing 1 required positional argument: 'ev' From my understanding wheelEvent requires two argument (self, ev)
I adjusted the pyproject.toml file to make sure that:
- The 3D model .stl files get copied correctly when doing a normal
pip install mdanse_guiin a fresh virtual environment. - The VTK version gets updated if an old one is already present (since
renderer.ResetCameraScreenSpace(0.4)was not implemented in older versions of VTK).
Looks good, one thing could we make the yellow sphere and ring green so it matches the MDANSE logo?
Also, the logo disappears when I click the visual object checkboxes the placeholder disappears.
Thanks for pointing it out. I think I fixed the problem with the checkboxes.
As for the colour scheme, I tried to copy the colours from the MDANSE icon within 1% precision this time.
Looks good just one last thing related to the previous issue. The placeholder also disappears when you change the atom size scaling.