Skip to content
Permalink
Browse files
reindex/renumbering mesh layer (#44969)
[mesh] [feature] reindex/renumbering mesh layer

Co-authored-by: PeterPetrik <zilolv@gmail.com>
  • Loading branch information
vcloarec and PeterPetrik committed Sep 9, 2021
1 parent e84f013 commit be3a9e75640951a19111dc4547e551a58ded480e
@@ -929,6 +929,7 @@
<file>themes/default/mActionMeshTransformByExpression.svg</file>
<file>themes/default/mIconVertexCoordinates.svg</file>
<file>themes/default/mActionMeshEditForceByVectorLines.svg</file>
<file>themes/default/mActionMeshReindex.svg</file>
<file>themes/default/mIconGeometryCollectionLayer.svg</file>
<file>themes/default/mIconGps.svg</file>
<file>themes/default/mActionNewGpx.svg</file>
@@ -0,0 +1 @@
<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m14.556915 5.3891781-6.2013474 6.2974509m0-6.2974509 6.2013474 6.2974509m-6.4832274-6.5836985h6.7651074v6.8699455h-6.7651074z" fill="none" stroke="#5b6775" stroke-linecap="round" stroke-width="1.001834"/><g style="font-weight:bold;font-size:8.521494;font-family:FreeSans;letter-spacing:0;word-spacing:0;fill:#505050" transform="scale(1.0164779 .98378922)"><text x=".875224" y="11.377851"><tspan font-size="11.504018" x=".875224" y="11.377851">1</tspan></text><text x="15.869693" y="15.30352"><tspan font-size="11.504018" x="15.869693" y="15.30352">2</tspan></text><text x="6.831705" y="22.544098"><tspan font-size="11.504018" x="6.831705" y="22.544098">3</tspan></text></g></svg>
@@ -170,6 +170,15 @@ Returns the extent of the edited mesh
Returns whether the mesh has been modified
%End

bool reindex( bool renumbering );
%Docstring
Reindexes the mesh, that is remove unusued index of face and vertices, this operation void the undo/redo stack.

If ``renumbering`` is true, a renumbering is operated to optimize the vertices indexes.

Returns ``False`` if the operation fail.
%End


QList<int> freeVerticesIndexes() const;
%Docstring
@@ -768,6 +768,17 @@ Stops edition of the mesh, re-indexes the faces and vertices,
rebuilds the triangular mesh and its spatial index with ``transform``,
clean the undostack

.. versionadded:: 3.22
%End

bool reindex( const QgsCoordinateTransform &transform, bool renumber );
%Docstring
Re-indexes the faces and vertices, and renumber the indexes if ``renumber`` is ``True``.
rebuilds the triangular mesh and its spatial index with ``transform``,
clean the undostack

Returns ``False`` if the operation fails

.. versionadded:: 3.22
%End

@@ -15,6 +15,8 @@
***************************************************************************/
#include "qgsmaptooleditmeshframe.h"

#include <QMessageBox>

#include "qgis.h"
#include "qgisapp.h"
#include "qgsapplication.h"
@@ -220,6 +222,8 @@ QgsMapToolEditMeshFrame::QgsMapToolEditMeshFrame( QgsMapCanvas *canvas )
mWidgetActionForceByLine = new QgsMeshEditForceByLineAction( this );
mWidgetActionForceByLine->setMapCanvas( canvas );

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 );
@@ -275,6 +279,7 @@ QgsMapToolEditMeshFrame::QgsMapToolEditMeshFrame( QgsMapCanvas *canvas )
} );

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

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

connect( canvas, &QgsMapCanvas::selectionChanged, this, [this]
@@ -284,6 +289,8 @@ QgsMapToolEditMeshFrame::QgsMapToolEditMeshFrame( QgsMapCanvas *canvas )

connect( mActionForceByVectorLayerGeometries, &QAction::triggered, this, &QgsMapToolEditMeshFrame::forceBySelectedLayerPolyline );

connect( mActionReindexMesh, &QAction::triggered, this, &QgsMapToolEditMeshFrame::reindexMesh );

setAutoSnapEnabled( true );
}

@@ -317,7 +324,8 @@ void QgsMapToolEditMeshFrame::setActionsEnable( bool enable )
<< mActionSelectByPolygon
<< mActionSelectByExpression
<< mActionTransformCoordinates
<< mActionForceByVectorLayerGeometries;
<< mActionForceByVectorLayerGeometries
<< mActionReindexMesh;

for ( QAction *action : std::as_const( actions ) )
action->setEnabled( enable );
@@ -1623,6 +1631,26 @@ void QgsMapToolEditMeshFrame::forceBySelectedLayerPolyline()
}


void QgsMapToolEditMeshFrame::reindexMesh()
{
if ( !mCurrentLayer || !mCurrentLayer->isEditable() )
return;

onEditingStarted();

if ( QMessageBox::question( canvas(), tr( "Reindex the Mesh" ),
tr( "Do you want to reindex the faces and vertices of the mesh layer %1?" ).arg( mCurrentLayer->name() ),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No )
== QMessageBox::No )
return;


QgsCoordinateTransform transform( mCurrentLayer->crs(), canvas()->mapSettings().destinationCrs(), QgsProject::instance() );

QgsTemporaryCursorOverride waitCursor( Qt::WaitCursor );
mCurrentLayer->reindex( transform, true );
}

void QgsMapToolEditMeshFrame::selectInGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers )
{
if ( mCurrentLayer.isNull() || !mCurrentLayer->triangularMesh() || mCurrentEditor.isNull() )
@@ -166,6 +166,7 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing
void selectByExpression( const QString &textExpression, Qgis::SelectBehavior behavior, QgsMesh::ElementType elementType );
void onZoomToSelected();
void forceBySelectedLayerPolyline();
void reindexMesh();

private:

@@ -333,6 +334,7 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing
QAction *mActionSelectByExpression = nullptr;
QAction *mActionForceByVectorLayerGeometries = nullptr;
QgsMeshEditForceByLineAction *mWidgetActionForceByLine = nullptr;
QAction *mActionReindexMesh = nullptr;

friend class TestQgsMapToolEditMesh;
};
@@ -61,6 +61,10 @@ QgsMeshEditingError QgsMeshEditor::initialize()
return error;
}

void QgsMeshEditor::resetTriangularMesh( QgsTriangularMesh *triangularMesh )
{
mTriangularMesh = triangularMesh;
}

bool QgsMeshEditor::isFaceGeometricallyCompatible( const QgsMeshFace &face )
{
@@ -777,6 +781,28 @@ bool QgsMeshEditor::isModified() const
return false;
}

bool QgsMeshEditor::reindex( bool renumbering )
{
mTopologicalMesh.reindex();
mUndoStack->clear();
QgsMeshEditingError error = initialize();

if ( error.errorType != Qgis::MeshEditingErrorType::NoError )
return false;

if ( renumbering )
{
if ( !mTopologicalMesh.renumber() )
return false;

QgsMeshEditingError error = initialize();
return error.errorType == Qgis::MeshEditingErrorType::NoError;
}

else
return true;
}

QList<int> QgsMeshEditor::freeVerticesIndexes() const
{
return mTopologicalMesh.freeVerticesIndexes();
@@ -69,13 +69,16 @@ class CORE_EXPORT QgsMeshEditor : public QObject
//! Constructor with a specified layer \a meshLayer
QgsMeshEditor( QgsMeshLayer *meshLayer );

//! Constructoe with a specific mesh \a nativeMesh and an associatd triangular mesh \a triangularMesh
//! Constructor with a specific mesh \a nativeMesh and an associatd triangular mesh \a triangularMesh
QgsMeshEditor( QgsMesh *nativeMesh, QgsTriangularMesh *triangularMesh, QObject *parent = nullptr ); SIP_SKIP
~QgsMeshEditor();

//! Initialize the mesh editor and return errors if the internal native mesh have topologic errors
QgsMeshEditingError initialize();

//! Resets the triangular mesh
void resetTriangularMesh( QgsTriangularMesh *triangularMesh ); SIP_SKIP

//! Returns TRUE if a \a face can be added to the mesh
bool faceCanBeAdded( const QgsMeshFace &face );

@@ -181,6 +184,15 @@ class CORE_EXPORT QgsMeshEditor : public QObject
//! Returns whether the mesh has been modified
bool isModified() const;

/**
* Reindexes the mesh, that is remove unusued index of face and vertices, this operation void the undo/redo stack.
*
* If \a renumbering is true, a renumbering is operated to optimize the vertices indexes.
*
* Returns FALSE if the operation fail.
*/
bool reindex( bool renumbering );

//----------- access element methods

//! Returns all the free vertices indexes
@@ -1004,6 +1004,23 @@ void QgsMeshLayer::stopFrameEditing( const QgsCoordinateTransform &transform )
mRendererCache.reset( new QgsMeshLayerRendererCache() );
}

bool QgsMeshLayer::reindex( const QgsCoordinateTransform &transform, bool renumber )
{
if ( !mMeshEditor )
return false;

if ( !mMeshEditor->reindex( renumber ) )
return false;

mTriangularMeshes.clear();
mTriangularMeshes.emplace_back( new QgsTriangularMesh );
mTriangularMeshes.at( 0 )->update( mNativeMesh.get(), transform );
mRendererCache.reset( new QgsMeshLayerRendererCache() );
mMeshEditor->resetTriangularMesh( mTriangularMeshes.at( 0 ).get() );

return true;
}

QgsMeshEditor *QgsMeshLayer::meshEditor()
{
return mMeshEditor;
@@ -779,6 +779,17 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
*/
void stopFrameEditing( const QgsCoordinateTransform &transform );

/**
* Re-indexes the faces and vertices, and renumber the indexes if \a renumber is TRUE.
* rebuilds the triangular mesh and its spatial index with \a transform,
* clean the undostack
*
* Returns FALSE if the operation fails
*
* \since QGIS 3.22
*/
bool reindex( const QgsCoordinateTransform &transform, bool renumber );

/**
* Returns a pointer to the mesh editor own by the mesh layer
*

0 comments on commit be3a9e7

Please sign in to comment.