From 93c80de908801930a86c6cdb9365fdb1d1e656bd Mon Sep 17 00:00:00 2001 From: Withalion Date: Fri, 7 Mar 2025 13:47:51 +0100 Subject: [PATCH 1/7] Fix line editing tool crash when used wrong --- src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp index ef46f567ad80..97b8a408fbb5 100644 --- a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp +++ b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp @@ -169,6 +169,8 @@ void Qgs3DMapToolPointCloudChangeAttributePolygon::run() if ( mToolType == AboveLine || mToolType == BelowLine ) { + if ( mScreenPoints.size() != 2 ) + return; const double y = mToolType == AboveLine ? 0 : mCanvas->height(); mScreenPoints.append( { QgsPointXY( mScreenPoints[1].x(), y ), QgsPointXY( mScreenPoints[0].x(), y ) } ); } From 7fc46005c9122bcb589885a5980707b7790f081e Mon Sep 17 00:00:00 2001 From: Withalion Date: Fri, 7 Mar 2025 13:56:47 +0100 Subject: [PATCH 2/7] Disable editing tool, when disabling editing in 3D --- src/app/3d/qgs3dmapcanvaswidget.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/3d/qgs3dmapcanvaswidget.cpp b/src/app/3d/qgs3dmapcanvaswidget.cpp index 09dcc5368079..e5b7646be34d 100644 --- a/src/app/3d/qgs3dmapcanvaswidget.cpp +++ b/src/app/3d/qgs3dmapcanvaswidget.cpp @@ -87,7 +87,10 @@ Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked ) mActionToggleEditing = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionToggleEditing.svg" ) ), tr( "Toggle editing" ), this ); mActionToggleEditing->setCheckable( true ); - connect( mActionToggleEditing, &QAction::triggered, this, [] { QgisApp::instance()->toggleEditing( QgisApp::instance()->activeLayer() ); } ); + connect( mActionToggleEditing, &QAction::triggered, this, [this] { + QgisApp::instance()->toggleEditing( QgisApp::instance()->activeLayer() ); + mCanvas->setMapTool( nullptr ); + } ); mActionUndo = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUndo.svg" ) ), tr( "Undo" ), this ); mActionRedo = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRedo.svg" ) ), tr( "Redo" ), this ); From 153bb0277de48bca433e86d0db133fa92a339518 Mon Sep 17 00:00:00 2001 From: Withalion Date: Fri, 7 Mar 2025 14:48:15 +0100 Subject: [PATCH 3/7] Add minimum size for paintbrush 3D editing tool --- .../3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp index dd02d64671e2..8d4233640e04 100644 --- a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp +++ b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp @@ -143,9 +143,12 @@ void Qgs3DMapToolPointCloudChangeAttributePaintbrush::mouseWheelEvent( QWheelEve const QgsSettings settings; const bool reverseZoom = settings.value( QStringLiteral( "qgis/reverse_wheel_zoom" ), false ).toBool(); const bool shrink = reverseZoom ? event->angleDelta().y() < 0 : event->angleDelta().y() > 0; + if ( shrink && mSelectionRubberBand->width() <= 5 ) + return; // "Normal" mouse have an angle delta of 120, precision mouses provide data faster, in smaller steps const double zoomFactor = ( shrink ? 0.8 : 1.25 ) / 120.0 * std::fabs( event->angleDelta().y() ); - mSelectionRubberBand->setWidth( mSelectionRubberBand->width() * zoomFactor ); + const float newWidth = mSelectionRubberBand->width() * zoomFactor < 5 ? 5 : mSelectionRubberBand->width() * static_cast( zoomFactor ); + mSelectionRubberBand->setWidth( newWidth ); } void Qgs3DMapToolPointCloudChangeAttributePaintbrush::keyPressEvent( QKeyEvent *event ) From edae588593410cbe93dba098a6dfb80f33fad2da Mon Sep 17 00:00:00 2001 From: Withalion Date: Fri, 7 Mar 2025 20:26:06 +0100 Subject: [PATCH 4/7] Fix paintbrush editing tool movement --- src/3d/qgs3dmapcanvas.cpp | 3 +++ src/3d/qgs3dmaptool.cpp | 5 +++++ src/3d/qgs3dmaptool.h | 2 ++ src/app/3d/qgs3dmapcanvaswidget.cpp | 1 + ...aptoolpointcloudchangeattributepaintbrush.cpp | 16 ++++++++++++---- ...dmaptoolpointcloudchangeattributepaintbrush.h | 1 + 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/3d/qgs3dmapcanvas.cpp b/src/3d/qgs3dmapcanvas.cpp index dc920edafab2..c45b00aef7e5 100644 --- a/src/3d/qgs3dmapcanvas.cpp +++ b/src/3d/qgs3dmapcanvas.cpp @@ -300,6 +300,9 @@ bool Qgs3DMapCanvas::eventFilter( QObject *watched, QEvent *event ) case QEvent::KeyPress: mMapTool->keyPressEvent( static_cast( event ) ); break; + case QEvent::KeyRelease: + mMapTool->keyReleaseEvent( static_cast( event ) ); + break; case QEvent::Wheel: mMapTool->mouseWheelEvent( static_cast( event ) ); break; diff --git a/src/3d/qgs3dmaptool.cpp b/src/3d/qgs3dmaptool.cpp index 1a68a553a4b3..f82a45af3797 100644 --- a/src/3d/qgs3dmaptool.cpp +++ b/src/3d/qgs3dmaptool.cpp @@ -44,6 +44,11 @@ void Qgs3DMapTool::keyPressEvent( QKeyEvent *event ) Q_UNUSED( event ) } +void Qgs3DMapTool::keyReleaseEvent( QKeyEvent *event ) +{ + Q_UNUSED( event ) +} + void Qgs3DMapTool::mouseWheelEvent( QWheelEvent *event ) { Q_UNUSED( event ) diff --git a/src/3d/qgs3dmaptool.h b/src/3d/qgs3dmaptool.h index cc9713caba3a..b15c51ff04b4 100644 --- a/src/3d/qgs3dmaptool.h +++ b/src/3d/qgs3dmaptool.h @@ -50,6 +50,8 @@ class _3D_EXPORT Qgs3DMapTool : public QObject virtual void mouseMoveEvent( QMouseEvent *event ); //! Reimplement to handle key press \a event forwarded by the parent Qgs3DMapCanvas virtual void keyPressEvent( QKeyEvent *event ); + //! Reimplement to handle key release \a event forwarded by the parent Qgs3DMapCanvas + virtual void keyReleaseEvent( QKeyEvent *event ); //! Reimplement to handle mouse wheel \a event forwarded by the parent Qgs3DMapCanvas virtual void mouseWheelEvent( QWheelEvent *event ); diff --git a/src/app/3d/qgs3dmapcanvaswidget.cpp b/src/app/3d/qgs3dmapcanvaswidget.cpp index e5b7646be34d..11e3ae6d5d5e 100644 --- a/src/app/3d/qgs3dmapcanvaswidget.cpp +++ b/src/app/3d/qgs3dmapcanvaswidget.cpp @@ -484,6 +484,7 @@ void Qgs3DMapCanvasWidget::changePointCloudAttributeByPaintbrush() if ( !action ) return; + mCanvas->requestActivate(); mCanvas->setMapTool( nullptr ); mMapToolChangeAttribute.reset( new Qgs3DMapToolPointCloudChangeAttributePaintbrush( mCanvas ) ); onPointCloudChangeAttributeSettingsChanged(); diff --git a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp index 8d4233640e04..1960bd7c0998 100644 --- a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp +++ b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp @@ -158,10 +158,18 @@ void Qgs3DMapToolPointCloudChangeAttributePaintbrush::keyPressEvent( QKeyEvent * restart(); } - if ( !mIsClicked && event->key() == Qt::Key_Space ) + if ( event->key() == Qt::Key_Space && !event->isAutoRepeat() ) { - const bool newState = !mCanvas->cameraController()->hasInputHandlersEnabled(); - mCanvas->cameraController()->setInputHandlersEnabled( newState ); - mIsMoving = newState; + mCanvas->cameraController()->setInputHandlersEnabled( true ); + mIsMoving = true; + } +} + +void Qgs3DMapToolPointCloudChangeAttributePaintbrush::keyReleaseEvent( QKeyEvent *event ) +{ + if ( event->key() == Qt::Key_Space && !event->isAutoRepeat() ) + { + mCanvas->cameraController()->setInputHandlersEnabled( false ); + mIsMoving = false; } } diff --git a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.h b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.h index d7b6ab479daf..a42fd11d142f 100644 --- a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.h +++ b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.h @@ -42,6 +42,7 @@ class Qgs3DMapToolPointCloudChangeAttributePaintbrush : public Qgs3DMapToolPoint void mouseMoveEvent( QMouseEvent *event ) override; void mouseWheelEvent( QWheelEvent *event ) override; void keyPressEvent( QKeyEvent *event ) override; + void keyReleaseEvent( QKeyEvent *event ) override; private: void run() override; From 35b38dac18555afedfd2bde5241da3459fbebf9b Mon Sep 17 00:00:00 2001 From: Withalion Date: Fri, 7 Mar 2025 23:21:28 +0100 Subject: [PATCH 5/7] Fix build issue & crash on closing 3D window Fixes msvc build issue caused by uniqueqobject pointer, we revert back to raw pointers. Fixes QGIS crash on 3D window closed when editing tools are selected. We can't delete QgsRubberBand3D entities from this class as they are owned by RubberBandRootEntity, which deletes them on windows close. Only point rubberbands leave artifacts in scene whene deleted by default destructor. --- src/3d/qgsrubberband3d.cpp | 11 ++----- src/app/3d/qgs3dmapcanvaswidget.cpp | 31 ++++++++----------- src/app/3d/qgs3dmapcanvaswidget.h | 2 +- ...oolpointcloudchangeattributepaintbrush.cpp | 2 ++ 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/3d/qgsrubberband3d.cpp b/src/3d/qgsrubberband3d.cpp index 8b28fa23cfba..85d76b799a9a 100644 --- a/src/3d/qgsrubberband3d.cpp +++ b/src/3d/qgsrubberband3d.cpp @@ -140,15 +140,8 @@ void QgsRubberBand3D::setupPolygon( Qt3DCore::QEntity *parentEntity ) mPolygonEntity->addComponent( mPolygonMaterial ); } -QgsRubberBand3D::~QgsRubberBand3D() -{ - if ( mPolygonEntity ) - mPolygonEntity->deleteLater(); - if ( mLineEntity ) - mLineEntity->deleteLater(); - if ( mMarkerEntity ) - mMarkerEntity->deleteLater(); -} +QgsRubberBand3D::~QgsRubberBand3D() = default; + float QgsRubberBand3D::width() const { diff --git a/src/app/3d/qgs3dmapcanvaswidget.cpp b/src/app/3d/qgs3dmapcanvaswidget.cpp index 11e3ae6d5d5e..ba9d56975496 100644 --- a/src/app/3d/qgs3dmapcanvaswidget.cpp +++ b/src/app/3d/qgs3dmapcanvaswidget.cpp @@ -309,7 +309,7 @@ Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked ) mMapToolMeasureLine = new Qgs3DMapToolMeasureLine( mCanvas ); - mMapToolChangeAttribute.reset( new Qgs3DMapToolPointCloudChangeAttribute( mCanvas ) ); + mMapToolChangeAttribute = new Qgs3DMapToolPointCloudChangeAttribute( mCanvas ); mLabelPendingJobs = new QLabel( this ); mProgressPendingJobs = new QProgressBar( this ); @@ -418,11 +418,6 @@ Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked ) Qgs3DMapCanvasWidget::~Qgs3DMapCanvasWidget() { delete mDockableWidgetHelper; - // we don't want canvas to reset the map tool as it is managed by unique_ptr - if ( mMapToolChangeAttribute.get() == mCanvas->mapTool() ) - { - mCanvas->setMapTool( nullptr ); - } } void Qgs3DMapCanvasWidget::saveAsImage() @@ -485,10 +480,10 @@ void Qgs3DMapCanvasWidget::changePointCloudAttributeByPaintbrush() return; mCanvas->requestActivate(); - mCanvas->setMapTool( nullptr ); - mMapToolChangeAttribute.reset( new Qgs3DMapToolPointCloudChangeAttributePaintbrush( mCanvas ) ); + mMapToolChangeAttribute->deleteLater(); + mMapToolChangeAttribute = new Qgs3DMapToolPointCloudChangeAttributePaintbrush( mCanvas ); onPointCloudChangeAttributeSettingsChanged(); - mCanvas->setMapTool( mMapToolChangeAttribute.get() ); + mCanvas->setMapTool( mMapToolChangeAttribute ); mEditingToolsAction->setIcon( action->icon() ); } @@ -498,10 +493,10 @@ void Qgs3DMapCanvasWidget::changePointCloudAttributeByPolygon() if ( !action ) return; - mCanvas->setMapTool( nullptr ); - mMapToolChangeAttribute.reset( new Qgs3DMapToolPointCloudChangeAttributePolygon( mCanvas, Qgs3DMapToolPointCloudChangeAttributePolygon::Polygon ) ); + mMapToolChangeAttribute->deleteLater(); + mMapToolChangeAttribute = new Qgs3DMapToolPointCloudChangeAttributePolygon( mCanvas, Qgs3DMapToolPointCloudChangeAttributePolygon::Polygon ); onPointCloudChangeAttributeSettingsChanged(); - mCanvas->setMapTool( mMapToolChangeAttribute.get() ); + mCanvas->setMapTool( mMapToolChangeAttribute ); mEditingToolsAction->setIcon( action->icon() ); } @@ -511,10 +506,10 @@ void Qgs3DMapCanvasWidget::changePointCloudAttributeByAboveLine() if ( !action ) return; - mCanvas->setMapTool( nullptr ); - mMapToolChangeAttribute.reset( new Qgs3DMapToolPointCloudChangeAttributePolygon( mCanvas, Qgs3DMapToolPointCloudChangeAttributePolygon::AboveLine ) ); + mMapToolChangeAttribute->deleteLater(); + mMapToolChangeAttribute = new Qgs3DMapToolPointCloudChangeAttributePolygon( mCanvas, Qgs3DMapToolPointCloudChangeAttributePolygon::AboveLine ); onPointCloudChangeAttributeSettingsChanged(); - mCanvas->setMapTool( mMapToolChangeAttribute.get() ); + mCanvas->setMapTool( mMapToolChangeAttribute ); mEditingToolsAction->setIcon( action->icon() ); } @@ -524,10 +519,10 @@ void Qgs3DMapCanvasWidget::changePointCloudAttributeByBelowLine() if ( !action ) return; - mCanvas->setMapTool( nullptr ); - mMapToolChangeAttribute.reset( new Qgs3DMapToolPointCloudChangeAttributePolygon( mCanvas, Qgs3DMapToolPointCloudChangeAttributePolygon::BelowLine ) ); + mMapToolChangeAttribute->deleteLater(); + mMapToolChangeAttribute = new Qgs3DMapToolPointCloudChangeAttributePolygon( mCanvas, Qgs3DMapToolPointCloudChangeAttributePolygon::BelowLine ); onPointCloudChangeAttributeSettingsChanged(); - mCanvas->setMapTool( mMapToolChangeAttribute.get() ); + mCanvas->setMapTool( mMapToolChangeAttribute ); mEditingToolsAction->setIcon( action->icon() ); } diff --git a/src/app/3d/qgs3dmapcanvaswidget.h b/src/app/3d/qgs3dmapcanvaswidget.h index d73c3238350e..d681937a0e16 100644 --- a/src/app/3d/qgs3dmapcanvaswidget.h +++ b/src/app/3d/qgs3dmapcanvaswidget.h @@ -143,7 +143,7 @@ class APP_EXPORT Qgs3DMapCanvasWidget : public QWidget QTimer *mLabelNavSpeedHideTimeout = nullptr; Qgs3DMapToolIdentify *mMapToolIdentify = nullptr; Qgs3DMapToolMeasureLine *mMapToolMeasureLine = nullptr; - QObjectUniquePtr mMapToolChangeAttribute; + Qgs3DMapToolPointCloudChangeAttribute *mMapToolChangeAttribute = nullptr; std::unique_ptr mMapToolExtent; QgsMapTool *mMapToolPrevious = nullptr; QMenu *mExportMenu = nullptr; diff --git a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp index 1960bd7c0998..9b1262534f1e 100644 --- a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp +++ b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepaintbrush.cpp @@ -62,6 +62,8 @@ void Qgs3DMapToolPointCloudChangeAttributePaintbrush::activate() void Qgs3DMapToolPointCloudChangeAttributePaintbrush::deactivate() { restart(); + // this makes sure there are no leftover artifacts when switching from paintbrush tool to another + mSelectionRubberBand->setMarkersEnabled( false ); mSelectionRubberBand.reset(); mIsActive = false; mCanvas->cameraController()->setInputHandlersEnabled( true ); From 9303315b4b203b8bf3f5c45efb2b10b4b7e221ea Mon Sep 17 00:00:00 2001 From: Withalion Date: Mon, 10 Mar 2025 14:17:31 +0100 Subject: [PATCH 6/7] Keep 3D editing toolbar position on closing --- src/app/3d/qgs3dmapcanvaswidget.cpp | 15 +++++++++++++-- src/app/3d/qgs3dmapcanvaswidget.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/app/3d/qgs3dmapcanvaswidget.cpp b/src/app/3d/qgs3dmapcanvaswidget.cpp index ba9d56975496..90d5c982d7b4 100644 --- a/src/app/3d/qgs3dmapcanvaswidget.cpp +++ b/src/app/3d/qgs3dmapcanvaswidget.cpp @@ -80,7 +80,6 @@ Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked ) // Editing toolbar mEditingToolBar = new QToolBar( this ); mEditingToolBar->setWindowTitle( tr( "Editing Toolbar" ) ); - mEditingToolBar->setVisible( false ); mEditingToolsMenu = new QMenu( this ); mPointCloudEditingToolbar = new QToolBar( this ); @@ -123,8 +122,12 @@ Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked ) mClassValidator = new ClassValidator( this ); mCboChangeAttributeValueAction = mPointCloudEditingToolbar->addWidget( mCboChangeAttributeValue ); - QAction *actionEditingToolbar = toolBar->addAction( QIcon( QgsApplication::iconPath( "mIconPointCloudLayer.svg" ) ), tr( "Show Editing Toolbar" ), this, [this] { mEditingToolBar->setVisible( !mEditingToolBar->isVisible() ); } ); + QAction *actionEditingToolbar = toolBar->addAction( QIcon( QgsApplication::iconPath( "mIconPointCloudLayer.svg" ) ), tr( "Show Editing Toolbar" ) ); actionEditingToolbar->setCheckable( true ); + actionEditingToolbar->setChecked( + setting.value( QStringLiteral( "/3D/editingToolbar/visibility" ), false, QgsSettings::Gui ).toBool() + ); + connect( actionEditingToolbar, &QAction::toggled, this, &Qgs3DMapCanvasWidget::toggleEditingToolbar ); connect( mCboChangeAttribute, qOverload( &QComboBox::currentIndexChanged ), this, [this]( int ) { onPointCloudChangeAttributeSettingsChanged(); } ); connect( mCboChangeAttributeValue, qOverload( &QComboBox::currentTextChanged ), this, [this]( const QString &text ) { double newValue = 0; @@ -395,6 +398,7 @@ Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked ) } ); updateLayerRelatedActions( QgisApp::instance()->activeLayer() ); + mEditingToolBar->setVisible( setting.value( QStringLiteral( "/3D/editingToolbar/visibility" ), false, QgsSettings::Gui ).toBool() ); QList toolbarMenuActions; // Set action names so that they can be used in customization @@ -611,6 +615,13 @@ void Qgs3DMapCanvasWidget::toggleNavigationWidget( const bool visibility ) setting.setValue( QStringLiteral( "/3D/navigationWidget/visibility" ), visibility, QgsSettings::Gui ); } +void Qgs3DMapCanvasWidget::toggleEditingToolbar( const bool visibility ) +{ + mEditingToolBar->setVisible( visibility ); + QgsSettings setting; + setting.setValue( QStringLiteral( "/3D/editingToolbar/visibility" ), visibility, QgsSettings::Gui ); +} + void Qgs3DMapCanvasWidget::toggleFpsCounter( const bool visibility ) { mLabelFpsCounter->setVisible( visibility ); diff --git a/src/app/3d/qgs3dmapcanvaswidget.h b/src/app/3d/qgs3dmapcanvaswidget.h index d681937a0e16..37e4d6fe24d6 100644 --- a/src/app/3d/qgs3dmapcanvaswidget.h +++ b/src/app/3d/qgs3dmapcanvaswidget.h @@ -108,6 +108,7 @@ class APP_EXPORT Qgs3DMapCanvasWidget : public QWidget void changePointCloudAttributeByBelowLine(); void exportScene(); void toggleNavigationWidget( bool visibility ); + void toggleEditingToolbar( bool visibility ); void toggleFpsCounter( bool visibility ); void toggleDebugWidget( bool visibility ) const; void toggleDebugWidget() const; From 4049525d0ea36a4f590652e2d6ffa232030edb0e Mon Sep 17 00:00:00 2001 From: Withalion Date: Wed, 12 Mar 2025 10:30:27 +0100 Subject: [PATCH 7/7] Finish editing when 2. point selected with line tool --- src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp index 97b8a408fbb5..e062d02f3842 100644 --- a/src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp +++ b/src/app/3d/qgs3dmaptoolpointcloudchangeattributepolygon.cpp @@ -126,6 +126,11 @@ void Qgs3DMapToolPointCloudChangeAttributePolygon::mouseReleaseEvent( QMouseEven mPolygonRubberBand->addPoint( screenEdgePoint ); mPolygonRubberBand->addPoint( newPoint ); } + else if ( mScreenPoints.size() == 2 ) + { + run(); + restart(); + } } } else if ( event->button() == Qt::RightButton )