Results 1 to 8 of 8

Thread: drawing contours

  1. #1
    Join Date
    Jul 2017
    Posts
    37
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default drawing contours

    I just got my program to display contours. (I've had it drawing them in PostScript for over a year and drawing them correctly for a few months, but just got it to draw them in Qt.) The relevant part of the paintEvent method is this:
    Qt Code:
    1. for (i=0;i<doc.pl[plnum].contours.size();i++)
    2. {
    3. b3d=doc.pl[plnum].contours[i].approx3d(pixelScale());
    4. path=QPainterPath();
    5. for (k=0;k<b3d.size();k++)
    6. {
    7. beziseg=b3d[k];
    8. if (k==0)
    9. path.moveTo(worldToWindow(beziseg[0]));
    10. path.cubicTo(worldToWindow(beziseg[1]),worldToWindow(beziseg[2]),worldToWindow(beziseg[3]));
    11. }
    12. if (!doc.pl[plnum].contours[i].isopen())
    13. path.closeSubpath();
    14. contourType=doc.pl[plnum].contourInterval.contourType(doc.pl[plnum].contours[i].getElevation());
    15. painter.strokePath(path,contourPen[contourType>>8][contourType&31]);
    16. }
    To copy to clipboard, switch view to plain text mode 
    There are hundreds of contours, many of which have hundreds of segments (which will be spiralarcs once I smooth them), and the whole thing takes about 200 or 300 ms to draw. It's common in CAD programs to keep a list of lines to draw and regenerate the list when the scale changes by a lot, but I don't see how that can work with QPainterPaths. There's a way to translate a QPainterPath, but not to scale or rotate it. Suggestions?

  2. #2
    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: drawing contours

    Suggestions?
    Why are you regenerating the QPainterPath for every paintEvent()? (Your comment implies that's what you're doing). Store the path in a member variable and simply use QPainter::drawPath() in the paintEvent() to redraw it. Most of your overhead is likely due to recreating the entire path with every paintEvent(). You should re-create the path only when the contours change.

    As for scaling, can you not apply the scaling transformation to the QPainter itself? Apply the scale transform, draw the path, reset the transform?

    QPainter also has the world-to-screen transformations built it, so could probably do what you seem to be doing manually.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jul 2017
    Posts
    37
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: drawing contours

    Would the world-to-screen transformation handle tilting the view? I don't have a way to tilt the view yet, but I'm thinking about it.

    I have to regenerate the bezier3d objects (and therefore the QPainterPaths) when the scale changes (including when the window is resized). How much scale change should need to happen before I regenerate them? Right now the scale argument to approx3d makes no difference, since the contours are made of straight lines, but once I smooth them, it will make a difference.

    If I scale the QPainter, what happens to line widths?

    ETA: How can I find out how much time the program is spending in approx3d and in drawing paths? Callgrind (a Valgrind tool) works well on the console program, but not as well on Qt GUI programs.
    Last edited by PierreA; 14th November 2017 at 08:55.

  4. #4
    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: drawing contours

    Would the world-to-screen transformation handle tilting the view?
    Unfortunately, QTransform and QPainter are 2D coordinates only. If you are doing 3D, then you are stuck with transforming coordinates yourself.

    If I scale the QPainter, what happens to line widths?
    If you use a cosmetic QPen, then line widths stay constant. Non-cosmetic pens will scale the line width.

    How much scale change should need to happen before I regenerate them?
    When I have a case of expensive redraws, I set a short-duration (maybe 250 ms) QTimer in the resizeEvent() and set a Boolean flag to determine what happens in the paintEvent() (or instead of a Boolean, check QTimer::isRunning()). When the timer times out, it resets the flag to trigger a redraw. Each time the resize event is called, it starts the timer again, so as long as the user is resizing the window, the contents won't be repainted and the UI stays "alive". Once the user stops moving the window, the timer times out, the flag is reset and the paintEvent will redraw the contents. You can do variations on this - redraw every "n" resize events, or when the scale has changed by "x", or some combination.

    If it is necessary for the user to see the resize / rescale in action, one possibility instead of a complete redraw is to capture the window to a QImage at the beginning, then call QPainter::drawImage() with scaling into the resized window. When resizing or scaling is done, remove the bitmap and redraw the actual contents to the new size or scale.

    In any case, if I am using a QPainterPath, I re-create the path only when absolutely necessary and store the result for the paint events.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Jul 2017
    Posts
    37
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: drawing contours

    I used QTime to find out how much time it's spending rendering the objects. Using a cache to cache the rendered bezier3d objects reduced the total time for the paintEvent method from 380 to 190 ms. Of this, 82 ms is spent drawing the bezier3ds as QPainterPaths and 47 ms drawing the QPainterPaths to the window. (The rest is probably mostly drawing the TIN. The average paintEvent time is 192 ms this time; there's a lot of standard deviation, so this difference isn't significant.) I'm going to leave it like this for now.

    It takes a lot longer to paint smooth contours, because they have more splines. It also takes longer to compute them than to compute rough contours.

  6. #6
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: drawing contours

    If you have so many little spline pieces, maybe you could replace the cubicTo() call with a lineTo() call without a noticeable visual difference?

  7. #7
    Join Date
    Jul 2017
    Posts
    37
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: drawing contours

    It's very noticeable when magnified. Should I check how far a spline is from straight, in window coordinates, and substitute a line if it isn't?

  8. #8
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: drawing contours

    I am not sure. The code could become cumbersome for not much speedup. I think the most promising next step would be to cache the QPainterPath so that you only have to paint it and not regenerate it. You could use an OpenGL environment to do your drawing so that you can cache everything and only need to modify the painter or view transformation. There is a QOpenGLWidget that might come in handy. Then there is the QGLViewer library, just google it.

Similar Threads

  1. Replies: 1
    Last Post: 7th November 2017, 08:11
  2. Replies: 3
    Last Post: 11th July 2014, 15:45
  3. Qt Drawing
    By Talguy in forum Newbie
    Replies: 4
    Last Post: 12th January 2011, 05:14
  4. 2D drawing
    By WXNSNW in forum Qt Programming
    Replies: 3
    Last Post: 6th October 2010, 00:01
  5. Drawing
    By chethana in forum Qt Programming
    Replies: 1
    Last Post: 16th October 2007, 07:29

Tags for this Thread

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.