Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animate different actors one at the time #30

Closed
vianamp opened this issue Jun 17, 2019 · 10 comments
Closed

Animate different actors one at the time #30

vianamp opened this issue Jun 17, 2019 · 10 comments

Comments

@vianamp
Copy link

vianamp commented Jun 17, 2019

Hi guys. First of all, thank you so much for developing vtkPlotter. I have been a VTK user (C++ and Python) for many years now and I found amazing what can be achieved using vtkPlotter with only a few lines of code.

Here is what I am working on. I have a time sequence of an object (closed mesh) with 32 timepoints. I want to animate the movement and deformation of this object in time. Usually I would export each timepoint as a vtk polydata file, open the sequence of files in paraview and play it. However, I want to do that in vtkPlotter if possible. The code bellow is my very first attempt -- no animation so far. Could you guys help me to improve it? I can help to turn this into an official example if you think it might be of interest of others. Thanks a lot,

n = 8
vp = Plotter()
coo = np.random.rand(n*12).reshape(n,12)
for i in range(n):
    u = coo[i,3:6]
    v = coo[i,6:9]
    q = coo[i,9:12]
    ell = Ellipsoid(pos=(2.5*coo[i,0], 2.5*coo[i,1], 2.5*coo[i,2]), axis1=u, axis2=v, axis3=q)
    scals = [i] * ell.N()
    ell.pointColors(scals, vmin=0, vmax=n)
    ell.VisibilityOff()
    vp += ell
vp.show()
@marcomusy
Copy link
Owner

Hi @vianamp
thanks for your interest!
Actually the show() command should be inside the loop. Check out for example this:

from vtkplotter import *
import numpy as np

vp = Plotter(interactive=False)
coo = np.random.rand(32*12).reshape(32,12)

for i in range(len(coo)):
    u = coo[i,3:6]
    v = coo[i,6:9]
    q = coo[i,9:12]
    ell = Ellipsoid(pos=(2.5*coo[i,0], 2.5*coo[i,1], 2.5*coo[i,2]),
                    axis1=u, axis2=v, axis3=q)
    scals = [i] * ell.N()
    ell.pointColors(scals, vmin=0, vmax=31)
    vp += ell
    vp.show()

interactive()

ezgif com-optimize

Let me know if you need more help. Also, you can find more examples of animations in example/simulations directory which may fit your need.

@vianamp
Copy link
Author

vianamp commented Jun 17, 2019

Thanks for quick reply. What if I need only one timepoint to be shown at the time? And also to keep the bounding box fixed at the largest size that fits all the objects?

@vianamp
Copy link
Author

vianamp commented Jun 17, 2019

Also, I got this error when I tried to run your code on a jupyter notebook:

AttributeError                            Traceback (most recent call last)
<ipython-input-12-4b069e1c07cd> in <module>()
     13     vp.show()
     14 
---> 15 interactive()

~/anaconda3/envs/qcb/lib/python3.6/site-packages/vtkplotter/plotter.py in interactive()
    259     if settings.plotter_instance:
    260         if hasattr(settings.plotter_instance, 'interactor'):
--> 261             settings.plotter_instance.interactor.Start()
    262     return settings.plotter_instance
    263 

AttributeError: 'NoneType' object has no attribute 'Start'

@marcomusy
Copy link
Owner

There are 2 ways of doing it:

  • either you create an invisible box that contains the object that you want to create afterwards or
  • render the scene once outside the loop with e.g. vp.show(world, ell, resetcam=False)
from vtkplotter import *
import numpy as np

vp = Plotter(interactive=False)
coo = np.random.rand(32*12).reshape(32,12)
world = Box([1,1,1], 5,5,5).wireframe().alpha(0) ##########

for i in range(len(coo)):
    u = coo[i,3:6]
    v = coo[i,6:9]
    q = coo[i,9:12]
    ell = Ellipsoid(pos=(2.5*coo[i,0], 2.5*coo[i,1], 2.5*coo[i,2]),
                    axis1=u, axis2=v, axis3=q)
    scals = [i] * ell.N()
    ell.pointColors(scals, vmin=0, vmax=31)
    vp.show(world, ell)
    
interactive()

About the jupyter thing indeed this a current limitation (or ... bug) due to how the K3D backend works...
One needs to collect the object returned by show() and then just expose it outside the loop...

image

@vianamp
Copy link
Author

vianamp commented Jun 17, 2019

I see what you mean. My final code looks like this:

np.random.seed(1234)
n = 8
vp = Plotter(interactive=False)
coo = np.random.rand(n*12).reshape(n,12)
world = Box([1,1,1], 5,5,5).wireframe().alpha(0)
for i in range(n):
    u = coo[i,3:6]
    v = coo[i,6:9]
    q = coo[i,9:12]
    ell = Ellipsoid(pos=(2.5*coo[i,0], 2.5*coo[i,1], 2.5*coo[i,2]), axis1=u, axis2=v, axis3=q)
    scals = [i] * ell.N()
    ell.pointColors(scals, vmin=0, vmax=n)
    vp += ell
    plt = vp.show(world, ell, resetcam=False)
plt

However, I don't actually see the animation. Only the last timepoint is shown.

@marcomusy
Copy link
Owner

Yes.. the jupyter functionality is still experimental and at the moment is not working well with loops.
It' s on my to-do list..
If you need to work in notebooks you still have the option of setting:

from vtkplotter import *
embedWindow(False)

then the normal vtk rendering window will pop up.

@vianamp vianamp closed this as completed Jun 17, 2019
@LogWell
Copy link

LogWell commented Oct 6, 2019

How to fix the viewing angle to the first frame. The object moves a little bit in the following gif.

Thanks~
@marcomusy

@marcomusy
Copy link
Owner

you can either add an invisible box:
vp += Box((1,1,1), length=5, width=5, height=5).wireframe().alpha(0)
or avoid resetting the camera later with
vp.show(resetcam=False)

in the ex. above, as the the object are added randomly, the first solution is probably the best.

@LogWell
Copy link

LogWell commented Jan 7, 2020

Hi, marcomusy~

How to add a description for each frame like: "frame: {}/{}.format(current, all)"?

If I set by txt = Text(...) with background, it seems to get slower and slower, if I use vp.clear(txt), there will be flashes.

@marcomusy
Copy link
Owner

@LogWell
thanks for spotting the problem, I'll investigate that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants