bwoodsend / vtkplotlib

VTK (C++ 3D graphics library) wrapped into an easy to use 3D equivalent of matplotlib
MIT License
40 stars 6 forks source link

"Ghost" artifact of other open tabs during screenshot - Ubuntu 18.04 #1

Closed aditya-krish closed 4 years ago

aditya-krish commented 4 years ago

I am using Ubuntu 18.04 to run an application, which takes screenshots of a mesh. I am using Nvidia Quadro P5000 GPU with nvidia 435 proprietary driver (I also tried with with Nouveau driver which gives the same issue). 31535222_13_1 31535222_13_2

Have you encountered this before, or aware of what causes the problem? The application runs fine on windows servers, and has been tested extensively, but gives this problem in Ubuntu.

bwoodsend commented 4 years ago

No, I've never seen that before.

Could you elaborate a bit? When you say screenshot, do you mean vtkplotlib.save_fig() or the PrtSC button on your keyboard? Am I right in saying it's the black ring-shaped thing you want to screenshot but the little windows in the bottom left that shouldn't be there?

Also can you post your VTK version (using pip show vtk or conda info vtk)?

aditya-krish commented 4 years ago

Yeah I am using save_fig(). I am aware that it uses vtk.vtkWindowToImageFilter() and I guess that has some OS specific code? Yeah the black ring is what I want but I am getting those extra windows, the pixels parameter is set to [1800,1800] if that helps.

On Sat, 7 Mar, 2020, 23:50 bwoodsend, notifications@github.com wrote:

No, I've never seen that before.

Could you elaborate a bit? When you say screenshot, do you mean vtkplotlib.save_fig() or the PrtSC button on your keyboard? Am I right in saying it's the black ring-shaped thing you want to screenshot but the little windows in the bottom left that shouldn't be there?

Also can you post your VTK version (using pip show vtk or conda info vtk)?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bwoodsend/vtkplotlib/issues/1?email_source=notifications&email_token=ANJMUEBISYUKND6EKEHMCJTRGKGARA5CNFSM4LADUBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOEB6UA#issuecomment-596123472, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANJMUED2JSGWZ7ORQMARHATRGKGARANCNFSM4LADUBBA .

bwoodsend commented 4 years ago

I hate to think what a lot of these vtk classes get up to underneath. I've just tried on Ubuntu 19.10 and that's all working normally. I'd like to do some tests but firstly does it change if you change the pixels parameter or plot something different (such as vpl.quick_test_plot())?

aditya-krish commented 4 years ago

You can see the windows on the image, those "ghost" windows are all 300x300 in size, changing pixel size still brings ghost windows but they are always 300x300. So if the pixels is set to [300,300] then entire image will be one ghost window and so on. Normal plotting and showing works fine, only screenshot_fig and save_fig are giving trouble. When the screenshot_fig is running, try constantly changing tabs between Firefox and activities tab to reproduce the error. You might have to give a pause before the screenshot_fig to make this tab change possible before screenshot is taken, like putting this block of code before screenshot_fig:

import time since = time.time() while time.time() - since < 2: pass

On Sun, Mar 8, 2020 at 12:11 AM bwoodsend notifications@github.com wrote:

I hate to think what a lot of these vtk classes get up to underneath. I've just tried on Ubuntu 19.10 and that's all working normally. I'd like to do some tests but firstly does it change if you change the pixels parameter or plot something different (such as vpl.quick_test_plot())?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bwoodsend/vtkplotlib/issues/1?email_source=notifications&email_token=ANJMUEH5YMYRUYNOTCMIOEDRGKIMVA5CNFSM4LADUBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOECPBI#issuecomment-596125573, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANJMUEFWGHY3ATU5XIWNYVTRGKIMVANCNFSM4LADUBBA .

bwoodsend commented 4 years ago

OK, I've tried what you said and I can't reproduce it at all. I noticed that screenshot_fig() doesn't call vtkWindowToImageFilter.Modified() which I think it aught to and there is also off screen rendering to play with. I've done a stripped down example for you to test. Could you give it a run for me please?

import vtkplotlib as vpl
import vtkplotlib.image_io
import matplotlib.pylab as plt
import vtk
import time

fig = vpl.figure()
vpl.quick_test_plot()

# Try turning this one on and off and see if it changes anything.
#fig.renWin.SetOffScreenRendering(True)

since = time.time()
while time.time() - since < 2:
    pass

fig.connect()
fig.reset_camera()
fig.renWin.Render()

win2im_filter = vtk.vtkWindowToImageFilter()
win2im_filter.SetInput(fig.renWin)
win2im_filter.Modified()
win2im_filter.Update()

arr = vpl.image_io.vtkimagedata_to_array(win2im_filter.GetOutput())

win2im_filter.SetInput(None)
vpl.close(fig)

plt.imshow(arr)
plt.show()
aditya-krish commented 4 years ago

I tried two things, the above routine and screenshot_fig, for the same mesh. The above routine almost always seems to work, but screenshot_fig almost always does not work. I am attaching the images generated by both the routines, the one showing a tooth like structure is the above routine on the other hand the one showing the "ghost" artifact is using screenshot_fig.

On Mon, Mar 9, 2020 at 5:16 PM bwoodsend notifications@github.com wrote:

OK, I've tried what you said and I can't reproduce it at all. I noticed that screenshot_fig() doesn't call vtkWindowToImageFilter.Modified() which I think it aught to and there is also off screen rendering to play with. I've done a stripped down example for you to test. Could you give it a run for me please?

import vtkplotlib as vpl import vtkplotlib.image_io import matplotlib.pylab as plt import vtk import time

fig = vpl.figure() vpl.quick_test_plot()

Try turning this one on and off and see if it changes anything.

fig.renWin.SetOffScreenRendering(True)

since = time.time() while time.time() - since < 2: pass

fig.connect() fig.reset_camera() fig.renWin.Render()

win2im_filter = vtk.vtkWindowToImageFilter() win2im_filter.SetInput(fig.renWin) win2im_filter.Modified() win2im_filter.Update()

arr = vpl.image_io.vtkimagedata_to_array(win2im_filter.GetOutput())

win2im_filter.SetInput(None) vpl.close(fig)

plt.imshow(arr) plt.show()

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bwoodsend/vtkplotlib/issues/1?email_source=notifications&email_token=ANJMUEFKELF3B625LVZP4YLRGTJH7A5CNFSM4LADUBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOGYZHQ#issuecomment-596479134, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANJMUEAWXB4MYCUKJ4SE4UDRGTJH7ANCNFSM4LADUBBA .

aditya-krish commented 4 years ago

I also tried commenting out the w2im_filter.Modified() line, that still gives proper image, with no artifacts. So I guess it is not due to that line.

On Mon, Mar 9, 2020 at 6:50 PM Aditya K adityakrish122@gmail.com wrote:

I tried two things, the above routine and screenshot_fig, for the same mesh. The above routine almost always seems to work, but screenshot_fig almost always does not work. I am attaching the images generated by both the routines, the one showing a tooth like structure is the above routine on the other hand the one showing the "ghost" artifact is using screenshot_fig.

On Mon, Mar 9, 2020 at 5:16 PM bwoodsend notifications@github.com wrote:

OK, I've tried what you said and I can't reproduce it at all. I noticed that screenshot_fig() doesn't call vtkWindowToImageFilter.Modified() which I think it aught to and there is also off screen rendering to play with. I've done a stripped down example for you to test. Could you give it a run for me please?

import vtkplotlib as vpl import vtkplotlib.image_io import matplotlib.pylab as plt import vtk import time

fig = vpl.figure() vpl.quick_test_plot()

Try turning this one on and off and see if it changes anything.

fig.renWin.SetOffScreenRendering(True)

since = time.time() while time.time() - since < 2: pass

fig.connect() fig.reset_camera() fig.renWin.Render()

win2im_filter = vtk.vtkWindowToImageFilter() win2im_filter.SetInput(fig.renWin) win2im_filter.Modified() win2im_filter.Update()

arr = vpl.image_io.vtkimagedata_to_array(win2im_filter.GetOutput())

win2im_filter.SetInput(None) vpl.close(fig)

plt.imshow(arr) plt.show()

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bwoodsend/vtkplotlib/issues/1?email_source=notifications&email_token=ANJMUEFKELF3B625LVZP4YLRGTJH7A5CNFSM4LADUBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOGYZHQ#issuecomment-596479134, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANJMUEAWXB4MYCUKJ4SE4UDRGTJH7ANCNFSM4LADUBBA .

aditya-krish commented 4 years ago

Okay after attempting multiple times I finally got the artifact even when using the code you have posted above.

On Mon, Mar 9, 2020 at 6:51 PM Aditya K adityakrish122@gmail.com wrote:

I also tried commenting out the w2im_filter.Modified() line, that still gives proper image, with no artifacts. So I guess it is not due to that line.

On Mon, Mar 9, 2020 at 6:50 PM Aditya K adityakrish122@gmail.com wrote:

I tried two things, the above routine and screenshot_fig, for the same mesh. The above routine almost always seems to work, but screenshot_fig almost always does not work. I am attaching the images generated by both the routines, the one showing a tooth like structure is the above routine on the other hand the one showing the "ghost" artifact is using screenshot_fig.

On Mon, Mar 9, 2020 at 5:16 PM bwoodsend notifications@github.com wrote:

OK, I've tried what you said and I can't reproduce it at all. I noticed that screenshot_fig() doesn't call vtkWindowToImageFilter.Modified() which I think it aught to and there is also off screen rendering to play with. I've done a stripped down example for you to test. Could you give it a run for me please?

import vtkplotlib as vpl import vtkplotlib.image_io import matplotlib.pylab as plt import vtk import time

fig = vpl.figure() vpl.quick_test_plot()

Try turning this one on and off and see if it changes anything.

fig.renWin.SetOffScreenRendering(True)

since = time.time() while time.time() - since < 2: pass

fig.connect() fig.reset_camera() fig.renWin.Render()

win2im_filter = vtk.vtkWindowToImageFilter() win2im_filter.SetInput(fig.renWin) win2im_filter.Modified() win2im_filter.Update()

arr = vpl.image_io.vtkimagedata_to_array(win2im_filter.GetOutput())

win2im_filter.SetInput(None) vpl.close(fig)

plt.imshow(arr) plt.show()

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bwoodsend/vtkplotlib/issues/1?email_source=notifications&email_token=ANJMUEFKELF3B625LVZP4YLRGTJH7A5CNFSM4LADUBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOGYZHQ#issuecomment-596479134, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANJMUEAWXB4MYCUKJ4SE4UDRGTJH7ANCNFSM4LADUBBA .

bwoodsend commented 4 years ago

I am attaching the images generated by both

Either you forgot to attach or they didn't work... :)

Did you try the fig.renWin.SetOffScreenRendering(True) line near the top?

Also are you doing teeth as well? That's what I wrote this library for in the first place.

aditya-krish commented 4 years ago

This following one is the correct image, output of fig.renWin.SetOffScreenRendering(True): above_code

This is the bad screenshot generated by the above routine: above_code2

This is the output of screenshot_fig: screenshot_fig

Yes I am working on intra-oral scans, small world!!

The fig.renWin.SetOffScreenRendering(True) line seems to do the job, thanks a lot. The only issue is it is not running from the shell on the server and aborting with error "Aborting - bad X server connection." But that does not belong to this thread. I will edit the screenshot_fig in my environment to reflect this change. Thank you for your inputs.

bwoodsend commented 4 years ago

OK, I'm glad you highlighted that. It looks like off screen rendering can get ugly. I'll pop it in the next update but as an optional parameter.

bwoodsend commented 4 years ago

Could you do me a favour and keep me posted on your resolving that bad X-server issue? I'd like to at least add it to the docs if it's not practical to fix outright.

aditya-krish commented 4 years ago

It works when I make a GUI login to the server, open terminal and run the application. It does not work when I connect to the server through SSH. Do you want me to post a screenshot of the error?

bwoodsend commented 4 years ago

Might as well although I doubt I can help much. I did a google of "Aborting - bad X server connection" and this comment seems to say you need a special build of VTK with OSMesa. But the fact you can get it to work via the GUI suggests you already have everything you need.

aditya-krish commented 4 years ago

Yes I am good with the current solution, even if it doesn't work with SSH, I was just suggesting it for your documentation purposes bwoodsend_error_image

bwoodsend commented 4 years ago

OK. I'll leave this issue open until I've pushed and released the changes. Thanks for your help with this.

Just as a warning to future readers of this thread: The fig.renWin.SetOffScreenRendering(True) option seems to mess the vtkRenderWindow irreversibly so that the figure can no longer be shown normally without crashing. Calling vpl.close(fig=fig) after screenhot_fig() or save_fig() resets the vtkRenderWindow so that the figure can be safely reshown. Hopefully this will all be ironed out in the next release (v1.3.0) so that you shouldn't need to worry about any of this.