1

I m using Qt 3D to visualise point cloud data. I have modified the example given here: simple-cpp example. I have added the code to read a file containing 99477 points. Following code snippet shows how I m filling the Entity class with point cloud data.

for (int i = 0; i < X.size(); i++)
{
    Qt3DCore::QEntity *sphereEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QSphereMesh *sphereMesh = new Qt3DExtras::QSphereMesh;
    sphereMesh->setRadius(0.05);

    Qt3DCore::QTransform *sphereTransform = new Qt3DCore::QTransform;

    sphereTransform->setTranslation(QVector3D(X[i], Y[i], Z[i]));
    sphereEntity->addComponent(sphereMesh);
    sphereEntity->addComponent(sphereTransform);
    sphereEntity->addComponent(material);
}

The code is crashes after around 10 minustes after Qt3DExtras::Qt3DWindow::show() is called. The terminal output is as below:

17:53:33: Starting /home/suraj/Qt/Examples/Qt-5.15.2/qt3d/build-simple-cpp-
Desktop_Qt_5_15_2_GCC_64bit-Release/simple-cpp ...
Point cloud size: 99477 points.
18:00:06: The program has unexpectedly finished.
18:00:06: The process was ended forcefully.
18:00:06: /home/suraj/Qt/Examples/Qt-5.15.2/qt3d/build-simple-cpp-Desktop_Qt_5_15_2_GCC_64bit-Release/simple-cpp crashed.

So I decreased the number of points to ~18000, then it is able to load the scene but with some delay in seconds.

Can anyone guide me on this?

surajj4837
  • 49
  • 1
  • 10

1 Answers1

3

Default number of rings and slices for QSphereMesh is 16. Those are basically vertical and horizontal sphere subdivisions. That means each of your spheres is made out of 480 triangles. Because you are drawing 99477 spheres that means you are drawing 47,748,960 triangles. That can be a lot for integrated GPU. To fix this you can try to use smaller integer for rings and slices for each sphere or you can try to implement instancing. For example if you set rings and slices to 3 You would draw only 1,193,724 triangles.

  • Thanks for the update on rings and slices, I changed setRings(2) and setSlices(3) and I was able to display up to 32k points(still with some delay). What is the upper limit of the number of items that can be displayed? – surajj4837 Apr 20 '21 at 11:15
  • It depends on how good your GPU is. However, the best solution when you are using a lot of duplicates of the same object is to utilize instancing. Instanced rendering should be many times faster than creating each object from scratch. That is how modern games can render grass hills or thousands of tree leaves in real-time. Instancing is implemented in Qt 3D, however I still haven't figured out how to use it because of the very poorly written documentation. – Nemanja Stojanovic Apr 20 '21 at 11:38
  • I will also do my research on instancing in Qt 3D. Does visualising the huge data on Qt+PCL framework improve the performance? – surajj4837 Apr 20 '21 at 11:49
  • I'm not familiar with PCL. I've used mostly [Open3D](http://www.open3d.org/) – Nemanja Stojanovic Apr 20 '21 at 11:54
  • 1
    I implemented [picking for instanced rendering in Qt3D](https://github.com/florianblume/qt3d-instanced-picking) with a little trick (rendering IDs to texture) some time ago. Maybe it can get you started. I got the instanced rendering code from somewhere else though (see description on GitHub). Another suggestions: Why don't you render the points as points instead of spheres? You could enlarge the point size to make them bigger if that's an issue. – Florian Blume Apr 20 '21 at 13:41
  • Qt6.0 [documentation](https://doc.qt.io/qt-6/qt3d-overview.html#instanced-rendering) says: **Instanced rendering is planned for a future release.** – surajj4837 Apr 22 '21 at 03:47
  • Thanks Florian, I will take a look at it. – surajj4837 Apr 22 '21 at 03:50
  • [Demo](https://www.qt.io/blog/introducing-qtquick3d-benchmarking-application) page shows a complete animation using 3D module. This looks more complicated than displaying 99477 points. Is there something I m missing in implementation of the same? – surajj4837 Apr 22 '21 at 11:50
  • That scene contains maybe hundred objects. You draw almost 100.000. That is why instancing exists in the first place. Basically most of the execution time is spent on communication between your CPU and GPU while they both sit idle most of the time. If you for example combine your 100.000 objects in one big mesh and then send it to the GPU then you would have only one draw call and drastic FPS boost. It is that simple – Nemanja Stojanovic Apr 22 '21 at 15:56