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

Add new constructors to PCLVisualizer #2004

Merged

Conversation

denix56
Copy link
Contributor

@denix56 denix56 commented Sep 22, 2017

New constructors allow to provide custom renderers and render windows. It gives the ability to use QVTKOpenGLWidget and lots of vtk render windows.

New constructors allow to provide custom renderers and render windows
@denix56
Copy link
Contributor Author

denix56 commented Sep 22, 2017

fixes #1989

Oh, I have found that there is the code repeat. I will fix it tomorrow.

@taketwo
Copy link
Member

taketwo commented Sep 26, 2017

Could you please elaborate why you first used raw pointers and then switched to smart pointers? I'd like to understand the implications of both options.

@taketwo taketwo added the needs: code review Specify why not closed/merged yet label Sep 26, 2017
@denix56
Copy link
Contributor Author

denix56 commented Sep 26, 2017

I moved to smart pointers, because the visualizer stores smart pointers (consistency) and it is safer (if we use this renderer somewhere else, and decide to delete visualizer, the renderer will not be deleted).

@taketwo
Copy link
Member

taketwo commented Sep 27, 2017

because the visualizer stores smart pointers (consistency)

As far as I can tell, this is not entirely correct. The vtkRenderWindow object is indeed stored as a smart pointer member field (win_), however the vtkRenderer object is added to a collection called rens_, which actually stores raw pointers.

In general, the memory management in VTK is a bit of a mystery for me with all their "self-owning" pointers and reference counters inside objects. I'll just assume that you have tested your proposed changes (including destroying widget and visualizer in different order) and it does not crash.

Copy link
Member

@taketwo taketwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good. Since you are already doing a bit of refactoring, maybe try to minimize code repeat between these two different versions of construct() function?

Also, please fix the code to match PCL style guide. Specifically, we need spaces between function names and brackets.

if (create_interactor)
createInteractor();

win_->SetWindowName(name.c_str());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already done in line 339?

@denix56
Copy link
Contributor Author

denix56 commented Sep 29, 2017

I have dug into vtk library and have found that it is save to convert smart pointers to raw ones. When the object is deleted, the special function handles if the reference count is not bigger than 1 nad deletes the object only if it is true.

@denix56
Copy link
Contributor Author

denix56 commented Sep 29, 2017

Also, I would like to continue refactoring pcl visualizer, but it will be other pull requests.

// Set the window size as 1/2 of the screen size or the user given parameter
if (!camera_set_ && !camera_file_loaded_)
{
win_->SetSize (scr_size_x / 2, scr_size_y / 2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I miss something, but why do we need this conditional resizing/repositioning? Resizing already happened in the other construct() function.

@taketwo taketwo added needs: author reply Specify why not closed/merged yet and removed needs: code review Specify why not closed/merged yet labels Sep 30, 2017
@denix56
Copy link
Contributor Author

denix56 commented Sep 30, 2017

I decided to add one more argument to 'small' construct function - resize_window.
This argument prevents from double window resizing. Because if we have cam file and load it, the small constructor resizes window first, then after loading camera parameters window will be resized again.

Another solution without additional argument would be to move window resizing to constructor (without camera loading), but I think that it would be inconsistent (we call only construct functions in all constructors) and harder to understand.

Copy link
Member

@taketwo taketwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that adding resize_window argument to one of the construct() overloads is a good idea. Note that the code that actually resizes the window in duplicated in both versions of the function nevertheless. I take this as a strong indication that the granularity that we chose for splitting construction work into functions is wrong.

What do you think about the following: split construct() into smaller functions, an call (some of) them as needed in each class constructor?

if (resize_window)
{
int scr_size_x = win_->GetScreenSize ()[0],
scr_size_y = win_->GetScreenSize ()[1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please only declare one name per line.

@taketwo
Copy link
Member

taketwo commented Sep 30, 2017

Seems like the changes to the header file haven't been committed.

@denix56
Copy link
Contributor Author

denix56 commented Oct 1, 2017

Yeah, I missed to commit that header file.

It would be nice, if we could achieve merging of this pull request until tomorrow)

@denix56
Copy link
Contributor Author

denix56 commented Oct 2, 2017

The build failed due to too long build of stage, other parts are ok

Copy link
Member

@taketwo taketwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder: squash on merge.

@taketwo taketwo removed the needs: author reply Specify why not closed/merged yet label Oct 2, 2017
@taketwo taketwo added this to the pcl-1.9.0 milestone Oct 2, 2017
@denix56
Copy link
Contributor Author

denix56 commented Oct 2, 2017

Some more questions - will it be merged to master or it will be waiting for pcl 1.9.0? And do I have to do anything? I am a bit newbie :)

@taketwo
Copy link
Member

taketwo commented Oct 3, 2017

From my side it's ready to be merged in master. But for nontrivial PRs we typically wait for a "yes" from a second maintainer. I think @SergioRAgostinho will be back from his vacations very soon, will give it a quick look, and merge.

* \param[in] argc
* \param[in] argv
*/
void setupCamera (int &argc, char **argv);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small comment: I know this PR is only refactoring, but this signature is completely cryptic for me. Do you have any idea which format one passes to these camera parameters? Is there any way we can add some documentation to improve it this an the other signatures which pass these? From our current docs there's nothing on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand, we pass the program arguments, which may contain -cam ".cam". It is good idea to add the documentation for it. I will do it, but in the another merge request. We are using my change in our project at the moment, and it will be nice to use pcl master repo instead of my fork.

@taketwo taketwo merged commit 9887bad into PointCloudLibrary:master Oct 9, 2017
@denix56 denix56 deleted the PCLVisualizerCustomRenderers branch October 9, 2017 14:36
@nikolaseu
Copy link

hey @denix56 great work! I was just trying to make pcl visualizer work with QVTKOpenGLWidget and found this.

I compiled from master today (not in debug mode :( ) and was just trying to use this new constructor but it crashes when doing the new.

Is this how it's supposed to be used? Do you see anything wrong? QVTKOpenGLWidget alone works ok.

   // before initializing QApplication, set the default surface format.
    QSurfaceFormat::setDefaultFormat(QVTKOpenGLWidget::defaultFormat());

    QApplication app(argc, argv);

    QVTKOpenGLWidget *widget = new QVTKOpenGLWidget();

    vtkNew<vtkRenderer> renderer;
    vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
    renderWindow->AddRenderer(renderer.Get());

    pcl::visualization::PCLVisualizer::Ptr pclViewer(new pcl::visualization::PCLVisualizer(renderer.Get(), renderWindow.Get(), "viewer", false));
    widget->SetRenderWindow(pclViewer->getRenderWindow());

    widget->show();

@denix56
Copy link
Contributor Author

denix56 commented Oct 13, 2017

Could you please provide the system info the you use? I have tested the code that you gave on Ubuntu 16.04 and it worked fine for me.

@nikolaseu
Copy link

pcl built from master yesterday and VTK 8.0.1 built with OpenGL2 and Module_vtkRenderingExternal, Qt 5.9.2, in macOS 10.13
Maybe I missed something when building pcl. I was using VTK7 and QVTKWidget previously and now I'm trying to update to VTK 8

@denix56
Copy link
Contributor Author

denix56 commented Oct 14, 2017 via email

@denix56
Copy link
Contributor Author

denix56 commented Oct 14, 2017

Tested the code on Windows. I worked on it too. The problem might be caused if you use in your build pcl or vtk in release and qt in debug. As for me, in such combination it crashes.

@taketwo
Copy link
Member

taketwo commented Oct 16, 2017

@nikolaseu If this is still a problem, please create a new issue with all the infos so that we can track it.

@nikolaseu
Copy link

I compiled vtk from master (8.1?) and it's working! thanks

@tudodetalhado
Copy link

I'm looking for this resource. Can I get it from master or need to wait for pcl 1.9.0?

@SergioRAgostinho
Copy link
Member

You can get it from master.

@tudodetalhado
Copy link

Thank you, Sergio!
I wrote a custom widget to Qt using the new constructor, and I'm sharing the code:

VideoQVTKOpenGLWidget.h


    #ifndef VIDEOQVKTOPENGLWIDGET_H
    #define VIDEOQVKTOPENGLWIDGET_H

    #include <QWidget >
    #include <QVTKOpenGLWidget.h >
    #include <pcl/visualization/pcl_visualizer.h >
    using namespace pcl::visualization;

    class VideoQVTKOpenGLWidget : public QVTKOpenGLWidget
    {
      public:
        explicit VideoQVTKOpenGLWidget(QWidget *parent = 0);
        void populateCloud(pcl::PointCloud<pcl::PointXYZRGBA >::Ptr cloud);

      private:
        boost::shared_ptr<PCLVisualizer > _viewer;
        vtkSmartPointer<vtkGenericOpenGLRenderWindow > _renderWindow;
    };

    #endif // VIDEOQVKTOPENGLWIDGET_H

VideoQVTKOpenGLWidget.cpp


    #include "VideoQVTKOpenGLWidget.h"

    #include <vtkPointPicker.h >
    #include <vtkGenericOpenGLRenderWindow.h >

    VideoQVTKOpenGLWidget::VideoQVTKOpenGLWidget(QWidget *parent)
      : QVTKOpenGLWidget(parent)
    {
      auto renderer = vtkSmartPointer<vtkRenderer >::New();
      _renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow >::New();
      _renderWindow- >AddRenderer(renderer);
      _viewer.reset(new PCLVisualizer(renderer, _renderWindow, "viewer", false));
      this- >SetRenderWindow(_viewer- >getRenderWindow());
      this- >update();
    }

    void VideoQVTKOpenGLWidget::populateCloud(pcl::PointCloud <pcl::PointXYZRGBA >::Ptr cloud)
    {
      if(!_viewer- >updatePointCloud(cloud, "cloud")) {
        _viewer- >addPointCloud(cloud, "cloud");
      }
      _renderWindow- >Render();
    }  

@SergioRAgostinho
Copy link
Member

Better post it to the mailing list. The users don't come that often here because it's just a bug tracker. I'm sure you're gonna make some them very happy because I think QVtk is a recurrent topic.

UnaNancyOwen pushed a commit to UnaNancyOwen/pcl that referenced this pull request Nov 24, 2017
Add new constructors to PCLVisualizer

New constructors allow to provide custom renderers and render windows.
@apalomer
Copy link

apalomer commented Sep 4, 2018

I have been trying to use this constructor alongside with VTK trunk to create a pcl widget for Qt and I get segmentation faults if I set the create_interactor to true. However it is very weird because I do not get the segmentation fault all the times I run the code, but all the times that I get the segmentation fault it is in the same place, when the pcl::visualization::PCLVisualizer executes createInteractor (). In detail when in this function the following code is called interactor_->Initialize (); in line 285 of file pcl_visualizer.cpp. This actually segfaults within vtk when it calls the function XtDisplayInitialize(vtkXRenderWindowInteractor::App,this->DisplayId, "VTK","vtk",nullptr,0,&argc,nullptr);

I am running Ubuntu 18.04 using this commit for VTK and this commit for PCL. The two used libraries (VTK and PCL) are not installed, i link against this version instead of the installed one by setting the falgs -DPCL_DIR and -DVTK_DIR when configuring cmake: cmake -DPCL_DIR=/path/to/pcl/custom/install/dir -DVTK_DIR=/path/to/vtk/compiled ..

You can find an example code here.

@SergioRAgostinho SergioRAgostinho added the changelog: enhancement Meta-information for changelog generation label Sep 4, 2018
@SergioRAgostinho
Copy link
Member

@apalomer Let's move this to a new issue.

@apalomer
Copy link

apalomer commented Sep 4, 2018

Done: #2413

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: enhancement Meta-information for changelog generation module: visualization
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants