Skip to content

Commit

Permalink
make AlignMapPointContext a class instead of a struct
Browse files Browse the repository at this point in the history
  • Loading branch information
lbartoletti authored and nyalldawson committed Sep 12, 2021
1 parent f4383aa commit 992dc6c
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 78 deletions.
74 changes: 55 additions & 19 deletions python/core/auto_generated/qgscadutils.sip.in
Expand Up @@ -32,25 +32,6 @@ The :py:class:`QgsCadUtils` class provides routines for CAD editing.
double value;
};

struct AlignMapPointContext
{
QgsSnappingUtils *snappingUtils;
double mapUnitsPerPixel;

QgsCadUtils::AlignMapPointConstraint xConstraint;
QgsCadUtils::AlignMapPointConstraint yConstraint;

QgsCadUtils::AlignMapPointConstraint zConstraint;

QgsCadUtils::AlignMapPointConstraint mConstraint;
QgsCadUtils::AlignMapPointConstraint distanceConstraint;
QgsCadUtils::AlignMapPointConstraint angleConstraint;
QgsCadUtils::AlignMapPointConstraint commonAngleConstraint;

QList<QgsPoint> cadPointList;

};

struct AlignMapPointOutput
{
bool valid;
Expand All @@ -64,6 +45,61 @@ The :py:class:`QgsCadUtils` class provides routines for CAD editing.
double softLockCommonAngle;
};

class AlignMapPointContext
{
%Docstring(signature="appended")
Class defining all constraints for :py:func:`~QgsCadUtils.alignMapPoint` method

This class was a structure before QGIS 3.22.

mCadPointList is now a private QList< :py:class:`QgsPoint` >.
Use getters/setters.

.. seealso:: :py:func:`cadPoints`

.. seealso:: :py:func:`setCadPoints`

.. versionadded:: 3.22
%End

%TypeHeaderCode
#include "qgscadutils.h"
%End
public:
QgsSnappingUtils *snappingUtils;
double mapUnitsPerPixel;

QgsCadUtils::AlignMapPointConstraint xConstraint;
QgsCadUtils::AlignMapPointConstraint yConstraint;

QgsCadUtils::AlignMapPointConstraint zConstraint;

QgsCadUtils::AlignMapPointConstraint mConstraint;
QgsCadUtils::AlignMapPointConstraint distanceConstraint;
QgsCadUtils::AlignMapPointConstraint angleConstraint;
QgsCadUtils::AlignMapPointConstraint commonAngleConstraint;


QList< QgsPoint > cadPoints() const;
%Docstring
Returns a list of points from mCadPointList.

.. versionadded:: 3.22
%End
void setCadPoints( const QList< QgsPoint> &list );
%Docstring
Set points to mCadPointList

:param list: points to mCadPointList

.. versionadded:: 3.22
%End
%Property( name = cadPointList, get = _cadPointList, set = _setCadPointList )
void _setCadPointList( const QList< QgsPointXY > &list );
QList< QgsPointXY > _cadPointList() const;

};

static QgsCadUtils::AlignMapPointOutput alignMapPoint( const QgsPointXY &originalMapPoint, const QgsCadUtils::AlignMapPointContext &ctx );
%Docstring
Applies X/Y/angle/distance constraints from the given context to a map point.
Expand Down
20 changes: 10 additions & 10 deletions src/core/qgscadutils.cpp
Expand Up @@ -57,10 +57,10 @@ QgsCadUtils::AlignMapPointOutput QgsCadUtils::alignMapPoint( const QgsPointXY &o
}

QgsPointXY previousPt, penultimatePt;
if ( ctx.cadPointList.count() >= 2 )
previousPt = ctx.cadPointList.at( 1 );
if ( ctx.cadPointList.count() >= 3 )
penultimatePt = ctx.cadPointList.at( 2 );
if ( ctx.cadPoints().count() >= 2 )
previousPt = ctx.cadPoints().at( 1 );
if ( ctx.cadPoints().count() >= 3 )
penultimatePt = ctx.cadPoints().at( 2 );

// *****************************
// ---- X constraint
Expand All @@ -70,7 +70,7 @@ QgsCadUtils::AlignMapPointOutput QgsCadUtils::alignMapPoint( const QgsPointXY &o
{
point.setX( ctx.xConstraint.value );
}
else if ( ctx.cadPointList.count() >= 2 )
else if ( ctx.cadPoints().count() >= 2 )
{
point.setX( previousPt.x() + ctx.xConstraint.value );
}
Expand Down Expand Up @@ -98,7 +98,7 @@ QgsCadUtils::AlignMapPointOutput QgsCadUtils::alignMapPoint( const QgsPointXY &o
{
point.setY( ctx.yConstraint.value );
}
else if ( ctx.cadPointList.count() >= 2 )
else if ( ctx.cadPoints().count() >= 2 )
{
point.setY( previousPt.y() + ctx.yConstraint.value );
}
Expand All @@ -120,15 +120,15 @@ QgsCadUtils::AlignMapPointOutput QgsCadUtils::alignMapPoint( const QgsPointXY &o

// *****************************
// ---- Common Angle constraint
if ( !ctx.angleConstraint.locked && ctx.cadPointList.count() >= 2 && ctx.commonAngleConstraint.locked && ctx.commonAngleConstraint.value != 0 )
if ( !ctx.angleConstraint.locked && ctx.cadPoints().count() >= 2 && ctx.commonAngleConstraint.locked && ctx.commonAngleConstraint.value != 0 )
{
const double commonAngle = ctx.commonAngleConstraint.value * M_PI / 180;
// see if soft common angle constraint should be performed
// only if not in HardLock mode
double softAngle = std::atan2( point.y() - previousPt.y(),
point.x() - previousPt.x() );
double deltaAngle = 0;
if ( ctx.commonAngleConstraint.relative && ctx.cadPointList.count() >= 3 )
if ( ctx.commonAngleConstraint.relative && ctx.cadPoints().count() >= 3 )
{
// compute the angle relative to the last segment (0° is aligned with last segment)
deltaAngle = std::atan2( previousPt.y() - penultimatePt.y(),
Expand Down Expand Up @@ -175,7 +175,7 @@ QgsCadUtils::AlignMapPointOutput QgsCadUtils::alignMapPoint( const QgsPointXY &o
if ( angleLocked )
{
double angleValue = angleValueDeg * M_PI / 180;
if ( angleRelative && ctx.cadPointList.count() >= 3 )
if ( angleRelative && ctx.cadPoints().count() >= 3 )
{
// compute the angle relative to the last segment (0° is aligned with last segment)
angleValue += std::atan2( previousPt.y() - penultimatePt.y(),
Expand Down Expand Up @@ -256,7 +256,7 @@ QgsCadUtils::AlignMapPointOutput QgsCadUtils::alignMapPoint( const QgsPointXY &o

// *****************************
// ---- Distance constraint
if ( ctx.distanceConstraint.locked && ctx.cadPointList.count() >= 2 )
if ( ctx.distanceConstraint.locked && ctx.cadPoints().count() >= 2 )
{
if ( ctx.xConstraint.locked || ctx.yConstraint.locked )
{
Expand Down
127 changes: 82 additions & 45 deletions src/core/qgscadutils.h
Expand Up @@ -50,51 +50,6 @@ class CORE_EXPORT QgsCadUtils
double value;
};

//! Structure defining all constraints for alignMapPoint() method
struct AlignMapPointContext
{
//! Snapping utils that will be used to snap point to map. Must not be NULLPTR.
QgsSnappingUtils *snappingUtils = nullptr;
//! Map units/pixel ratio from map canvas. Needed for
double mapUnitsPerPixel;

//! Constraint for X coordinate
QgsCadUtils::AlignMapPointConstraint xConstraint;
//! Constraint for Y coordinate
QgsCadUtils::AlignMapPointConstraint yConstraint;

/**
* Constraint for Z coordinate
* \since QGIS 3.22
*/
QgsCadUtils::AlignMapPointConstraint zConstraint;

/**
* Constraint for M coordinate
* \since QGIS 3.22
*/
QgsCadUtils::AlignMapPointConstraint mConstraint;
//! Constraint for distance
QgsCadUtils::AlignMapPointConstraint distanceConstraint;
//! Constraint for angle
QgsCadUtils::AlignMapPointConstraint angleConstraint;
//! Constraint for soft lock to a common angle
QgsCadUtils::AlignMapPointConstraint commonAngleConstraint;

/**
* List of recent CAD points in map coordinates. These are used to turn relative constraints to absolute.
* First point is the most recent point. Currently using only "previous" point (index 1) and "penultimate"
* point (index 2) for alignment purposes.
*/
QList<QgsPoint> cadPointList;

/**
* Dumps the context's properties, for debugging.
* \note Not available in Python bindings.
*/
SIP_SKIP void dump() const;
};

//! Structure returned from alignMapPoint() method
struct AlignMapPointOutput
{
Expand All @@ -120,6 +75,88 @@ class CORE_EXPORT QgsCadUtils
double softLockCommonAngle;
};

/**
* Class defining all constraints for alignMapPoint() method
*
* This class was a structure before QGIS 3.22.
*
* mCadPointList is now a private QList< QgsPoint >.
* Use getters/setters.
*
* \see cadPoints
* \see setCadPoints
*
* \since QGIS 3.22
*/
class AlignMapPointContext
{
public:
//! Snapping utils that will be used to snap point to map. Must not be NULLPTR.
QgsSnappingUtils *snappingUtils = nullptr;
//! Map units/pixel ratio from map canvas. Needed for
double mapUnitsPerPixel;

//! Constraint for X coordinate
QgsCadUtils::AlignMapPointConstraint xConstraint;
//! Constraint for Y coordinate
QgsCadUtils::AlignMapPointConstraint yConstraint;

/**
* Constraint for Z coordinate
* \since QGIS 3.22
*/
QgsCadUtils::AlignMapPointConstraint zConstraint;

/**
* Constraint for M coordinate
* \since QGIS 3.22
*/
QgsCadUtils::AlignMapPointConstraint mConstraint;
//! Constraint for distance
QgsCadUtils::AlignMapPointConstraint distanceConstraint;
//! Constraint for angle
QgsCadUtils::AlignMapPointConstraint angleConstraint;
//! Constraint for soft lock to a common angle
QgsCadUtils::AlignMapPointConstraint commonAngleConstraint;

/**
* Dumps the context's properties, for debugging.
* \note Not available in Python bindings.
*/
SIP_SKIP void dump() const;

/**
* Returns a list of points from mCadPointList.
* \since QGIS 3.22
*/
QList< QgsPoint > cadPoints() const { return mCadPointList; } ;

/**
* Set points to mCadPointList
* \param list points to mCadPointList
* \since QGIS 3.22
*/
void setCadPoints( const QList< QgsPoint> &list ) { mCadPointList = list; };

#ifdef SIP_RUN
SIP_PROPERTY( name = cadPointList, get = _cadPointList, set = _setCadPointList )
#endif
///@cond PRIVATE
void _setCadPointList( const QList< QgsPointXY > &list ) { mCadPointList.clear(); for ( const auto &pointxy : list ) { mCadPointList.append( QgsPoint( pointxy ) );} }
QList< QgsPointXY > _cadPointList() const { QList< QgsPointXY> list; for ( const auto &point : mCadPointList ) { list.append( QgsPointXY( point.x(), point.y() ) ); }; return list; }
///@endcond PRIVATE

private:

/**
* List of recent CAD points in map coordinates. These are used to turn relative constraints to absolute.
* First point is the most recent point. Currently using only "previous" point (index 1) and "penultimate"
* point (index 2) for alignment purposes.
*/
QList<QgsPoint> mCadPointList;

};

/**
* Applies X/Y/angle/distance constraints from the given context to a map point.
* Returns a structure containing aligned map point, whether the constraints are valid and
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsadvanceddigitizingdockwidget.cpp
Expand Up @@ -803,7 +803,7 @@ bool QgsAdvancedDigitizingDockWidget::applyConstraints( QgsMapMouseEvent *e )
context.mConstraint = _constraint( mMConstraint.get() );
context.distanceConstraint = _constraint( mDistanceConstraint.get() );
context.angleConstraint = _constraint( mAngleConstraint.get() );
context.cadPointList = mCadPointList;
context.setCadPoints( mCadPointList );

context.commonAngleConstraint.locked = true;
context.commonAngleConstraint.relative = context.angleConstraint.relative;
Expand Down
6 changes: 3 additions & 3 deletions tests/src/core/testqgscadutils.cpp
Expand Up @@ -53,7 +53,7 @@ class TestQgsCadUtils : public QObject
QgsCadUtils::AlignMapPointContext context;
context.snappingUtils = mSnappingUtils;
context.mapUnitsPerPixel = mMapSettings.mapUnitsPerPixel();
context.cadPointList << QgsPoint() << QgsPoint( 30, 20 ) << QgsPoint( 30, 30 );
context.cadPoints() << QgsPoint() << QgsPoint( 30, 20 ) << QgsPoint( 30, 30 );
return context;
}

Expand Down Expand Up @@ -231,7 +231,7 @@ void TestQgsCadUtils::testCommonAngle()
// common angle rel
context.angleConstraint = QgsCadUtils::AlignMapPointConstraint();
context.commonAngleConstraint = QgsCadUtils::AlignMapPointConstraint( true, true, 90 );
context.cadPointList[1] = QgsPoint( 40, 20 );
context.cadPoints()[1] = QgsPoint( 40, 20 );
QgsCadUtils::AlignMapPointOutput res3 = QgsCadUtils::alignMapPoint( QgsPointXY( 50.1, 29.9 ), context );
QVERIFY( res3.valid );
QCOMPARE( res3.softLockCommonAngle, 90.0 );
Expand Down Expand Up @@ -293,7 +293,7 @@ void TestQgsCadUtils::testDistance()
void TestQgsCadUtils::testEdge()
{
QgsCadUtils::AlignMapPointContext context( baseContext() );
context.cadPointList = QList<QgsPoint>() << QgsPoint() << QgsPoint( 40, 30 ) << QgsPoint( 40, 40 );
context.setCadPoints( QList<QgsPoint>() << QgsPoint() << QgsPoint( 40, 30 ) << QgsPoint( 40, 40 ) );

const QgsPointXY edgePt( 20, 15 ); // in the middle of the triangle polygon's edge

Expand Down

0 comments on commit 992dc6c

Please sign in to comment.