Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
use constraint cad Z value for mesh editing
  • Loading branch information
vcloarec committed Sep 19, 2021
1 parent 895d467 commit bb09d06
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 40 deletions.
8 changes: 8 additions & 0 deletions python/core/auto_generated/mesh/qgsmesheditor.sip.in
Expand Up @@ -153,7 +153,15 @@ Changes the Z values of the vertices with indexes in ``vertices`` indexes with t
void changeXYValues( const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
%Docstring
Changes the (X,Y) coordinates values of the vertices with indexes in ``vertices`` indexes with the values in ``newValues``.
The caller has the responsibility to check if changing the vertices coordinates does not lead to topological errors.
New values are in layer CRS.
%End

void changeCoordinates( const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
%Docstring
Changes the (X,Y,Z) coordinates values of the vertices with indexes in ``vertices`` indexes with the values in ``newValues``.
The caller has the responsibility to check if changing the vertices coordinates does not lead to topological errors
New coordinates are in layer CRS.
%End

void advancedEdit( QgsMeshAdvancedEditing *editing );
Expand Down
14 changes: 14 additions & 0 deletions python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in
Expand Up @@ -218,6 +218,20 @@ determines if CAD tools are enabled or if map tools behaves "nomally"
%Docstring
Determines if Z or M will be enabled.

.. versionadded:: 3.22
%End

void setEnabledZ( bool enable );
%Docstring
Sets whether Z is enabled

.. versionadded:: 3.22
%End

void setEnabledM( bool enable );
%Docstring
Sets whether M is enabled

.. versionadded:: 3.22
%End

Expand Down
108 changes: 87 additions & 21 deletions src/app/mesh/qgsmaptooleditmeshframe.cpp
Expand Up @@ -322,6 +322,14 @@ QgsMapToolEditMeshFrame::QgsMapToolEditMeshFrame( QgsMapCanvas *canvas )

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

connect( cadDockWidget(), &QgsAdvancedDigitizingDockWidget::cadEnabledChanged, this, [this]( bool enable )
{
if ( enable && mSelectedVertices.isEmpty() )
deleteZValueWidget();
else if ( !mZValueWidget )
createZValueWidget();
} );

setAutoSnapEnabled( true );
}

Expand Down Expand Up @@ -538,7 +546,7 @@ void QgsMapToolEditMeshFrame::initialize()

connect( mCanvas, &QgsMapCanvas::currentLayerChanged, this, &QgsMapToolEditMeshFrame::setCurrentLayer );

mUserZValue = QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.value();
mUserZValue = defaultZValue();
createZValueWidget();
updateFreeVertices();

Expand All @@ -547,13 +555,13 @@ void QgsMapToolEditMeshFrame::initialize()

void QgsMapToolEditMeshFrame::deactivate()
{
QgsMapToolAdvancedDigitizing::deactivate();
clearSelection();
clearCanvasHelpers();
deleteZValueWidget();
qDeleteAll( mFreeVertexMarker );
mFreeVertexMarker.clear();

QgsMapToolAdvancedDigitizing::deactivate();
}

void QgsMapToolEditMeshFrame::clearAll()
Expand Down Expand Up @@ -597,7 +605,8 @@ void QgsMapToolEditMeshFrame::clearAll()
void QgsMapToolEditMeshFrame::activate()
{
QgsMapToolAdvancedDigitizing::activate();
createZValueWidget();
if ( !cadDockWidget()->cadEnabled() )
createZValueWidget();
}

bool QgsMapToolEditMeshFrame::populateContextMenuWithEvent( QMenu *menu, QgsMapMouseEvent *event )
Expand Down Expand Up @@ -683,7 +692,9 @@ void QgsMapToolEditMeshFrame::cadCanvasPressEvent( QgsMapMouseEvent *e )
if ( !mCurrentEditor )
return;

if ( e->button() == Qt::LeftButton )
if ( e->button() == Qt::LeftButton &&
( !mCadDockWidget->cadEnabled() ||
mCadDockWidget->additionalConstraint() == QgsAdvancedDigitizingDockWidget::AdditionalConstraint::NoConstraint ) )
mLeftButtonPressed = true;

switch ( mCurrentState )
Expand Down Expand Up @@ -769,6 +780,7 @@ void QgsMapToolEditMeshFrame::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( !mDoubleClicks )
{
mFirstClickPoint = mapPoint;
mFirstClickZValue = currentZValue();
}

if ( e->button() == Qt::LeftButton )
Expand All @@ -782,6 +794,7 @@ void QgsMapToolEditMeshFrame::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( mDoubleClicks ) //double clicks --> add a vertex
{
addVertex( mFirstClickPoint, e->mapPointMatch() );
cadDockWidget()->setPoints( QList<QgsPointXY>() << mFirstClickPoint << mFirstClickPoint );
}
else if ( mNewFaceMarker->isVisible() &&
mapPoint.distance( mNewFaceMarker->center() ) < tolerance
Expand All @@ -796,10 +809,11 @@ void QgsMapToolEditMeshFrame::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
const QgsPointXY &currentPoint = mapVertexXY( mCurrentVertexIndex );
cadDockWidget()->setPoints( QList<QgsPointXY>() << currentPoint << currentPoint );
}
else if ( isSelectionGrapped( mapPoint ) && //click on a vertex, a edges or faces box
else if ( isSelectionGrapped( mapPoint ) && //click on a selected vertex, an edge or face box
!( e->modifiers() &Qt::ControlModifier ) ) // without control modifier that is used to remove from the selection
{
mCurrentState = MovingSelection;
mCadDockWidget->setEnabledZ( false );
mStartMovingPoint = mapPoint;
cadDockWidget()->setPoints( QList<QgsPointXY>() << mapPoint << mapPoint );
}
Expand Down Expand Up @@ -876,18 +890,37 @@ void QgsMapToolEditMeshFrame::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
const QgsVector &translationInLayerCoordinate = mapPointInNativeCoordinate - startingPointInNativeCoordinate;

const QgsMesh &mesh = *mCurrentLayer->nativeMesh();
for ( int i = 0; i < verticesIndexes.count(); ++i )
newPosition.append( QgsPointXY( mesh.vertex( verticesIndexes.at( i ) ) ) + translationInLayerCoordinate );

mKeepSelectionOnEdit = true;
mCurrentEditor->changeXYValues( mSelectedVertices.keys(), newPosition );
if ( verticesIndexes.count() != 1 )
{
for ( int i = 0; i < verticesIndexes.count(); ++i )
newPosition.append( QgsPointXY( mesh.vertex( verticesIndexes.at( i ) ) ) + translationInLayerCoordinate );
mCurrentEditor->changeXYValues( verticesIndexes, newPosition );
}
else
{
//only one vertex, change also the Z value if snap on a 3D vector layer
if ( e->mapPointMatch().isValid() &&
QgsWkbTypes::hasZ( e->mapPointMatch().layer()->wkbType() ) )
{
const QgsMeshVertex &mapPointInNativeCoordinate =
mCurrentLayer->triangularMesh()->triangularToNativeCoordinates( QgsMeshVertex( mapPoint.x(), mapPoint.y(), e->mapPointMatch().interpolatedPoint().z() ) );
mCurrentEditor->changeCoordinates( verticesIndexes,
QList<QgsPoint>()
<< mapPointInNativeCoordinate ) ;
}
else
mCurrentEditor->changeXYValues( verticesIndexes, QList<QgsPointXY>()
<< QgsPointXY( mesh.vertex( verticesIndexes.at( 0 ) ) ) + translationInLayerCoordinate );
}
}
updateSelectecVerticesMarker();
prepareSelection();
clearCanvasHelpers();
mMovingEdgesRubberband->reset();
mMovingFacesRubberband->reset();
mMovingFreeVertexRubberband->reset();
mCadDockWidget->setEnabledZ( mCadDockWidget->cadEnabled() );
mCurrentState = Digitizing;
break;
case SelectingByPolygon:
Expand Down Expand Up @@ -1000,25 +1033,33 @@ void QgsMapToolEditMeshFrame::select( const QgsPointXY &mapPoint, Qt::KeyboardMo
else
behavior = Qgis::SelectBehavior::SetSelection;

QgsPointXY currentPoint = mapPoint;

if ( mSelectFaceMarker->isVisible() &&
mapPoint.distance( mSelectFaceMarker->center() ) < tolerance
&& mCurrentFaceIndex >= 0 )
{
setSelectedVertices( nativeFace( mCurrentFaceIndex ).toList(), behavior );
currentPoint = mCurrentLayer->triangularMesh()->faceCentroids().at( mCurrentFaceIndex );
}
else if ( mCurrentVertexIndex != -1 )
{
setSelectedVertices( QList<int>() << mCurrentVertexIndex, behavior );
currentPoint = mCurrentLayer->triangularMesh()->vertices().at( mCurrentVertexIndex );
}
else if ( mSelectEdgeMarker->isVisible() &&
mapPoint.distance( mSelectEdgeMarker->center() ) < tolerance &&
mCurrentEdge.first != -1 && mCurrentEdge.second != -1 )
{
QVector<int> edgeVert = edgeVertices( mCurrentEdge );
setSelectedVertices( edgeVert.toList(), behavior );
const QgsMeshVertex v1 = mCurrentLayer->triangularMesh()->vertices().at( edgeVert.at( 0 ) );
const QgsMeshVertex v2 = mCurrentLayer->triangularMesh()->vertices().at( edgeVert.at( 1 ) );
currentPoint = QgsPointXY( ( v1.x() + v2.x() ) / 2, ( v1.y() + v2.y() ) / 2 );
}
else
setSelectedVertices( QList<int>(), behavior );
mCadDockWidget->setPoints( QList < QgsPointXY>() << currentPoint << currentPoint );
}

void QgsMapToolEditMeshFrame::keyPressEvent( QKeyEvent *e )
Expand Down Expand Up @@ -1078,6 +1119,7 @@ void QgsMapToolEditMeshFrame::keyPressEvent( QKeyEvent *e )
mMovingEdgesRubberband->reset( QgsWkbTypes::LineGeometry );
mMovingFacesRubberband->reset( QgsWkbTypes::PolygonGeometry );
mMovingFreeVertexRubberband->reset( QgsWkbTypes::PointGeometry );
mCadDockWidget->setEnabledZ( mCadDockWidget->cadEnabled() );
break;
case Selecting:
case SelectingByPolygon:
Expand Down Expand Up @@ -1115,7 +1157,7 @@ void QgsMapToolEditMeshFrame::keyReleaseEvent( QKeyEvent *e )
break;
}

if ( !consumned )
if ( !consumned && mZValueWidget )
QgsApplication::sendEvent( mZValueWidget->keyboardEntryWidget(), e );

QgsMapToolAdvancedDigitizing::keyReleaseEvent( e );
Expand Down Expand Up @@ -1158,6 +1200,18 @@ const QgsMeshFace QgsMapToolEditMeshFrame::nativeFace( int index ) const
return mCurrentLayer->nativeMesh()->face( index );
}

double QgsMapToolEditMeshFrame::currentZValue()
{
if ( mDoubleClicks )
return mFirstClickZValue;
else if ( mZValueWidget )
return mZValueWidget->zValue();
else if ( mCadDockWidget->cadEnabled() )
return mCadDockWidget->currentPointV2().z();

return defaultZValue();
}

void QgsMapToolEditMeshFrame::highLight( const QgsPointXY &mapPoint )
{
highlightCurrentHoveredFace( mapPoint );
Expand All @@ -1177,6 +1231,9 @@ void QgsMapToolEditMeshFrame::setCurrentLayer( QgsMapLayer *layer )
if ( mCurrentLayer == meshLayer && mCurrentEditor != nullptr )
return;

if ( mCurrentEditor )
deactivate();

if ( mIsInitialized )
clearSelection(); //TODO later: implement a mechanism to retrieve selection if the layer is again selected

Expand Down Expand Up @@ -1215,8 +1272,6 @@ void QgsMapToolEditMeshFrame::setCurrentLayer( QgsMapLayer *layer )
activate();
updateFreeVertices();
}
else
deactivate();

emit selectionChange( mCurrentLayer, mSelectedVertices.keys() );
}
Expand Down Expand Up @@ -1351,10 +1406,9 @@ bool QgsMapToolEditMeshFrame::isFaceSelected( int faceIndex )

void QgsMapToolEditMeshFrame::setSelectedVertices( const QList<int> newSelectedVertices, Qgis::SelectBehavior behavior )
{

if ( mSelectedVertices.isEmpty() )
{
mUserZValue = mZValueWidget->zValue();
mUserZValue = currentZValue();
}

bool removeVertices = false;
Expand Down Expand Up @@ -1633,7 +1687,7 @@ void QgsMapToolEditMeshFrame::forceBySelectedLayerPolyline()

forceByPolylinesEdit.setTolerance( tolerance );
forceByPolylinesEdit.setAddVertexOnIntersection( mWidgetActionForceByLine->newVertexOnIntersectingEdge() );
forceByPolylinesEdit.setDefaultZValue( mZValueWidget->zValue() );
forceByPolylinesEdit.setDefaultZValue( currentZValue() );
forceByPolylinesEdit.setInterpolateZValueOnMesh(
mWidgetActionForceByLine->interpolationMode() == QgsMeshEditForceByLineAction::Mesh );

Expand Down Expand Up @@ -1752,7 +1806,7 @@ void QgsMapToolEditMeshFrame::applyZValueOnSelectedVertices()

QList<double> zValues;
zValues.reserve( mSelectedVertices.count() );
mUserZValue = mZValueWidget->zValue();
mUserZValue = currentZValue();
for ( int i = 0; i < mSelectedVertices.count(); ++i )
zValues.append( mUserZValue );

Expand All @@ -1768,11 +1822,17 @@ void QgsMapToolEditMeshFrame::prepareSelection()
vertexZValue += mapVertex( i ).z();
vertexZValue /= mSelectedVertices.count();

if ( !mZValueWidget )
createZValueWidget();

mZValueWidget->setZValue( vertexZValue );
}
else
{
mZValueWidget->setZValue( mUserZValue );
if ( cadDockWidget()->cadEnabled() && mZValueWidget )
deleteZValueWidget();
else if ( mZValueWidget )
mZValueWidget->setZValue( mUserZValue );
}

mConcernedFaceBySelection.clear();
Expand Down Expand Up @@ -2163,6 +2223,9 @@ void QgsMapToolEditMeshFrame::highlightCloseVertex( const QgsPointXY &mapPoint )
}
}
}

if ( mCadDockWidget->cadEnabled() && !mCadDockWidget->constraintZ()->isLocked() && mCurrentVertexIndex != -1 )
mCadDockWidget->setZ( QString::number( mapVertex( mCurrentVertexIndex ).z(), 'f', 2 ), QgsAdvancedDigitizingDockWidget::WidgetSetMode::TextEdited );
}

void QgsMapToolEditMeshFrame::highlightCloseEdge( const QgsPointXY &mapPoint )
Expand Down Expand Up @@ -2337,7 +2400,7 @@ void QgsMapToolEditMeshFrame::createZValueWidget()
deleteZValueWidget();

mZValueWidget = new QgsZValueWidget( tr( "Vertex Z value:" ) );
mZValueWidget->setDefaultValue( QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.value() );
mZValueWidget->setDefaultValue( defaultZValue() );
mZValueWidget->setZValue( mUserZValue );
QgisApp::instance()->addUserInputWidget( mZValueWidget );
}
Expand Down Expand Up @@ -2391,9 +2454,12 @@ void QgsMapToolEditMeshFrame::addVertex(
const QgsPointLocator::Match &mapPointMatch )
{
QgsTemporaryCursorOverride waitCursor( Qt::WaitCursor );
double zValue = mZValueWidget ? mZValueWidget->zValue() : std::numeric_limits<double>::quiet_NaN();

if ( mapPointMatch.isValid() )
double zValue;

if ( mCadDockWidget->cadEnabled() && mCurrentFaceIndex == -1 )
zValue = currentZValue();
else if ( mapPointMatch.isValid() )
{
QgsPoint layerPoint = mapPointMatch.interpolatedPoint();
zValue = layerPoint.z();
Expand All @@ -2409,7 +2475,7 @@ void QgsMapToolEditMeshFrame::addVertex(
zValue = QgsMeshLayerUtils::interpolateFromVerticesData( v1, v2, v3, v1.z(), v2.z(), v3.z(), mapPoint );
}
else
zValue = mZValueWidget->zValue();
zValue = currentZValue();

QVector<QgsMeshVertex> points( 1, QgsMeshVertex( mapPoint.x(), mapPoint.y(), zValue ) );
if ( mCurrentEditor )
Expand Down
3 changes: 3 additions & 0 deletions src/app/mesh/qgsmaptooleditmeshframe.h
Expand Up @@ -188,6 +188,8 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing
const QgsPointXY mapVertexXY( int index ) const;
const QgsMeshFace nativeFace( int index ) const;

double currentZValue();

void highLight( const QgsPointXY &mapPoint );
void highlightCurrentHoveredFace( const QgsPointXY &mapPoint );
void highlightCloseVertex( const QgsPointXY &mapPoint );
Expand Down Expand Up @@ -262,6 +264,7 @@ class APP_EXPORT QgsMapToolEditMeshFrame : public QgsMapToolAdvancedDigitizing
QList<int> mNewFaceCandidate;
bool mDoubleClicks = false;
QgsPointXY mFirstClickPoint; //the first click point when double clicks, we need it when the point is constraint by the cad tool, second click could not be constraint
double mFirstClickZValue;
double mUserZValue = 0;

//! Rubber band used to highlight a face that is on mouse over and not dragging anything, own by map canvas
Expand Down

0 comments on commit bb09d06

Please sign in to comment.