Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Select by existing geometries (#45006)
[mesh] [feature] mesh select  element by existing selected polygon
  • Loading branch information
vcloarec committed Sep 10, 2021
1 parent 87d42af commit 4e0d0f6
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 49 deletions.
2 changes: 2 additions & 0 deletions images/images.qrc
Expand Up @@ -927,6 +927,8 @@
<file>themes/default/mActionMeshSelectExpression.svg</file>
<file>themes/default/mActionNewMeshLayer.svg</file>
<file>themes/default/mActionMeshTransformByExpression.svg</file>
<file>themes/default/mActionMeshSelectByTouchingGeometry.svg</file>
<file>themes/default/mActionMeshSelectByContainingGeometry.svg</file>
<file>themes/default/mIconVertexCoordinates.svg</file>
<file>themes/default/mActionMeshEditForceByVectorLines.svg</file>
<file>themes/default/mActionMeshReindex.svg</file>
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
172 changes: 125 additions & 47 deletions src/app/mesh/qgsmaptooleditmeshframe.cpp
Expand Up @@ -206,30 +206,41 @@ QgsMapToolEditMeshFrame::QgsMapToolEditMeshFrame( QgsMapCanvas *canvas )
: QgsMapToolAdvancedDigitizing( canvas, QgisApp::instance()->cadDockWidget() )
, mSnapIndicator( new QgsSnapIndicator( canvas ) )
{
mActionDigitizing = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshDigitizing.svg" ) ), tr( "Digitize mesh elements" ), this );
mActionDigitizing = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshDigitizing.svg" ) ), tr( "Digitize Mesh elements" ), this );
mActionDigitizing->setCheckable( true );
mActionSelectByPolygon = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshSelectPolygon.svg" ) ), tr( "Select mesh element by polygon" ), this );
mActionSelectByPolygon = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshSelectPolygon.svg" ) ), tr( "Select mesh elements by polygon" ), this );
mActionSelectByPolygon->setCheckable( true );
mActionSelectByExpression = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshSelectExpression.svg" ) ), tr( "Select mesh elements by expression" ), this );

mActionTransformCoordinates = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshTransformByExpression.svg" ) ), tr( "Transform vertices coordinates" ), this );
mActionSelectByPolygon = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshSelectPolygon.svg" ) ), tr( "Select Mesh Elements by Polygon" ), this );
mActionSelectByPolygon->setCheckable( true );
mActionSelectByPolygon->setObjectName( QStringLiteral( "ActionMeshSelectByPolygon" ) );
mActionSelectByExpression = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshSelectExpression.svg" ) ), tr( "Select Mesh Elements by Expression" ), this );
mActionSelectByExpression->setObjectName( QStringLiteral( "ActionMeshSelectByExpression" ) );
mActionSelectByContainingSelectedPolygon = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshSelectByContainingGeometry.svg" ) ), tr( "Select Contained Elements by Selected Polygons" ), this );
mActionSelectByTouchingSelectedPolygon = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshSelectByTouchingGeometry.svg" ) ), tr( "Select Touched Elements by Selected Polygons" ), this );
mActionSelectByContainingSelectedPolygon->setEnabled( false );
mActionSelectByTouchingSelectedPolygon->setEnabled( false );

mSelectActions << mActionSelectByPolygon
<< mActionSelectByExpression
<< mActionSelectByContainingSelectedPolygon
<< mActionSelectByTouchingSelectedPolygon;

mActionTransformCoordinates = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshTransformByExpression.svg" ) ), tr( "Transform Vertices Coordinates" ), this );
mActionTransformCoordinates->setCheckable( true );

mActionForceByVectorLayerGeometries = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshEditForceByVectorLines.svg" ) ), tr( "Force by selected geometries" ), this );
mActionForceByVectorLayerGeometries = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshEditForceByVectorLines.svg" ) ), tr( "Force by Selected Geometries" ), this );
mActionForceByVectorLayerGeometries->setEnabled( areGeometriesSelectedInVectorLayer() );

mWidgetActionForceByLine = new QgsMeshEditForceByLineAction( this );
mWidgetActionForceByLine->setMapCanvas( canvas );

mActionReindexMesh = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshReindex.svg" ) ), tr( "Reindex faces and vertices" ), this );
mActionReindexMesh = new QAction( QgsApplication::getThemePixmap( QStringLiteral( "/mActionMeshReindex.svg" ) ), tr( "Reindex Faces and Vertices" ), this );

mActionRemoveVerticesFillingHole = new QAction( this );
mActionDelaunayTriangulation = new QAction( tr( "Delaunay triangulation with selected vertices" ), this );
mActionFacesRefinement = new QAction( tr( "Refine current face" ), this );
mActionDelaunayTriangulation = new QAction( tr( "Delaunay Triangulation with Selected Vertices" ), this );
mActionFacesRefinement = new QAction( tr( "Refine Current Face" ), this );
mActionRemoveVerticesWithoutFillingHole = new QAction( this );
mActionRemoveFaces = new QAction( tr( "Remove current face" ), this );
mActionSplitFaces = new QAction( tr( "Split current face" ), this );
mActionRemoveFaces = new QAction( tr( "Remove Current Face" ), this );
mActionSplitFaces = new QAction( tr( "Split Current Face" ), this );

connect( mActionRemoveVerticesFillingHole, &QAction::triggered, this, [this] {removeSelectedVerticesFromMesh( true );} );
connect( mActionRemoveVerticesWithoutFillingHole, &QAction::triggered, this, [this] {removeSelectedVerticesFromMesh( false );} );
Expand All @@ -242,14 +253,30 @@ QgsMapToolEditMeshFrame::QgsMapToolEditMeshFrame( QgsMapCanvas *canvas )
activateWithState( Digitizing );
} );

connect( mActionSelectByPolygon, &QAction::toggled, this, [this]( bool checked )
for ( int i = 0; i < mSelectActions.count(); ++i )
{
if ( checked )
connect( mSelectActions.at( i ), &QAction::triggered, this, [i]
{
QgsSettings settings;
settings.setValue( QStringLiteral( "UI/Mesh/defaultSelection" ), i );
} );
}

connect( mActionSelectByPolygon, &QAction::triggered, this, [this]
{
if ( mActionSelectByPolygon->isChecked() )
{
activateWithState( SelectingByPolygon );
}
else
mSelectionBand->reset( QgsWkbTypes::PolygonGeometry );
} );


connect( mActionSelectByExpression, &QAction::triggered, this, &QgsMapToolEditMeshFrame::showSelectByExpressionDialog );
connect( mActionSelectByTouchingSelectedPolygon, &QAction::triggered, this, &QgsMapToolEditMeshFrame::selectByTouchingSelectedPolygons );
connect( mActionSelectByContainingSelectedPolygon, &QAction::triggered, this, &QgsMapToolEditMeshFrame::selectByContainingSelectedPolygons );

connect( mActionDelaunayTriangulation, &QAction::triggered, this, [this]
{
if ( mCurrentEditor && mSelectedVertices.count() >= 3 )
Expand Down Expand Up @@ -280,11 +307,12 @@ QgsMapToolEditMeshFrame::QgsMapToolEditMeshFrame( QgsMapCanvas *canvas )

connect( mActionTransformCoordinates, &QAction::triggered, this, &QgsMapToolEditMeshFrame::triggerTransformCoordinatesDockWidget );

connect( mActionSelectByExpression, &QAction::triggered, this, &QgsMapToolEditMeshFrame::showSelectByExpressionDialog );

connect( canvas, &QgsMapCanvas::selectionChanged, this, [this]
{
mActionForceByVectorLayerGeometries->setEnabled( areGeometriesSelectedInVectorLayer() &&( mCurrentEditor != nullptr ) );
bool enable = areGeometriesSelectedInVectorLayer() && ( mCurrentEditor != nullptr );
mActionForceByVectorLayerGeometries->setEnabled( enable );
mActionSelectByContainingSelectedPolygon->setEnabled( enable );
mActionSelectByTouchingSelectedPolygon->setEnabled( enable );
} );

connect( mActionForceByVectorLayerGeometries, &QAction::triggered, this, &QgsMapToolEditMeshFrame::forceBySelectedLayerPolyline );
Expand Down Expand Up @@ -330,7 +358,10 @@ void QgsMapToolEditMeshFrame::setActionsEnable( bool enable )
for ( QAction *action : std::as_const( actions ) )
action->setEnabled( enable );

mActionForceByVectorLayerGeometries->setEnabled( enable && areGeometriesSelectedInVectorLayer() );
bool areGeometriesSelected = areGeometriesSelectedInVectorLayer();
mActionForceByVectorLayerGeometries->setEnabled( enable && areGeometriesSelected );
mActionSelectByContainingSelectedPolygon->setEnabled( enable && areGeometriesSelected );
mActionSelectByTouchingSelectedPolygon->setEnabled( enable && areGeometriesSelected );
}


Expand All @@ -348,12 +379,18 @@ QAction *QgsMapToolEditMeshFrame::digitizeAction() const

QList<QAction *> QgsMapToolEditMeshFrame::selectActions() const
{
return QList<QAction *>()
<< mActionSelectByPolygon;
return mSelectActions;
}

QAction *QgsMapToolEditMeshFrame::defaultSelectActions() const
{
QgsSettings settings;
bool ok = false;
int defaultIndex = settings.value( QStringLiteral( "UI/Mesh/defaultSelection" ) ).toInt( &ok );

if ( ok && mSelectActions.at( defaultIndex )->isEnabled() )
return mSelectActions.at( defaultIndex );

return mActionSelectByPolygon;
}

Expand Down Expand Up @@ -926,7 +963,7 @@ void QgsMapToolEditMeshFrame::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
case Selecting:
{
QgsGeometry selectionGeom = mSelectionBand->asGeometry();
selectInGeometry( selectionGeom, e->modifiers() );
selectByGeometry( selectionGeom, e->modifiers() );
mSelectionBand->reset( QgsWkbTypes::PolygonGeometry );
mCurrentState = Digitizing;
}
Expand Down Expand Up @@ -967,7 +1004,7 @@ void QgsMapToolEditMeshFrame::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
else if ( e->button() == Qt::RightButton )
{
QgsGeometry selectionGeom = mSelectionBand->asGeometry();
selectInGeometry( selectionGeom, e->modifiers() );
selectByGeometry( selectionGeom, e->modifiers() );
mSelectionBand->reset( QgsWkbTypes::PolygonGeometry );
}
break;
Expand Down Expand Up @@ -1651,11 +1688,27 @@ void QgsMapToolEditMeshFrame::reindexMesh()
mCurrentLayer->reindex( transform, true );
}

void QgsMapToolEditMeshFrame::selectInGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers )
void QgsMapToolEditMeshFrame::selectByGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers )
{
if ( mCurrentLayer.isNull() || !mCurrentLayer->triangularMesh() || mCurrentEditor.isNull() )
return;

Qgis::SelectBehavior behavior;
if ( modifiers & Qt::ShiftModifier )
behavior = Qgis::SelectBehavior::RemoveFromSelection;
else if ( modifiers & Qt::ControlModifier )
behavior = Qgis::SelectBehavior::RemoveFromSelection;
else
behavior = Qgis::SelectBehavior::SetSelection;

if ( modifiers & Qt::AltModifier )
selectContainedByGeometry( geometry, behavior );
else
selectTouchedByGeometry( geometry, behavior );
}

void QgsMapToolEditMeshFrame::selectTouchedByGeometry( const QgsGeometry &geometry, Qgis::SelectBehavior behavior )
{
QSet<int> selectedVertices;
const QList<int> nativeFaceIndexes = mCurrentLayer->triangularMesh()->nativeFaceIndexForRectangle( geometry.boundingBox() );

Expand All @@ -1665,26 +1718,43 @@ void QgsMapToolEditMeshFrame::selectInGeometry( const QgsGeometry &geometry, Qt:
for ( const int faceIndex : nativeFaceIndexes )
{
const QgsMeshFace &face = nativeFace( faceIndex );
if ( !( modifiers & Qt::AltModifier ) )
std::unique_ptr<QgsPolygon> faceGeom( new QgsPolygon( new QgsLineString( nativeFaceGeometry( faceIndex ) ) ) );
if ( engine->intersects( faceGeom.get() ) )
{
std::unique_ptr<QgsPolygon> faceGeom( new QgsPolygon( new QgsLineString( nativeFaceGeometry( faceIndex ) ) ) );
if ( engine->intersects( faceGeom.get() ) )
{
QSet<int> faceToAdd = qgis::listToSet( face.toList() );
selectedVertices.unite( faceToAdd );
}
QSet<int> faceToAdd = qgis::listToSet( face.toList() );
selectedVertices.unite( faceToAdd );
}
else
}

const QList<int> &freeVerticesIndexes = mCurrentEditor->freeVerticesIndexes();
for ( const int freeVertexIndex : freeVerticesIndexes )
{
const QgsMeshVertex &vertex = mapVertex( freeVertexIndex );
if ( engine->contains( &vertex ) )
selectedVertices.insert( freeVertexIndex );
}

setSelectedVertices( selectedVertices.values(), behavior );
}

void QgsMapToolEditMeshFrame::selectContainedByGeometry( const QgsGeometry &geometry, Qgis::SelectBehavior behavior )
{
QSet<int> selectedVertices;
const QList<int> nativeFaceIndexes = mCurrentLayer->triangularMesh()->nativeFaceIndexForRectangle( geometry.boundingBox() );

std::unique_ptr<QgsGeometryEngine> engine( QgsGeometry::createGeometryEngine( geometry.constGet() ) );
engine->prepareGeometry();
for ( const int faceIndex : nativeFaceIndexes )
{
const QgsMeshFace &face = nativeFace( faceIndex );
for ( const int vertexIndex : face )
{
for ( const int vertexIndex : face )
{
const QgsMeshVertex &vertex = mapVertex( vertexIndex );
if ( engine->contains( &vertex ) )
selectedVertices.insert( vertexIndex );
}
const QgsMeshVertex &vertex = mapVertex( vertexIndex );
if ( engine->contains( &vertex ) )
selectedVertices.insert( vertexIndex );
}
}
//free vertices

const QList<int> &freeVerticesIndexes = mCurrentEditor->freeVerticesIndexes();
for ( const int freeVertexIndex : freeVerticesIndexes )
{
Expand All @@ -1693,17 +1763,25 @@ void QgsMapToolEditMeshFrame::selectInGeometry( const QgsGeometry &geometry, Qt:
selectedVertices.insert( freeVertexIndex );
}

Qgis::SelectBehavior behavior;
if ( modifiers & Qt::ShiftModifier )
behavior = Qgis::SelectBehavior::RemoveFromSelection;
else if ( modifiers & Qt::ControlModifier )
behavior = Qgis::SelectBehavior::RemoveFromSelection;
else
behavior = Qgis::SelectBehavior::SetSelection;

setSelectedVertices( selectedVertices.values(), behavior );
}

void QgsMapToolEditMeshFrame::selectByTouchingSelectedPolygons()
{
onEditingStarted();
const QList<QgsGeometry> geometries = selectedGeometriesInVectorLayers();
for ( const QgsGeometry &geom : geometries )
selectTouchedByGeometry( geom, Qgis::SelectBehavior::AddToSelection );
}

void QgsMapToolEditMeshFrame::selectByContainingSelectedPolygons()
{
onEditingStarted();
const QList<QgsGeometry> geometries = selectedGeometriesInVectorLayers();
for ( const QgsGeometry &geom : geometries )
selectContainedByGeometry( geom, Qgis::SelectBehavior::AddToSelection );
}

void QgsMapToolEditMeshFrame::applyZValueOnSelectedVertices()
{
if ( !mZValueWidget )
Expand Down Expand Up @@ -2412,7 +2490,6 @@ int QgsMapToolEditMeshFrame::closeVertex( const QgsPointXY &mapPoint ) const
return -1;
}


void QgsMapToolEditMeshFrame::selectByExpression( const QString &textExpression, Qgis::SelectBehavior behavior, QgsMesh::ElementType elementType )
{
if ( !mCurrentEditor || !mCurrentLayer )
Expand Down Expand Up @@ -2440,6 +2517,7 @@ void QgsMapToolEditMeshFrame::selectByExpression( const QString &textExpression,
}
}


void QgsMapToolEditMeshFrame::onZoomToSelected()
{
canvas()->zoomToFeatureExtent( mSelectedMapExtent );
Expand Down
10 changes: 9 additions & 1 deletion src/app/mesh/qgsmaptooleditmeshframe.h
Expand Up @@ -164,6 +164,8 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing

void showSelectByExpressionDialog();
void selectByExpression( const QString &textExpression, Qgis::SelectBehavior behavior, QgsMesh::ElementType elementType );
void selectByTouchingSelectedPolygons();
void selectByContainingSelectedPolygons();
void onZoomToSelected();
void forceBySelectedLayerPolyline();
void reindexMesh();
Expand Down Expand Up @@ -226,7 +228,9 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing
bool isFaceSelected( int faceIndex );
void setSelectedVertices( const QList<int> newSelectedVertices, Qgis::SelectBehavior behavior );
void setSelectedFaces( const QList<int> newSelectedFaces, Qgis::SelectBehavior behavior );
void selectInGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers );
void selectByGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers );
void selectTouchedByGeometry( const QgsGeometry &geometry, Qgis::SelectBehavior behavior );
void selectContainedByGeometry( const QgsGeometry &geometry, Qgis::SelectBehavior behavior );
void applyZValueOnSelectedVertices();
void prepareSelection();
void updateSelectecVerticesMarker();
Expand Down Expand Up @@ -282,6 +286,7 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing
QList<QgsVertexMarker *> mFreeVertexMarker;

//! members for selection of vertices/faces
QList<QAction *> mSelectActions;
QMap<int, SelectedVertexData> mSelectedVertices;
QgsRectangle mSelectedMapExtent;
QSet<int> mSelectedFaces;
Expand Down Expand Up @@ -333,6 +338,9 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing

QAction *mActionSelectByExpression = nullptr;
QAction *mActionForceByVectorLayerGeometries = nullptr;
QAction *mActionSelectByContainingSelectedPolygon = nullptr;
QAction *mActionSelectByTouchingSelectedPolygon = nullptr;

QgsMeshEditForceByLineAction *mWidgetActionForceByLine = nullptr;
QAction *mActionReindexMesh = nullptr;

Expand Down

0 comments on commit 4e0d0f6

Please sign in to comment.