Re: [Interest] QtLocation MapPolyLine and MouseArea
Thanks Shawn, that looks the best approach, I 'll give it a try. Le 07-03-2019 20:29, Shawn Rutledge a écrit : On 7 Mar 2019, at 18:32, maitai wrote: Hi, I need to trigger various actions whenever a MapPolyLine is hovered or pressed, such as displaying a tooltip, a menu, etc. I have put a MouseArea on it with anchors.fills: parent, but the problem is that the mouse area does not represent the line, but the polygon made by the line. For instance if you have a L shape, entered event and so on is triggered when you enter the bounding rectangle of the line, not when you hover over the line itself. On a QGraphicsScene we had the shape() protected method for that kinds of case, for instance with a QPainterPathStroker to give some thickness to the line's "mousearea". I will probably end with a custom property that will carry the pixel distance between the line segments and the mouse coordinates, but this is going to be heavy to compute (I have potentially hundreds of complicated lines on the map). Is there a better way or even better a standard way to do that? Check out containmentMask: that’s how you can redefine the behavior of MouseArea’s contains() method in QML. You could use HoverHandler and/or TapHandler though, and then perhaps set containmentMask on the polyline itself if behavior is still not what you want (I haven’t tried it with MapPolyLine myself, only with QtQuick.Shapes). ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] QtLocation MapPolyLine and MouseArea
Hi Tony, Yes in fact there is a quadtree on top of that. Philippe. Le 08-03-2019 02:31, Tony Rietwyk a écrit : Hi Philippe, Just to confirm - you are filtering your list of lines by using the bounding rectangle first, then doing the detailed line-segment check? Regards, Tony On 8/03/2019 4:32 am, maitai wrote: Hi, I need to trigger various actions whenever a MapPolyLine is hovered or pressed, such as displaying a tooltip, a menu, etc. I have put a MouseArea on it with anchors.fills: parent, but the problem is that the mouse area does not represent the line, but the polygon made by the line. For instance if you have a L shape, entered event and so on is triggered when you enter the bounding rectangle of the line, not when you hover over the line itself. On a QGraphicsScene we had the shape() protected method for that kinds of case, for instance with a QPainterPathStroker to give some thickness to the line's "mousearea". I will probably end with a custom property that will carry the pixel distance between the line segments and the mouse coordinates, but this is going to be heavy to compute (I have potentially hundreds of complicated lines on the map). Is there a better way or even better a standard way to do that? Thanks Philippe Lelong ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] QtLocation MapPolyLine and MouseArea
Hi Philippe, Just to confirm - you are filtering your list of lines by using the bounding rectangle first, then doing the detailed line-segment check? Regards, Tony On 8/03/2019 4:32 am, maitai wrote: Hi, I need to trigger various actions whenever a MapPolyLine is hovered or pressed, such as displaying a tooltip, a menu, etc. I have put a MouseArea on it with anchors.fills: parent, but the problem is that the mouse area does not represent the line, but the polygon made by the line. For instance if you have a L shape, entered event and so on is triggered when you enter the bounding rectangle of the line, not when you hover over the line itself. On a QGraphicsScene we had the shape() protected method for that kinds of case, for instance with a QPainterPathStroker to give some thickness to the line's "mousearea". I will probably end with a custom property that will carry the pixel distance between the line segments and the mouse coordinates, but this is going to be heavy to compute (I have potentially hundreds of complicated lines on the map). Is there a better way or even better a standard way to do that? Thanks Philippe Lelong ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] QtLocation MapPolyLine and MouseArea
If you ever need that approach you could avoid the qsqrt() and compare the square distance instead, that would save some time (but yes it still heavy). If you have a line thickness threshold you could square it when you receive it only once. The best would be to have a shader doing it for you, you could render the map into a special shader and check the trace color/distance into the pixel and the mouse position. Not sure you can have a property output from that or if Qml ShaderEffect can be used that way. Maybe a pixel image from the map could be useful and simply do a pixel color compare? This is a really cheap way to do this but could worth a try. Every Item can be render to an image with grabToImage(), this is probably costly too. If you find a solution I would be interested into the final solution of this. -Original Message- From: Interest On Behalf Of maitai Sent: March 7, 2019 3:35 PM To: Interest@qt-project.org Subject: Re: [Interest] QtLocation MapPolyLine and MouseArea Yes thanks I know the maths for that, the problem being it's going to be calculated for all lines every time the user touches the mouse. Just to share here is my routine to calculate a QPointF distance to a QLineF: #define DIST(P1, P2) ((P1.x() - P2.x()) * (P1.x() - P2.x()) + (P1.y() - P2.y()) * (P1.y() - P2.y())) double Util::distToSegment(const QPointF ,const QLineF ) { const double d1 = DIST(line.p1(),line.p2()); if(d1 == 0.0) return qSqrt(DIST(point, line.p1())); const double t = ((point.x() - line.p1().x()) * (line.p2().x() - line.p1().x()) + (point.y() - line.p1().y()) * (line.p2().y() - line.p1().y())) / d1; if(t < 0) return qSqrt(DIST(point, line.p1())); if(t>1) return qSqrt(DIST(point, line.p2())); return qSqrt(DIST(point, QPointF(line.p1().x() + t * (line.p2().x() - line.p1().x()), line.p1().y() + t * (line.p2().y() - line.p1().y(); } I doubt there is a faster solution, still it's heavy if you need to do that on each mouse move, for all lines/segments you need to iterate to find the smallest. Philippe Lelong Le 07-03-2019 20:28, Jérôme Godbout a écrit : > Just throwing an idea, maybe you could convert the mouse click or > hover to coordinate on the Map::toCoordinate() and interpolate the > coordinate to see with parameter to the line vector and then find the > distance to that line parameter point or min/max point. This is not > super fast but could be quick enough. Maybe doing the inverted > converting the coordinate to point would make the computation easier. > > http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html > > > -Original Message- > From: Interest On Behalf Of maitai > Sent: March 7, 2019 12:33 PM > To: Interest@qt-project.org > Subject: [Interest] QtLocation MapPolyLine and MouseArea > > Hi, > > I need to trigger various actions whenever a MapPolyLine is hovered or > pressed, such as displaying a tooltip, a menu, etc. > > I have put a MouseArea on it with anchors.fills: parent, but the > problem is that the mouse area does not represent the line, but the > polygon made by the line. For instance if you have a L shape, entered > event and so on is triggered when you enter the bounding rectangle of > the line, not when you hover over the line itself. > > On a QGraphicsScene we had the shape() protected method for that kinds > of case, for instance with a QPainterPathStroker to give some > thickness to the line's "mousearea". > > I will probably end with a custom property that will carry the pixel > distance between the line segments and the mouse coordinates, but this > is going to be heavy to compute (I have potentially hundreds of > complicated lines on the map). > > Is there a better way or even better a standard way to do that? > > Thanks > Philippe Lelong > ___ > Interest mailing list > Interest@qt-project.org > https://lists.qt-project.org/listinfo/interest ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] QtLocation MapPolyLine and MouseArea
Yes thanks I know the maths for that, the problem being it's going to be calculated for all lines every time the user touches the mouse. Just to share here is my routine to calculate a QPointF distance to a QLineF: #define DIST(P1, P2) ((P1.x() - P2.x()) * (P1.x() - P2.x()) + (P1.y() - P2.y()) * (P1.y() - P2.y())) double Util::distToSegment(const QPointF ,const QLineF ) { const double d1 = DIST(line.p1(),line.p2()); if(d1 == 0.0) return qSqrt(DIST(point, line.p1())); const double t = ((point.x() - line.p1().x()) * (line.p2().x() - line.p1().x()) + (point.y() - line.p1().y()) * (line.p2().y() - line.p1().y())) / d1; if(t < 0) return qSqrt(DIST(point, line.p1())); if(t>1) return qSqrt(DIST(point, line.p2())); return qSqrt(DIST(point, QPointF(line.p1().x() + t * (line.p2().x() - line.p1().x()), line.p1().y() + t * (line.p2().y() - line.p1().y(); } I doubt there is a faster solution, still it's heavy if you need to do that on each mouse move, for all lines/segments you need to iterate to find the smallest. Philippe Lelong Le 07-03-2019 20:28, Jérôme Godbout a écrit : Just throwing an idea, maybe you could convert the mouse click or hover to coordinate on the Map::toCoordinate() and interpolate the coordinate to see with parameter to the line vector and then find the distance to that line parameter point or min/max point. This is not super fast but could be quick enough. Maybe doing the inverted converting the coordinate to point would make the computation easier. http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html -Original Message- From: Interest On Behalf Of maitai Sent: March 7, 2019 12:33 PM To: Interest@qt-project.org Subject: [Interest] QtLocation MapPolyLine and MouseArea Hi, I need to trigger various actions whenever a MapPolyLine is hovered or pressed, such as displaying a tooltip, a menu, etc. I have put a MouseArea on it with anchors.fills: parent, but the problem is that the mouse area does not represent the line, but the polygon made by the line. For instance if you have a L shape, entered event and so on is triggered when you enter the bounding rectangle of the line, not when you hover over the line itself. On a QGraphicsScene we had the shape() protected method for that kinds of case, for instance with a QPainterPathStroker to give some thickness to the line's "mousearea". I will probably end with a custom property that will carry the pixel distance between the line segments and the mouse coordinates, but this is going to be heavy to compute (I have potentially hundreds of complicated lines on the map). Is there a better way or even better a standard way to do that? Thanks Philippe Lelong ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] QtLocation MapPolyLine and MouseArea
> On 7 Mar 2019, at 18:32, maitai wrote: > > Hi, > > I need to trigger various actions whenever a MapPolyLine is hovered or > pressed, such as displaying a tooltip, a menu, etc. > > I have put a MouseArea on it with anchors.fills: parent, but the problem is > that the mouse area does not represent the line, but the polygon made by the > line. For instance if you have a L shape, entered event and so on is > triggered when you enter the bounding rectangle of the line, not when you > hover over the line itself. > > On a QGraphicsScene we had the shape() protected method for that kinds of > case, for instance with a QPainterPathStroker to give some thickness to the > line's "mousearea". > > I will probably end with a custom property that will carry the pixel distance > between the line segments and the mouse coordinates, but this is going to be > heavy to compute (I have potentially hundreds of complicated lines on the > map). > > Is there a better way or even better a standard way to do that? Check out containmentMask: that’s how you can redefine the behavior of MouseArea’s contains() method in QML. You could use HoverHandler and/or TapHandler though, and then perhaps set containmentMask on the polyline itself if behavior is still not what you want (I haven’t tried it with MapPolyLine myself, only with QtQuick.Shapes). ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] QtLocation MapPolyLine and MouseArea
Just throwing an idea, maybe you could convert the mouse click or hover to coordinate on the Map::toCoordinate() and interpolate the coordinate to see with parameter to the line vector and then find the distance to that line parameter point or min/max point. This is not super fast but could be quick enough. Maybe doing the inverted converting the coordinate to point would make the computation easier. http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html -Original Message- From: Interest On Behalf Of maitai Sent: March 7, 2019 12:33 PM To: Interest@qt-project.org Subject: [Interest] QtLocation MapPolyLine and MouseArea Hi, I need to trigger various actions whenever a MapPolyLine is hovered or pressed, such as displaying a tooltip, a menu, etc. I have put a MouseArea on it with anchors.fills: parent, but the problem is that the mouse area does not represent the line, but the polygon made by the line. For instance if you have a L shape, entered event and so on is triggered when you enter the bounding rectangle of the line, not when you hover over the line itself. On a QGraphicsScene we had the shape() protected method for that kinds of case, for instance with a QPainterPathStroker to give some thickness to the line's "mousearea". I will probably end with a custom property that will carry the pixel distance between the line segments and the mouse coordinates, but this is going to be heavy to compute (I have potentially hundreds of complicated lines on the map). Is there a better way or even better a standard way to do that? Thanks Philippe Lelong ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
[Interest] Rendering Qt/QML within native OpenGL or to texture
Hey, I'm having another attempt at a problem I failed to solve about a year ago. The rough sketch is: I have an external application which is using Qt and renders some content using the OpenSource graphics engine OGRE. (I can't / don’t want to change the application's source. My current approach is a plugin) I want to overlay a QWidget or a QML Scene on top of the rendered 3D scene. Now, there are different ways to achieve this. 1) My currently working one is to create a texture that is overlaid on top of the 3D scene by OGRE. I simply have to lock the texture's memory, create a QImage on top of the memory and draw into the image. This works for QWidgets, however, I can't display a QML scene that way (at least not as far as I know). 2) Whenever the scene has rendered, I switch to a QOpenGLContext, QOffscreenSurface, QOpenGLPaintDevice and QOpenGLFramebufferObject. Render the QWidget or QML scene into the FBO, retrieve the rendered content as a QImage, switch back to OGRE's OpenGL context and copy the image's content to the texture. This works for both QWidgets and QML but the copy operation takes quite a performance penalty making it inviable (around an order of magnitude longer than the first approach). Today I've found another way to use native OpenGL to draw on top of the scene in OGRE after the render queue ended but couldn't work out how to paint on it using Qt without getting stuck at the getting the content on screen without the QImage copy workaround in Approach 2. Unfortunately, 3D graphics and OpenGL is pretty far from my fields of expertise which is why I'm hoping someone who is more competent than me regarding OpenGL and QOpenGL can help me figure this out. I'll attach code parts that I deem important below, if you require a working example I can send you the code (it's not opensource yet but I'm planning on releasing it in the near future) but it requires a Linux distribution (only tested with Ubuntu) and a ROS installation. To summarize: I'm trying to find a way to either render directly to the texture, use a quicker method to copy the content from the FBO to the texture than getting a QImage and memcpy or, alternatively, render directly on top of the scene using the access to native OpenGL I've found today (here the problem is that I don't really know how to continue using OGRE's context when rendering Qt/QML). Best regards and thank you for taking your time to read until here, Stefan Texture generation: // Ogre::OverlayManager _manager = Ogre::OverlayManager::getSingleton(); ogre_overlay_ = overlay_manager.create( "overlay" ); material_ = Ogre::MaterialManager::getSingleton().create( "overlay_OverlayMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); overlay_panel_ = dynamic_cast( overlay_manager.createOverlayElement( "Panel", "overlay_Panel" )); overlay_panel_->setPosition( 0.0, 0.0 ); overlay_panel_->setDimensions( 1.0, 1.0 ); overlay_panel_->setMaterialName( "overlay_OverlayMaterial" ); ogre_overlay_->add2D( overlay_panel_ ); texture_ = Ogre::TextureManager::getSingleton().createManual( "overlay_OverlayTexture", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, texture_width, texture_height, 0, Ogre::PF_A8R8G8B8, Ogre::TU_DEFAULT ); material_->getTechnique( 0 )->getPass( 0 )->createTextureUnitState( texture_->getName()); material_->getTechnique( 0 )->getPass( 0 )->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA ); material_->getTechnique( 0 )->getPass( 0 )->setSceneBlending( Ogre::SBF_ONE, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA ); // Approach 1: // buffer_ = texture_->getBuffer(); buffer_->lock( Ogre::HardwareBuffer::HBL_DISCARD ); auto width = (unsigned int) geometry_.width(); auto height = (unsigned int) geometry_.height(); const Ogre::PixelBox _box = buffer_->getCurrentLock(); auto data = static_cast(pixel_box.data); int bytes_per_line = pixel_box.getWidth() * 4; // Empties the texture by overwriting all ARGB data with 0. Ogre::uint8 *offset = data; for (int i = 0; i < height; ++i) { memset(offset, 0, width * 4); offset += bytes_per_line; } paint_device_image_ = QImage(data, width, height, bytes_per_line, QImage::Format_ARGB32_Premultiplied); // Rendering stuff // ... buffer_->unlock(); buffer_.setNull(); // Approach 2: // // Initialization QSurfaceFormat format; format.setDepthBufferSize( 16 ); format.setStencilBufferSize( 8 ); context_ = new QOpenGLContext; context_->setFormat( format ); if ( !context_->create()) { LOG_ERROR( "OverlayManager: Fatal! Failed to create context!" ); } surface_ = new
[Interest] QtLocation MapPolyLine and MouseArea
Hi, I need to trigger various actions whenever a MapPolyLine is hovered or pressed, such as displaying a tooltip, a menu, etc. I have put a MouseArea on it with anchors.fills: parent, but the problem is that the mouse area does not represent the line, but the polygon made by the line. For instance if you have a L shape, entered event and so on is triggered when you enter the bounding rectangle of the line, not when you hover over the line itself. On a QGraphicsScene we had the shape() protected method for that kinds of case, for instance with a QPainterPathStroker to give some thickness to the line's "mousearea". I will probably end with a custom property that will carry the pixel distance between the line segments and the mouse coordinates, but this is going to be heavy to compute (I have potentially hundreds of complicated lines on the map). Is there a better way or even better a standard way to do that? Thanks Philippe Lelong ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
[Interest] PinchHandler weirdness
I have an issue which is reproducible only on android, but not on desktop. And looks like PinchHandler is the root cause (at least commenting it out changes behaviour). What is interesting, is that the issue happens without any interaction with pinch handler from my side. Just its presence under android make code behave differently. On desktop - not. Maybe because PinchHandler is disabled for desktop? Is it possible to trigger PinchHandler on desktop? Or maybe it is possible to capture pinch-handler related events on android to replay on desktop? ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest