Skip to content

Commit

Permalink
Merge pull request #45081 from vcloarec/someFixes_09
Browse files Browse the repository at this point in the history
[mesh] some fixes related to mesh editing
  • Loading branch information
PeterPetrik committed Sep 16, 2021
2 parents 78e4691 + fa87494 commit 21433a6
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 38 deletions.
5 changes: 5 additions & 0 deletions python/core/auto_generated/mesh/qgsmeshdataset.sip.in
Expand Up @@ -737,6 +737,11 @@ Returns whether all the datasets contain ``count`` values
void calculateStatistic();
%Docstring
Calculates the statistics (minimum and maximum)
%End

void setStatisticObsolete();
%Docstring
Sets statistic obsolete, that means statistic will be recalculated when requested
%End

virtual QStringList datasetGroupNamesDependentOn() const;
Expand Down
6 changes: 6 additions & 0 deletions python/core/auto_generated/mesh/qgsmesheditor.sip.in
Expand Up @@ -62,6 +62,12 @@ Constructor with a specified layer ``meshLayer``
%End


QgsMeshDatasetGroup *createZValueDatasetGroup() /TransferBack/;
%Docstring
Creates and returns a scalar dataset group with value on vertex that is can be used to access the Z value of the edited mesh.
The caller takes ownership.
%End

QgsMeshEditingError initialize();
%Docstring
Initialize the mesh editor and return errors if the internal native mesh have topologic errors
Expand Down
19 changes: 10 additions & 9 deletions src/app/mesh/qgsmaptooleditmeshframe.cpp
Expand Up @@ -413,6 +413,11 @@ QWidgetAction *QgsMapToolEditMeshFrame::forceByLineWidgetActionSettings() const
return mWidgetActionForceByLine;
}

QAction *QgsMapToolEditMeshFrame::reindexAction() const
{
return mActionReindexMesh;
}

void QgsMapToolEditMeshFrame::initialize()
{
if ( !mFaceRubberBand )
Expand Down Expand Up @@ -1481,19 +1486,15 @@ void QgsMapToolEditMeshFrame::splitSelectedFaces()

void QgsMapToolEditMeshFrame::triggerTransformCoordinatesDockWidget( bool checked )
{
if ( !checked && mTransformDockWidget )
{
mTransformDockWidget->close();
return;
}
else if ( mTransformDockWidget )
if ( mTransformDockWidget )
{
mTransformDockWidget->show();
mTransformDockWidget->setUserVisible( checked );
return;
}

onEditingStarted();
mTransformDockWidget = new QgsMeshTransformCoordinatesDockWidget( QgisApp::instance() );
mTransformDockWidget->setToggleVisibilityAction( mActionTransformCoordinates );
mTransformDockWidget->setWindowTitle( tr( "Transform Mesh Vertices" ) );
mTransformDockWidget->setObjectName( QStringLiteral( "TransformMeshVerticesDockWidget" ) );
const QList<int> &inputVertices = mSelectedVertices.keys();
Expand Down Expand Up @@ -1656,11 +1657,11 @@ void QgsMapToolEditMeshFrame::forceBySelectedLayerPolyline()

void QgsMapToolEditMeshFrame::reindexMesh()
{
onEditingStarted();

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 )
Expand Down
1 change: 1 addition & 0 deletions src/app/mesh/qgsmaptooleditmeshframe.h
Expand Up @@ -128,6 +128,7 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing
QList<QAction *> forceByLinesActions() const;
QAction *defaultForceAction() const;
QWidgetAction *forceByLineWidgetActionSettings() const;
QAction *reindexAction() const;

void setActionsEnable( bool enable );

Expand Down
2 changes: 2 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -3869,6 +3869,8 @@ void QgisApp::createToolBars()
mDigitizeModeToolButton->setMenu( digitizeMenu );
for ( QAction *mapToolAction : editMeshMapTool->mapToolActions() )
mMapToolGroup->addAction( mapToolAction );

mMeshMenu->addAction( editMeshMapTool->reindexAction() );
}

QToolButton *annotationLayerToolButton = new QToolButton();
Expand Down
39 changes: 28 additions & 11 deletions src/core/mesh/qgsmeshdataset.cpp
Expand Up @@ -975,18 +975,12 @@ QDomElement QgsMeshMemoryDatasetGroup::writeXml( QDomDocument &doc, const QgsRea

void QgsMeshDatasetGroup::calculateStatistic()
{
double min = std::numeric_limits<double>::max();
double max = std::numeric_limits<double>::min();
updateStatictic();
}

const int count = datasetCount();
for ( int i = 0; i < count; ++i )
{
const QgsMeshDatasetMetadata &meta = datasetMetadata( i );
min = std::min( min, meta.minimum() );
max = std::max( max, meta.maximum() );
}
mMinimum = min;
mMaximum = max;
void QgsMeshDatasetGroup::setStatisticObsolete()
{
mIsStatisticObsolete = true;
}

QStringList QgsMeshDatasetGroup::datasetGroupNamesDependentOn() const
Expand All @@ -1004,6 +998,27 @@ void QgsMeshDatasetGroup::setReferenceTime( const QDateTime &referenceTime )
mReferenceTime = referenceTime;
}

void QgsMeshDatasetGroup::updateStatictic() const
{
if ( !mIsStatisticObsolete )
return;

double min = std::numeric_limits<double>::max();
double max = std::numeric_limits<double>::min();

const int count = datasetCount();
for ( int i = 0; i < count; ++i )
{
const QgsMeshDatasetMetadata &meta = datasetMetadata( i );
min = std::min( min, meta.minimum() );
max = std::max( max, meta.maximum() );
}
mMinimum = min;
mMaximum = max;

mIsStatisticObsolete = false;
}

bool QgsMeshDatasetGroup::checkValueCountPerDataset( int count ) const
{
for ( int i = 0; i < datasetCount(); ++i )
Expand All @@ -1021,11 +1036,13 @@ QgsMeshDatasetGroup::QgsMeshDatasetGroup( const QString &name ): mName( name ) {

double QgsMeshDatasetGroup::minimum() const
{
updateStatictic();
return mMinimum;
}

double QgsMeshDatasetGroup::maximum() const
{
updateStatictic();
return mMaximum;
}

Expand Down
10 changes: 8 additions & 2 deletions src/core/mesh/qgsmeshdataset.h
Expand Up @@ -658,6 +658,9 @@ class CORE_EXPORT QgsMeshDatasetGroup
//! Calculates the statistics (minimum and maximum)
void calculateStatistic();

//! Sets statistic obsolete, that means statistic will be recalculated when requested
void setStatisticObsolete();

//! Returns the dataset group variable name which this dataset group depends on
virtual QStringList datasetGroupNamesDependentOn() const;

Expand All @@ -678,8 +681,11 @@ class CORE_EXPORT QgsMeshDatasetGroup
bool mIsScalar = true;

private:
double mMinimum = std::numeric_limits<double>::quiet_NaN();
double mMaximum = std::numeric_limits<double>::quiet_NaN();
mutable double mMinimum = std::numeric_limits<double>::quiet_NaN();
mutable double mMaximum = std::numeric_limits<double>::quiet_NaN();
mutable bool mIsStatisticObsolete = true;

void updateStatictic() const;

QDateTime mReferenceTime;
};
Expand Down
40 changes: 38 additions & 2 deletions src/core/mesh/qgsmesheditor.cpp
Expand Up @@ -52,6 +52,13 @@ QgsMeshEditor::QgsMeshEditor( QgsMesh *nativeMesh, QgsTriangularMesh *triangular
connect( mUndoStack, &QUndoStack::indexChanged, this, &QgsMeshEditor::meshEdited );
}

QgsMeshDatasetGroup *QgsMeshEditor::createZValueDatasetGroup()
{
std::unique_ptr<QgsMeshDatasetGroup> zValueDatasetGroup = std::make_unique<QgsMeshVerticesElevationDatasetGroup>( tr( "vertices Z value" ), mMesh );
mZValueDatasetGroup = zValueDatasetGroup.get();
return zValueDatasetGroup.release();
}

QgsMeshEditor::~QgsMeshEditor() = default;

QgsMeshEditingError QgsMeshEditor::initialize()
Expand Down Expand Up @@ -184,12 +191,24 @@ void QgsMeshEditor::applyEdit( QgsMeshEditor::Edit &edit )
{
mTopologicalMesh.applyChanges( edit.topologicalChanges );
mTriangularMesh->applyChanges( edit.triangularMeshChanges );

if ( mZValueDatasetGroup &&
( !edit.topologicalChanges.newVerticesZValues().isEmpty() ||
!edit.topologicalChanges.verticesToRemoveIndexes().isEmpty() ||
!edit.topologicalChanges.addedVertices().isEmpty() ) )
mZValueDatasetGroup->setStatisticObsolete();
}

void QgsMeshEditor::reverseEdit( QgsMeshEditor::Edit &edit )
{
mTopologicalMesh.reverseChanges( edit.topologicalChanges );
mTriangularMesh->reverseChanges( edit.triangularMeshChanges, *mMesh );

if ( mZValueDatasetGroup &&
( !edit.topologicalChanges.newVerticesZValues().isEmpty() ||
!edit.topologicalChanges.verticesToRemoveIndexes().isEmpty() ||
!edit.topologicalChanges.addedVertices().isEmpty() ) )
mZValueDatasetGroup->setStatisticObsolete();
}

void QgsMeshEditor::applyAddVertex( QgsMeshEditor::Edit &edit, const QgsMeshVertex &vertex, double tolerance )
Expand Down Expand Up @@ -217,16 +236,25 @@ void QgsMeshEditor::applyAddVertex( QgsMeshEditor::Edit &edit, const QgsMeshVert
}

applyEditOnTriangularMesh( edit, topologicChanges );

if ( mZValueDatasetGroup )
mZValueDatasetGroup->setStatisticObsolete();
}

void QgsMeshEditor::applyRemoveVertexFillHole( QgsMeshEditor::Edit &edit, int vertexIndex )
{
applyEditOnTriangularMesh( edit, mTopologicalMesh.removeVertexFillHole( vertexIndex ) );

if ( mZValueDatasetGroup )
mZValueDatasetGroup->setStatisticObsolete();
}

void QgsMeshEditor::applyRemoveVerticesWithoutFillHole( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes )
{
applyEditOnTriangularMesh( edit, mTopologicalMesh.removeVertices( verticesIndexes ) );

if ( mZValueDatasetGroup )
mZValueDatasetGroup->setStatisticObsolete();
}

void QgsMeshEditor::applyAddFaces( QgsMeshEditor::Edit &edit, const QgsTopologicalMesh::TopologicalFaces &faces )
Expand All @@ -242,6 +270,9 @@ void QgsMeshEditor::applyRemoveFaces( QgsMeshEditor::Edit &edit, const QList<int
void QgsMeshEditor::applyChangeZValue( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes, const QList<double> &newValues )
{
applyEditOnTriangularMesh( edit, mTopologicalMesh.changeZValue( verticesIndexes, newValues ) );

if ( mZValueDatasetGroup )
mZValueDatasetGroup->setStatisticObsolete();
}

void QgsMeshEditor::applyChangeXYValue( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues )
Expand Down Expand Up @@ -493,7 +524,9 @@ int QgsMeshEditor::addVertices( const QVector<QgsMeshVertex> &vertices, double t
mUndoStack->push( new QgsMeshLayerUndoCommandAddVertices( this, verticesInLayerCoordinate, tolerance ) );
}

return vertices.count() - ignoredVertex;
int effectivlyAddedVertex = vertices.count() - ignoredVertex;

return effectivlyAddedVertex;
}

int QgsMeshEditor::addPointsAsVertices( const QVector<QgsPoint> &point, double tolerance )
Expand All @@ -518,7 +551,10 @@ QgsMeshEditingError QgsMeshEditor::removeVertices( const QList<int> &verticesToR
return error;
}

mUndoStack->push( new QgsMeshLayerUndoCommandRemoveVertices( this, verticesIndexes, fillHoles ) );
if ( error.errorType == Qgis::MeshEditingErrorType::NoError )
{
mUndoStack->push( new QgsMeshLayerUndoCommandRemoveVertices( this, verticesIndexes, fillHoles ) );
}

return error;
}
Expand Down
7 changes: 7 additions & 0 deletions src/core/mesh/qgsmesheditor.h
Expand Up @@ -73,6 +73,12 @@ class CORE_EXPORT QgsMeshEditor : public QObject
QgsMeshEditor( QgsMesh *nativeMesh, QgsTriangularMesh *triangularMesh, QObject *parent = nullptr ); SIP_SKIP
~QgsMeshEditor();

/**
* Creates and returns a scalar dataset group with value on vertex that is can be used to access the Z value of the edited mesh.
* The caller takes ownership.
*/
QgsMeshDatasetGroup *createZValueDatasetGroup() SIP_TRANSFERBACK;

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

Expand Down Expand Up @@ -241,6 +247,7 @@ class CORE_EXPORT QgsMeshEditor : public QObject
QgsTopologicalMesh mTopologicalMesh;
QgsTriangularMesh *mTriangularMesh = nullptr;
int mMaximumVerticesPerFace = 0;
QgsMeshDatasetGroup *mZValueDatasetGroup = nullptr;

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

Expand Down
16 changes: 13 additions & 3 deletions src/core/mesh/qgsmeshlayer.cpp
Expand Up @@ -925,11 +925,12 @@ bool QgsMeshLayer::startFrameEditing( const QgsCoordinateTransform &transform )
// All dataset group are removed and replace by a unique virtual dataset group that provide vertices elevation value.
mExtraDatasetUri.clear();
mDatasetGroupStore.reset( new QgsMeshDatasetGroupStore( this ) );
mDatasetGroupStore->addDatasetGroup( new QgsMeshVerticesElevationDatasetGroup( tr( "vertices Z value" ), mNativeMesh.get() ) );
mDatasetGroupStore->addDatasetGroup( mMeshEditor->createZValueDatasetGroup() );
resetDatasetGroupTreeItem();

connect( mMeshEditor, &QgsMeshEditor::meshEdited, this, &QgsMeshLayer::onMeshEdited );

emit dataChanged();
emit editingStarted();

return true;
Expand All @@ -938,7 +939,10 @@ bool QgsMeshLayer::startFrameEditing( const QgsCoordinateTransform &transform )
bool QgsMeshLayer::commitFrameEditing( const QgsCoordinateTransform &transform, bool continueEditing )
{
if ( !mMeshEditor->checkConsistency() )
{
QgsMessageLog::logMessage( QObject::tr( "Mesh layer \"%1\" not support mesh editing" ).arg( name() ), QString(), Qgis::MessageLevel::Critical );
return false;
}

stopFrameEditing( transform );

Expand Down Expand Up @@ -973,12 +977,16 @@ bool QgsMeshLayer::rollBackFrameEditing( const QgsCoordinateTransform &transform
if ( !mDataProvider )
return false;

mTriangularMeshes.clear();
mDataProvider->reloadData();
mDataProvider->populateMesh( mNativeMesh.get() );
updateTriangularMesh( transform );
mRendererCache.reset( new QgsMeshLayerRendererCache() );
trigger3DUpdate();

if ( continueEditing )
{
mMeshEditor->resetTriangularMesh( triangularMesh() );
return mMeshEditor->initialize() == QgsMeshEditingError();
}
else
Expand All @@ -990,6 +998,7 @@ bool QgsMeshLayer::rollBackFrameEditing( const QgsCoordinateTransform &transform
mDatasetGroupStore.reset( new QgsMeshDatasetGroupStore( this ) );
mDatasetGroupStore->setPersistentProvider( mDataProvider, QStringList() );
resetDatasetGroupTreeItem();
emit dataChanged();
return true;
}
}
Expand Down Expand Up @@ -1538,8 +1547,9 @@ bool QgsMeshLayer::writeXml( QDomNode &layer_node, QDomDocument &document, const
elemStaticDataset.setAttribute( QStringLiteral( "vector" ), mStaticVectorDatasetIndex );
layer_node.appendChild( elemStaticDataset );

// write dataset group store
layer_node.appendChild( mDatasetGroupStore->writeXml( document, context ) );
// write dataset group store if not in edting mode
if ( !isEditable() )
layer_node.appendChild( mDatasetGroupStore->writeXml( document, context ) );

// renderer specific settings
QString errorMsg;
Expand Down

0 comments on commit 21433a6

Please sign in to comment.