Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[3d] Fix missing rubber bands when measuring (fixes #34630)
This fix also introduces a helper class QgsRubberBand3D to handle rubber bands in 3D, similar to how QgsRubberBand is used in 2D map canvas. Avoids addition of a temporary vector layer only used for measurement purposes, which was confusing. Also fixes unreported crash when user removed the measurement layer after it was added and the tool was used again.
- Loading branch information
1 parent
c62c133
commit de79264
Showing
5 changed files
with
241 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/*************************************************************************** | ||
qgsrubberband3d.cpp | ||
-------------------------------------- | ||
Date : June 2021 | ||
Copyright : (C) 2021 by Martin Dobias | ||
Email : wonder dot sk at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#include "qgsrubberband3d.h" | ||
|
||
#include "qgslinevertexdata_p.h" | ||
#include "qgsabstractmaterialsettings.h" | ||
#include "qgslinematerial_p.h" | ||
#include "qgsphongmaterialsettings.h" | ||
|
||
#include "qgslinestring.h" | ||
|
||
#include <Qt3DCore/QEntity> | ||
#include <Qt3DRender/QAttribute> | ||
#include <Qt3DRender/QBuffer> | ||
#include <Qt3DRender/QGeometry> | ||
#include <Qt3DRender/QGeometryRenderer> | ||
#include <Qt3DRender/QMaterial> | ||
|
||
|
||
/// @cond PRIVATE | ||
|
||
|
||
QgsRubberBand3D::QgsRubberBand3D( Qgs3DMapSettings &map, Qt3DCore::QEntity *parentEntity ) | ||
{ | ||
mMapSettings = ↦ | ||
|
||
mEntity = new Qt3DCore::QEntity( parentEntity ); | ||
|
||
QgsLineVertexData dummyLineData; | ||
mGeometry = dummyLineData.createGeometry( mEntity ); | ||
|
||
Q_ASSERT( mGeometry->attributes().count() == 2 ); | ||
mPositionAttribute = mGeometry->attributes()[0]; | ||
mIndexAttribute = mGeometry->attributes()[1]; | ||
|
||
mGeomRenderer = new Qt3DRender::QGeometryRenderer; | ||
mGeomRenderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStripAdjacency ); | ||
mGeomRenderer->setGeometry( mGeometry ); | ||
mGeomRenderer->setPrimitiveRestartEnabled( true ); | ||
mGeomRenderer->setRestartIndexValue( 0 ); | ||
|
||
mEntity->addComponent( mGeomRenderer ); | ||
|
||
mLineMaterial = new QgsLineMaterial; | ||
mLineMaterial->setLineWidth( 3 ); | ||
mLineMaterial->setLineColor( Qt::red ); | ||
mLineMaterial->setViewportSize( QSize( 200, 200 ) ); // TODO: based on viewport size! | ||
|
||
mEntity->addComponent( mLineMaterial ); | ||
} | ||
|
||
QgsRubberBand3D::~QgsRubberBand3D() | ||
{ | ||
delete mEntity; | ||
} | ||
|
||
float QgsRubberBand3D::width() const | ||
{ | ||
return mLineMaterial->lineWidth(); | ||
} | ||
|
||
void QgsRubberBand3D::setWidth( float width ) | ||
{ | ||
mLineMaterial->setLineWidth( width ); | ||
} | ||
|
||
QColor QgsRubberBand3D::color() const | ||
{ | ||
return mLineMaterial->lineColor(); | ||
} | ||
|
||
void QgsRubberBand3D::setColor( QColor color ) | ||
{ | ||
mLineMaterial->setLineColor( color ); | ||
} | ||
|
||
void QgsRubberBand3D::reset() | ||
{ | ||
mLineString.clear(); | ||
updateGeometry(); | ||
} | ||
|
||
void QgsRubberBand3D::addPoint( const QgsPoint &pt ) | ||
{ | ||
mLineString.addVertex( pt ); | ||
updateGeometry(); | ||
} | ||
|
||
void QgsRubberBand3D::removeLastPoint() | ||
{ | ||
int lastVertexIndex = mLineString.numPoints() - 1; | ||
mLineString.deleteVertex( QgsVertexId( 0, 0, lastVertexIndex ) ); | ||
updateGeometry(); | ||
} | ||
|
||
void QgsRubberBand3D::updateGeometry() | ||
{ | ||
QgsLineVertexData lineData; | ||
lineData.withAdjacency = true; | ||
lineData.init( Qgs3DTypes::AltClampAbsolute, Qgs3DTypes::AltBindVertex, 0, mMapSettings ); | ||
lineData.addLineString( mLineString ); | ||
|
||
mPositionAttribute->buffer()->setData( lineData.createVertexBuffer() ); | ||
mIndexAttribute->buffer()->setData( lineData.createIndexBuffer() ); | ||
mGeomRenderer->setVertexCount( lineData.indexes.count() ); | ||
} | ||
|
||
/// @endcond |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/*************************************************************************** | ||
qgsrubberband3d.h | ||
-------------------------------------- | ||
Date : June 2021 | ||
Copyright : (C) 2021 by Martin Dobias | ||
Email : wonder dot sk at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#ifndef QGSRUBBERBAND3D_H | ||
#define QGSRUBBERBAND3D_H | ||
|
||
#include "qgis_3d.h" | ||
|
||
#define SIP_NO_FILE | ||
|
||
/// @cond PRIVATE | ||
|
||
// | ||
// W A R N I N G | ||
// ------------- | ||
// | ||
// This file is not part of the QGIS API. It exists purely as an | ||
// implementation detail. This header file may change from version to | ||
// version without notice, or even be removed. | ||
// | ||
|
||
#include "qgslinestring.h" | ||
|
||
class QgsLineMaterial; | ||
class Qgs3DMapSettings; | ||
|
||
namespace Qt3DCore | ||
{ | ||
class QEntity; | ||
} | ||
namespace Qt3DRender | ||
{ | ||
class QGeometry; | ||
class QGeometryRenderer; | ||
class QBuffer; | ||
class QMaterial; | ||
class QAttribute; | ||
} | ||
|
||
/** | ||
* \ingroup 3d | ||
* Rubber band implementation for use in 3D map views. | ||
* | ||
* Coordinates are expected to be passed in map CRS and the 3D entity generated by this | ||
* class will be attached to the parentEntity given in the constructor (normally this | ||
* should be the root entity, i.e. map scene object). | ||
* | ||
* \note Currently only supports linestring geometry. | ||
* \since QGIS 3.20 | ||
*/ | ||
class _3D_EXPORT QgsRubberBand3D | ||
{ | ||
public: | ||
QgsRubberBand3D( Qgs3DMapSettings &map, Qt3DCore::QEntity *parentEntity ); | ||
~QgsRubberBand3D(); | ||
|
||
float width() const; | ||
void setWidth( float width ); | ||
|
||
QColor color() const; | ||
void setColor( QColor color ); | ||
|
||
void reset(); | ||
|
||
void addPoint( const QgsPoint &pt ); | ||
|
||
void removeLastPoint(); | ||
|
||
private: | ||
void updateGeometry(); | ||
|
||
private: | ||
QgsLineString mLineString; | ||
|
||
Qgs3DMapSettings *mMapSettings = nullptr; // not owned | ||
|
||
Qt3DCore::QEntity *mEntity = nullptr; // owned by parentEntity (from constructor) | ||
|
||
// all these are owned by mEntity | ||
Qt3DRender::QGeometryRenderer *mGeomRenderer = nullptr; | ||
Qt3DRender::QGeometry *mGeometry = nullptr; | ||
Qt3DRender::QAttribute *mPositionAttribute = nullptr; | ||
Qt3DRender::QAttribute *mIndexAttribute = nullptr; | ||
QgsLineMaterial *mLineMaterial = nullptr; | ||
}; | ||
|
||
/// @endcond | ||
|
||
#endif // QGSRUBBERBAND3D_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.