Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #45142 from vcloarec/verticesFacesCount
fix face/vertex count during editing
  • Loading branch information
PeterPetrik committed Sep 21, 2021
2 parents 5950326 + aa4258f commit ef2f404
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 26 deletions.
10 changes: 10 additions & 0 deletions python/core/auto_generated/mesh/qgsmesheditor.sip.in
Expand Up @@ -210,6 +210,16 @@ Return ``True`` if the edited mesh is consistent
%Docstring
Returns ``True`` if an edge of face is closest than the tolerance from the ``point`` in triangular mesh coordinate
Returns also the face index and the edge position in ``faceIndex`` and ``edgePosition``
%End

int validFacesCount() const;
%Docstring
Returns the count of valid faces, that is non void faces in the mesh
%End

int validVerticesCount() const;
%Docstring
Returns the count of valid vertices, that is non void vertices in the mesh
%End

signals:
Expand Down
8 changes: 8 additions & 0 deletions python/core/auto_generated/mesh/qgsmeshlayer.sip.in
Expand Up @@ -808,13 +808,21 @@ Returns whether the mesh contains at mesh elements of given type
%Docstring
Returns the vertices count of the mesh frame

.. note::

during mesh editing, some vertices can be void and are not included in this returned value

.. versionadded:: 3.22
%End

int meshFaceCount() const;
%Docstring
Returns the faces count of the mesh frame

.. note::

during mesh editing, some faces can be void and are not included in this returned value

.. versionadded:: 3.22
%End

Expand Down
55 changes: 53 additions & 2 deletions src/core/mesh/qgsmesheditor.cpp
Expand Up @@ -65,6 +65,8 @@ QgsMeshEditingError QgsMeshEditor::initialize()
{
QgsMeshEditingError error;
mTopologicalMesh = QgsTopologicalMesh::createTopologicalMesh( mMesh, mMaximumVerticesPerFace, error );
mValidFacesCount = mMesh->faceCount();
mValidVerticesCount = mMesh->vertexCount();
return error;
}

Expand Down Expand Up @@ -197,6 +199,8 @@ void QgsMeshEditor::applyEdit( QgsMeshEditor::Edit &edit )
!edit.topologicalChanges.verticesToRemoveIndexes().isEmpty() ||
!edit.topologicalChanges.addedVertices().isEmpty() ) )
mZValueDatasetGroup->setStatisticObsolete();

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::reverseEdit( QgsMeshEditor::Edit &edit )
Expand All @@ -209,6 +213,8 @@ void QgsMeshEditor::reverseEdit( QgsMeshEditor::Edit &edit )
!edit.topologicalChanges.verticesToRemoveIndexes().isEmpty() ||
!edit.topologicalChanges.addedVertices().isEmpty() ) )
mZValueDatasetGroup->setStatisticObsolete();

updateElementsCount( edit.topologicalChanges, false );
}

void QgsMeshEditor::applyAddVertex( QgsMeshEditor::Edit &edit, const QgsMeshVertex &vertex, double tolerance )
Expand Down Expand Up @@ -239,6 +245,8 @@ void QgsMeshEditor::applyAddVertex( QgsMeshEditor::Edit &edit, const QgsMeshVert

if ( mZValueDatasetGroup )
mZValueDatasetGroup->setStatisticObsolete();

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applyRemoveVertexFillHole( QgsMeshEditor::Edit &edit, int vertexIndex )
Expand All @@ -247,6 +255,8 @@ void QgsMeshEditor::applyRemoveVertexFillHole( QgsMeshEditor::Edit &edit, int ve

if ( mZValueDatasetGroup )
mZValueDatasetGroup->setStatisticObsolete();

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applyRemoveVerticesWithoutFillHole( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes )
Expand All @@ -255,16 +265,22 @@ void QgsMeshEditor::applyRemoveVerticesWithoutFillHole( QgsMeshEditor::Edit &edi

if ( mZValueDatasetGroup )
mZValueDatasetGroup->setStatisticObsolete();

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applyAddFaces( QgsMeshEditor::Edit &edit, const QgsTopologicalMesh::TopologicalFaces &faces )
{
applyEditOnTriangularMesh( edit, mTopologicalMesh.addFaces( faces ) );

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applyRemoveFaces( QgsMeshEditor::Edit &edit, const QList<int> &faceToRemoveIndex )
{
applyEditOnTriangularMesh( edit, mTopologicalMesh.removeFaces( faceToRemoveIndex ) );

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applyChangeZValue( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes, const QList<double> &newValues )
Expand All @@ -283,16 +299,29 @@ void QgsMeshEditor::applyChangeXYValue( QgsMeshEditor::Edit &edit, const QList<i
void QgsMeshEditor::applyFlipEdge( QgsMeshEditor::Edit &edit, int vertexIndex1, int vertexIndex2 )
{
applyEditOnTriangularMesh( edit, mTopologicalMesh.flipEdge( vertexIndex1, vertexIndex2 ) );

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applyMerge( QgsMeshEditor::Edit &edit, int vertexIndex1, int vertexIndex2 )
{
applyEditOnTriangularMesh( edit, mTopologicalMesh.merge( vertexIndex1, vertexIndex2 ) );

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applySplit( QgsMeshEditor::Edit &edit, int faceIndex )
{
applyEditOnTriangularMesh( edit, mTopologicalMesh.splitFace( faceIndex ) );

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applyAdvancedEdit( QgsMeshEditor::Edit &edit, QgsMeshAdvancedEditing *editing )
{
applyEditOnTriangularMesh( edit, editing->apply( this ) );

updateElementsCount( edit.topologicalChanges );
}

void QgsMeshEditor::applyEditOnTriangularMesh( QgsMeshEditor::Edit &edit, const QgsTopologicalMesh::Changes &topologicChanges )
Expand All @@ -304,9 +333,19 @@ void QgsMeshEditor::applyEditOnTriangularMesh( QgsMeshEditor::Edit &edit, const
edit.triangularMeshChanges = triangularChanges;
}

void QgsMeshEditor::applyAdvancedEdit( QgsMeshEditor::Edit &edit, QgsMeshAdvancedEditing *editing )
void QgsMeshEditor::updateElementsCount( const QgsTopologicalMesh::Changes &changes, bool apply )
{
applyEditOnTriangularMesh( edit, editing->apply( this ) );
if ( apply )
{
mValidFacesCount += changes.addedFaces().count() - changes.removedFaces().count();
mValidVerticesCount += changes.addedVertices().count() - changes.verticesToRemoveIndexes().count();
}
else
{
//reverse
mValidFacesCount -= changes.addedFaces().count() - changes.removedFaces().count();
mValidVerticesCount -= changes.addedVertices().count() - changes.verticesToRemoveIndexes().count();
}
}

bool QgsMeshEditor::checkConsistency() const
Expand Down Expand Up @@ -380,6 +419,16 @@ bool QgsMeshEditor::edgeIsClose( QgsPointXY point, double tolerance, int &faceIn

}

int QgsMeshEditor::validFacesCount() const
{
return mValidFacesCount;
}

int QgsMeshEditor::validVerticesCount() const
{
return mValidVerticesCount;
}

QgsMeshEditingError QgsMeshEditor::removeFaces( const QList<int> &facesToRemove )
{
QgsMeshEditingError error = mTopologicalMesh.canFacesBeRemoved( facesToRemove );
Expand Down Expand Up @@ -846,6 +895,8 @@ bool QgsMeshEditor::reindex( bool renumbering )
mTopologicalMesh.reindex();
mUndoStack->clear();
QgsMeshEditingError error = initialize();
mValidFacesCount = mMesh->faceCount();
mValidVerticesCount = mMesh->vertexCount();

if ( error.errorType != Qgis::MeshEditingErrorType::NoError )
return false;
Expand Down
10 changes: 10 additions & 0 deletions src/core/mesh/qgsmesheditor.h
Expand Up @@ -238,6 +238,12 @@ class CORE_EXPORT QgsMeshEditor : public QObject
*/
bool edgeIsClose( QgsPointXY point, double tolerance, int &faceIndex, int &edgePosition );

//! Returns the count of valid faces, that is non void faces in the mesh
int validFacesCount() const;

//! Returns the count of valid vertices, that is non void vertices in the mesh
int validVerticesCount() const;

signals:
//! Emitted when the mesh is edited
void meshEdited();
Expand All @@ -248,6 +254,8 @@ class CORE_EXPORT QgsMeshEditor : public QObject
QgsTriangularMesh *mTriangularMesh = nullptr;
int mMaximumVerticesPerFace = 0;
QgsMeshDatasetGroup *mZValueDatasetGroup = nullptr;
int mValidVerticesCount = 0;
int mValidFacesCount = 0;

QVector<QgsMeshFace> prepareFaces( const QVector<QgsMeshFace> &faces, QgsMeshEditingError &error );

Expand Down Expand Up @@ -276,6 +284,8 @@ class CORE_EXPORT QgsMeshEditor : public QObject

void applyEditOnTriangularMesh( Edit &edit, const QgsTopologicalMesh::Changes &topologicChanges );

void updateElementsCount( const QgsTopologicalMesh::Changes &changes, bool apply = true );

friend class TestQgsMeshEditor;
friend class QgsMeshLayerUndoCommandMeshEdit;
friend class QgsMeshLayerUndoCommandAddVertices;
Expand Down
4 changes: 2 additions & 2 deletions src/core/mesh/qgsmeshlayer.cpp
Expand Up @@ -1060,7 +1060,7 @@ bool QgsMeshLayer::contains( const QgsMesh::ElementType &type ) const
int QgsMeshLayer::meshVertexCount() const
{
if ( mMeshEditor )
return mNativeMesh->vertexCount();
return mMeshEditor->validVerticesCount();
else if ( mDataProvider )
return mDataProvider->vertexCount();
else return 0;
Expand All @@ -1069,7 +1069,7 @@ int QgsMeshLayer::meshVertexCount() const
int QgsMeshLayer::meshFaceCount() const
{
if ( mMeshEditor )
return mNativeMesh->faceCount();
return mMeshEditor->validFacesCount();
else if ( mDataProvider )
return mDataProvider->faceCount();
else return 0;
Expand Down
4 changes: 4 additions & 0 deletions src/core/mesh/qgsmeshlayer.h
Expand Up @@ -813,13 +813,17 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
/**
* Returns the vertices count of the mesh frame
*
* \note during mesh editing, some vertices can be void and are not included in this returned value
*
* \since QGIS 3.22
*/
int meshVertexCount() const;

/**
* Returns the faces count of the mesh frame
*
* \note during mesh editing, some faces can be void and are not included in this returned value
*
* \since QGIS 3.22
*/
int meshFaceCount() const;
Expand Down
10 changes: 5 additions & 5 deletions tests/src/app/testqgsmaptooleditmesh.cpp
Expand Up @@ -85,7 +85,7 @@ void TestQgsMapToolEditMesh::editMesh()
QCOMPARE( meshLayerQuadFlower->meshEditor()->freeVerticesIndexes().count(), 0 );

tool.mouseDoubleClick( 1500, 2800, Qt::LeftButton ); //add a vertex on the face 0
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 9 );
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 8 );
QCOMPARE( meshLayerQuadFlower->meshVertexCount(), 9 );
QCOMPARE( meshLayerQuadFlower->meshEditor()->freeVerticesIndexes().count(), 0 );

Expand All @@ -103,19 +103,19 @@ void TestQgsMapToolEditMesh::editMesh()

// redo
tool.mouseDoubleClick( 1500, 2800, Qt::LeftButton );
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 9 );
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 8 );
QCOMPARE( meshLayerQuadFlower->meshVertexCount(), 9 );
QCOMPARE( meshLayerQuadFlower->meshEditor()->freeVerticesIndexes().count(), 0 );

// attempt to add a vertex on place of existing one
tool.mouseDoubleClick( 2500, 2500, Qt::LeftButton );
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 9 );
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 8 );
QCOMPARE( meshLayerQuadFlower->meshVertexCount(), 9 );
QCOMPARE( meshLayerQuadFlower->meshEditor()->freeVerticesIndexes().count(), 0 );

// add a free vertex
tool.mouseDoubleClick( 2500, 3500, Qt::LeftButton ); // 9
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 9 );
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 8 );
QCOMPARE( meshLayerQuadFlower->meshVertexCount(), 10 );
QCOMPARE( meshLayerQuadFlower->meshEditor()->freeVerticesIndexes().count(), 1 );

Expand All @@ -130,7 +130,7 @@ void TestQgsMapToolEditMesh::editMesh()
tool.mouseClick( 2495, 2500, Qt::LeftButton ); // click near the vertex
tool.mouseClick( 5000, 5000, Qt::RightButton ); // valid the face

QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 10 );
QCOMPARE( meshLayerQuadFlower->meshFaceCount(), 9 );

// Remove vertex 7 and 9
tool.mouseMove( 1500, 3250 );
Expand Down

0 comments on commit ef2f404

Please sign in to comment.