Results 1 to 6 of 6

Thread: QGraphicsScene, QGraphicsPath, and a lot of shapes...

  1. #1
    Join Date
    Jul 2012
    Posts
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows

    Question QGraphicsScene, QGraphicsPath, and a lot of shapes...

    Hi Everybody,

    I try to draw multiple polygons inside a QGraphicsPath, itself inside a QGraphicsScene.
    My problem is that i have more that millions of polygons to draw. I know that in openGL/MFC, FPS is more than 10 and that's enough for my application.
    Now, in Qt.... it take several seconds...

    I think it's because QGraphicsPath are "intelligent" objects with a lot of interesting properties, but that also take a long time to draw if they are a lot...

    But i would like to keep QGraphicsScene properties, like setSceneRect ( to delimit draw ) and scale ( to change a zoom for example ).

    Can we combine QGraphicsScene / Qpainter and Scaling properties ????

    thanks for your help !
    Fred

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsScene, QGraphicsPath, and a lot of shapes...

    n Qt.... it take several seconds...

    I think it's because QGraphicsPath are "intelligent" objects with a lot of interesting properties, but that also take a long time to draw if they are a lot...
    Well, as you can read in the first paragraph of the QGraphics Framework docs:
    Graphics View uses a BSP (Binary Space Partitioning) tree to provide very fast item discovery, and as a result of this, it can visualize large scenes in real-time, even with millions of items.
    If you don't believe the trolls, you can test the examples that demonstrate this very thing.

    Conclusion:
    The performance issue *probably* has to be in your code.

    Can we combine QGraphicsScene / Qpainter and Scaling properties ????
    Its all here:
    http://qt-project.org/doc/qt-4.8/graphicsview.html
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicsScene, QGraphicsPath, and a lot of shapes...

    Conclusion:
    The performance issue *probably* has to be in your code.
    As a test of the QGraphics framework, and in particular, the ability to use BSP for fast sub-item discovery, I implemented a data plotting widget that is a somewhat simplified version of Qwt. In particular, the plotting of the actual curves within the scene was implemented using a QPainterPath inside a QGraphicsPathItem. Some of my curves contain 100,000 or more points, and may displayed as connected line segments or as vertical, unconnected "sticks".

    The algorithm was implemented so that when the curve data was set, the QPainterPath and QGraphicsPathItem were rebuilt from primitives (moveTo, lineTo,etc.) with pen changes as needed when different parts of the curve had different colors. Once the QGraphicsPathItem was updated in the scene, the curve's paint() method was essentially a no-op, because the path draws itself.

    I ran out of memory long before I could construct a path with 100,000 line segments in it. That leads me to seriously doubt this statement:

    Graphics View uses a BSP (Binary Space Partitioning) tree to provide very fast item discovery, and as a result of this, it can visualize large scenes in real-time, even with millions of items.
    What could be simpler than constructing a path with a large number of line segments?

    After trying several ways to work around this, I finally gave up, got rid of the QPainterPath and implemented a QGraphicsItem to draw the line segments manually in the paint() method. Turning on the DeviceCoordinateCache flag enabled good performance for zooming and other operations.

    The 40000 chips demo is not a good example for this issue, because it does not use QPainterPath, but draws each chip at the appropriate LOD on each paint() call. At the most coarse LOD, it is simply drawing 6 lines for each chip, so certainly it is blindingly fast. And at the finest LOD, there is just a bit of text and only a chip or two is visible. Each chip has only about 100 bytes of internal storage in addition to that used by QGraphicsItem, so even 40K of them is only 4 MB of memory plus the base class overhead - tiny.

    My conclusion is that the QGraphics framework has its best performance when the primitives it must draw are simple. So if you have a million little rectangles, and each of them is a QGraphicsItem-based item, you will get great performance. But if you try to add those same 1 million rectangles to a QGraphicsPathItem, the performance will be terrible, as the OP observed.

    I may try re-implementing my curve plotting class as a set of QGraphicsLineItem instances to see if that changes the performance. This seemed to me to be very wasteful - to create a new class instance for every segment, but maybe it will allow the BSP and the framework's clipping algorithms to work more efficiently.
    Last edited by d_stranz; 4th July 2012 at 19:32.

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsScene, QGraphicsPath, and a lot of shapes...

    After trying several ways to work around this, I finally gave up, got rid of the QPainterPath and implemented a QGraphicsItem to draw the line segments manually in the paint() method. Turning on the DeviceCoordinateCache flag enabled good performance for zooming and other operations.
    Had exactly the same problem (way, way back), solved it exactly the same way.
    Since the solution was to get rid of QPainterPath, which is NOT part of the QGraphics Framework, and relay purely on the Grpahics FW side - which proves that Graphics FW actaully is much more perfomant, then using the regular painter.
    I admit the QPainterPath bit escaped me when I read the OP post . (but I am reading the posts during work, so quite fast).

    The 40000 chips demo is not a good example for this issue, because it does not use QPainterPath, but draws each chip at the appropriate LOD on each paint() call. At the most coarse LOD, it is simply drawing 6 lines for each chip, so certainly it is blindingly fast. And at the finest LOD, there is just a bit of text and only a chip or two is visible. Each chip has only about 100 bytes of internal storage in addition to that used by QGraphicsItem, so even 40K of them is only 4 MB of memory plus the base class overhead - tiny.
    Well, when you go about dealing with millions of items, I would expect to have performance issues no matter what system I am working with, and would go for very simple items.
    Have millions of complex items on one side, and expecting miracles on the other (have them shown in a millisecond) at the moment at least, is not really sensible.


    One more tip to OP:
    You can use OpenGL (hardware acceleration) if you set your viewport to a QGLWidget.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGraphicsScene, QGraphicsPath, and a lot of shapes...

    As Daniel said, QPainterPath is not part of Graphics View framework, it doesn't use BSP and can't benefit from what graphics view offers. If one runs out of memory (quite hard for me to believe it unless resources are limited by the system somehow) then we can't circumvent that. However to improve performance in GV, it is enough to split the painter path into separate items, as far as I rememeber, it makes a big difference. Caching is a must as well.

    I just ran this small test program:

    Qt Code:
    1. #include <QtGui>
    2. #include <iostream>
    3.  
    4. int main(int argc, char **argv) {
    5. for(int i=0;i<100000;++i) {
    6. std::cerr << "Iteration " << i << "...";
    7. path.lineTo(qrand() % 1000, qrand() % 1000);
    8. std::cerr << "Done" << std::endl;
    9. }
    10. std::cerr << "Path ready" << std::endl;
    11. // let's sleep now
    12. QSemaphore s(0);
    13. s.acquire();
    14. return 0;
    15. }
    To copy to clipboard, switch view to plain text mode 

    The path was constructed fine, the system reports the following memory usage:
    VmPeak: 89104 kB
    VmSize: 89104 kB
    VmLck: 0 kB
    VmPin: 0 kB
    VmHWM: 7240 kB
    VmRSS: 7240 kB
    VmData: 4468 kB
    VmStk: 136 kB
    VmExe: 8 kB
    VmLib: 22452 kB
    VmPTE: 192 kB
    VmSwap: 0 kB
    One can see the peak memory usage is 90MB, with 22MB taken by libraries and only 4.5MB taken by the heap. This gives 45 bytes per path segment (on a 64b system).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicsScene, QGraphicsPath, and a lot of shapes...

    One can see the peak memory usage is 90MB, with 22MB taken by libraries and only 4.5MB taken by the heap. This gives 45 bytes per path segment (on a 64b system).
    Hmm, this is interesting. As I think about this more, it is entirely possible that the memory problems I saw are completely unrelated to QPainterPath and the GV framework. The program in which these large plots are displayed is a scientific data analysis application, which is manipulating large data sets in memory (240 MB just for the raw data alone, not even considering all of the annotation for the results). I have recently started to experience memory issues, where the app is getting into the 1GB range for heap usage. It is a 32-bit Windows app which can't be ported to 64-bit yet because of dependence on third-party DLLs which are only available in 32-bit.

    When I first implemented my plotting tool and was looking at smaller data sets, performance was just fine using QPainterPath. My (probably incorrect) assumption when I started having problems with large data sets was that it was a QPainterPath issue.

    Needs further investigation on my part, I think. I had high hopes for using the object tracking features of the GV framework.

Similar Threads

  1. Drawing and resizing shapes
    By jonnale in forum Qt Programming
    Replies: 10
    Last Post: 15th April 2020, 16:44
  2. computing intersections of two shapes
    By alpinista in forum Qt Programming
    Replies: 1
    Last Post: 20th August 2009, 11:23
  3. QGraphicsScene and fonts/shapes sizes
    By olelukoie in forum Qt Programming
    Replies: 15
    Last Post: 28th January 2009, 21:46
  4. Drawing shapes
    By ^NyAw^ in forum Qt Programming
    Replies: 2
    Last Post: 31st October 2008, 09:19
  5. Tweaking QGraphicsPath rendering
    By viridis in forum Qt Programming
    Replies: 0
    Last Post: 27th February 2008, 17:36

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.