Partially integrate grid snapping with constraints.

Fixes https://gitlab.com/kicad/code/kicad/issues/10941
This commit is contained in:
Jeff Young 2022-02-22 21:00:48 +00:00
parent c7dda3fbec
commit 41f6e634c6
5 changed files with 138 additions and 106 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2014 CERN * Copyright (C) 2014 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -29,45 +29,78 @@
#include <geometry/seg.h> #include <geometry/seg.h>
#include <trigo.h> #include <trigo.h>
#include <utility>
#include <geometry/geometry_utils.h> #include <geometry/geometry_utils.h>
void EC_VERTICAL::Apply( EDIT_POINT& aHandle ) void EC_VERTICAL::Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid )
{ {
VECTOR2I point = aHandle.GetPosition(); VECTOR2I point = aHandle.GetPosition();
if( aHandle.GetGridConstraint() == SNAP_TO_GRID )
point = aGrid.AlignGrid( point );
point.x = m_constrainer.GetPosition().x; point.x = m_constrainer.GetPosition().x;
aHandle.SetPosition( point ); aHandle.SetPosition( point );
} }
void EC_HORIZONTAL::Apply( EDIT_POINT& aHandle ) void EC_HORIZONTAL::Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid )
{ {
VECTOR2I point = aHandle.GetPosition(); VECTOR2I point = aHandle.GetPosition();
if( aHandle.GetGridConstraint() == SNAP_TO_GRID )
point = aGrid.AlignGrid( point );
point.y = m_constrainer.GetPosition().y; point.y = m_constrainer.GetPosition().y;
aHandle.SetPosition( point ); aHandle.SetPosition( point );
} }
void EC_45DEGREE::Apply( EDIT_POINT& aHandle ) void EC_45DEGREE::Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid )
{ {
VECTOR2I lineVector( aHandle.GetPosition() - m_constrainer.GetPosition() ); VECTOR2I lineVector( aHandle.GetPosition() - m_constrainer.GetPosition() );
VECTOR2I newLineVector = GetVectorSnapped45( lineVector ); VECTOR2I newLineVector = GetVectorSnapped45( lineVector );
aHandle.SetPosition( m_constrainer.GetPosition() + newLineVector ); if( aHandle.GetGridConstraint() == SNAP_TO_GRID
&& ( newLineVector.x == 0 || newLineVector.y == 0 ) )
{
VECTOR2I snap = aGrid.AlignGrid( m_constrainer.GetPosition() + newLineVector );
if( newLineVector.x == 0 )
aHandle.SetPosition( VECTOR2I( m_constrainer.GetPosition().x, snap.y ) );
else
aHandle.SetPosition( VECTOR2I( snap.x, m_constrainer.GetPosition().y ) );
}
else
{
aHandle.SetPosition( m_constrainer.GetPosition() + newLineVector );
}
} }
EC_LINE::EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EC_LINE::EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_constrainer( aConstrainer ) EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ),
m_constrainer( aConstrainer )
{ {
m_line = m_constrained.GetPosition() - m_constrainer.GetPosition(); m_line = m_constrained.GetPosition() - m_constrainer.GetPosition();
} }
void EC_LINE::Apply( EDIT_POINT& aHandle ) void EC_LINE::Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid )
{ {
SEG main( m_constrainer.GetPosition(), m_constrainer.GetPosition() + m_line ); SEG main( m_constrainer.GetPosition(), m_constrainer.GetPosition() + m_line );
if( aHandle.GetGridConstraint() == SNAP_TO_GRID
&& ( m_line.x == 0 || m_line.y == 0 ) )
{
VECTOR2I snappedHandle = aGrid.AlignGrid( aHandle.GetPosition() );
if( m_line.x == 0 )
aHandle.SetPosition( VECTOR2I( aHandle.GetPosition().x, snappedHandle.y ) );
else
aHandle.SetPosition( VECTOR2I( snappedHandle.x, aHandle.GetPosition().y ) );
}
SEG projection( aHandle.GetPosition(), aHandle.GetPosition() + m_line.Perpendicular() ); SEG projection( aHandle.GetPosition(), aHandle.GetPosition() + m_line.Perpendicular() );
if( OPT_VECTOR2I intersect = projection.IntersectLines( main ) ) if( OPT_VECTOR2I intersect = projection.IntersectLines( main ) )
@ -75,7 +108,7 @@ void EC_LINE::Apply( EDIT_POINT& aHandle )
} }
void EC_CIRCLE::Apply( EDIT_POINT& aHandle ) void EC_CIRCLE::Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid )
{ {
VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition();
VECTOR2I centerToPoint = aHandle.GetPosition() - m_center.GetPosition(); VECTOR2I centerToPoint = aHandle.GetPosition() - m_center.GetPosition();
@ -92,7 +125,8 @@ void EC_CIRCLE::Apply( EDIT_POINT& aHandle )
EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) :
EDIT_CONSTRAINT<EDIT_LINE>( aLine ), EDIT_CONSTRAINT<EDIT_LINE>( aLine ),
m_colinearConstraint( nullptr ), m_editPoints( aPoints ) m_colinearConstraint( nullptr ),
m_editPoints( aPoints )
{ {
// Dragged segment endings // Dragged segment endings
EDIT_POINT& origin = aLine.GetOrigin(); EDIT_POINT& origin = aLine.GetOrigin();
@ -129,7 +163,7 @@ EC_CONVERGING::~EC_CONVERGING()
} }
void EC_CONVERGING::Apply( EDIT_LINE& aHandle ) void EC_CONVERGING::Apply( EDIT_LINE& aHandle, const GRID_HELPER& aGrid )
{ {
// The dragged segment endpoints // The dragged segment endpoints
EDIT_POINT& origin = aHandle.GetOrigin(); EDIT_POINT& origin = aHandle.GetOrigin();
@ -137,16 +171,16 @@ void EC_CONVERGING::Apply( EDIT_LINE& aHandle )
if( m_colinearConstraint ) if( m_colinearConstraint )
{ {
m_colinearConstraint->Apply( origin ); m_colinearConstraint->Apply( origin, aGrid );
m_colinearConstraint->Apply( end ); m_colinearConstraint->Apply( end, aGrid );
} }
// The dragged segment // The dragged segment
SEG dragged( origin.GetPosition(), origin.GetPosition() + m_draggedVector ); SEG dragged( origin.GetPosition(), origin.GetPosition() + m_draggedVector );
// Do not allow points on the adjacent segments move freely // Do not allow points on the adjacent segments move freely
m_originSideConstraint->Apply(); m_originSideConstraint->Apply( aGrid );
m_endSideConstraint->Apply(); m_endSideConstraint->Apply( aGrid );
EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin, false ); EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin, false );
EDIT_POINT& nextEnd = *m_editPoints.Next( end, false ); EDIT_POINT& nextEnd = *m_editPoints.Next( end, false );
@ -180,20 +214,6 @@ void EC_CONVERGING::Apply( EDIT_LINE& aHandle )
} }
EC_SNAPLINE::EC_SNAPLINE( EDIT_LINE& aLine, V2D_TRANSFORM_FUN aSnapFun ) :
EDIT_CONSTRAINT<EDIT_LINE>( aLine ), m_snapFun( std::move(aSnapFun) )
{}
void EC_SNAPLINE::Apply( EDIT_LINE& aHandle )
{
VECTOR2D delta = aHandle.GetEnd().GetPosition() - aHandle.GetOrigin().GetPosition();
aHandle.GetOrigin().SetPosition( m_snapFun( aHandle.GetOrigin().GetPosition() ) );
aHandle.GetEnd().SetPosition( aHandle.GetOrigin().GetPosition() + delta );
}
EC_PERPLINE::EC_PERPLINE( EDIT_LINE& aLine ) : EC_PERPLINE::EC_PERPLINE( EDIT_LINE& aLine ) :
EDIT_CONSTRAINT<EDIT_LINE>( aLine ) EDIT_CONSTRAINT<EDIT_LINE>( aLine )
{ {
@ -202,7 +222,7 @@ EC_PERPLINE::EC_PERPLINE( EDIT_LINE& aLine ) :
} }
void EC_PERPLINE::Apply( EDIT_LINE& aHandle ) void EC_PERPLINE::Apply( EDIT_LINE& aHandle, const GRID_HELPER& aGrid )
{ {
SEG main( m_mid, m_mid + m_line ); SEG main( m_mid, m_mid + m_line );
SEG projection( aHandle.GetPosition(), aHandle.GetPosition() + m_line.Perpendicular() ); SEG projection( aHandle.GetPosition(), aHandle.GetPosition() + m_line.Perpendicular() );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2014 CERN * Copyright (C) 2014 CERN
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
@ -28,6 +28,7 @@
#define EDIT_CONSTRAINTS_H_ #define EDIT_CONSTRAINTS_H_
#include <math/vector2d.h> #include <math/vector2d.h>
#include <tool/grid_helper.h>
#include <functional> #include <functional>
class EDIT_POINT; class EDIT_POINT;
@ -43,6 +44,14 @@ enum GRID_CONSTRAINT_TYPE
}; };
enum SNAP_CONSTRAINT_TYPE
{
IGNORE_SNAPS,
OBJECT_LAYERS,
ALL_LAYERS
};
/** /**
* Describe constraints between two edit handles. * Describe constraints between two edit handles.
* *
@ -56,21 +65,23 @@ public:
/** /**
* @param aConstrained is EDIT_POINT to which the constraint is applied. * @param aConstrained is EDIT_POINT to which the constraint is applied.
*/ */
EDIT_CONSTRAINT( EDIT_TYPE& aConstrained ) : m_constrained( aConstrained ) {}; EDIT_CONSTRAINT( EDIT_TYPE& aConstrained ) :
m_constrained( aConstrained )
{};
virtual ~EDIT_CONSTRAINT() {}; virtual ~EDIT_CONSTRAINT() {};
/** /**
* Correct coordinates of the constrained edit handle. * Correct coordinates of the constrained edit handle.
*/ */
virtual void Apply( EDIT_TYPE& aHandle ) = 0; virtual void Apply( EDIT_TYPE& aHandle, const GRID_HELPER& aGrid ) = 0;
/** /**
* Correct coordinates of the constrained edit handle. * Correct coordinates of the constrained edit handle.
*/ */
void Apply() void Apply( const GRID_HELPER& aGrid )
{ {
Apply( m_constrained ); Apply( m_constrained, aGrid );
} }
protected: protected:
@ -89,11 +100,12 @@ public:
* @param aConstrainer is the point that is the source of the constrain. * @param aConstrainer is the point that is the source of the constrain.
*/ */
EC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_constrainer( aConstrainer ) EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ),
m_constrainer( aConstrainer )
{} {}
///< @copydoc EDIT_CONSTRAINT::Apply() ///< @copydoc EDIT_CONSTRAINT::Apply()
virtual void Apply( EDIT_POINT& aHandle ) override; virtual void Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid ) override;
private: private:
const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
@ -111,11 +123,12 @@ public:
* @param aConstrainer is the point that is the source of the constrain. * @param aConstrainer is the point that is the source of the constrain.
*/ */
EC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_constrainer( aConstrainer ) EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ),
m_constrainer( aConstrainer )
{} {}
///< @copydoc EDIT_CONSTRAINT::Apply() ///< @copydoc EDIT_CONSTRAINT::Apply()
virtual void Apply( EDIT_POINT& aHandle ) override; virtual void Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid ) override;
private: private:
const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
@ -134,11 +147,12 @@ public:
* @param aConstrainer is the point that is the source of the constrain. * @param aConstrainer is the point that is the source of the constrain.
*/ */
EC_45DEGREE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EC_45DEGREE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_constrainer( aConstrainer ) EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ),
m_constrainer( aConstrainer )
{} {}
///< @copydoc EDIT_CONSTRAINT::Apply() ///< @copydoc EDIT_CONSTRAINT::Apply()
virtual void Apply( EDIT_POINT& aHandle ) override; virtual void Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid ) override;
private: private:
const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
@ -155,7 +169,7 @@ public:
EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ); EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer );
///< @copydoc EDIT_CONSTRAINT::Apply() ///< @copydoc EDIT_CONSTRAINT::Apply()
virtual void Apply( EDIT_POINT& aHandle ) override; virtual void Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid ) override;
private: private:
const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
@ -175,11 +189,13 @@ public:
* @param aEnd is the point that decides on the radius of the circle. * @param aEnd is the point that decides on the radius of the circle.
*/ */
EC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) : EC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) :
EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_center( aCenter ), m_end( aEnd ) EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ),
m_center( aCenter ),
m_end( aEnd )
{} {}
///< @copydoc EDIT_CONSTRAINT::Apply() ///< @copydoc EDIT_CONSTRAINT::Apply()
virtual void Apply( EDIT_POINT& aHandle ) override; virtual void Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid ) override;
private: private:
///< Point that imposes the constraint (center of the circle). ///< Point that imposes the constraint (center of the circle).
@ -202,7 +218,7 @@ public:
virtual ~EC_CONVERGING(); virtual ~EC_CONVERGING();
///< @copydoc EDIT_CONSTRAINT::Apply() ///< @copydoc EDIT_CONSTRAINT::Apply()
virtual void Apply( EDIT_LINE& aHandle ) override; virtual void Apply( EDIT_LINE& aHandle, const GRID_HELPER& aGrid ) override;
private: private:
///< Constraint for origin side segment. ///< Constraint for origin side segment.
@ -223,31 +239,6 @@ private:
}; };
/**
* #EDIT_CONSTRAINT for a EDIT_LINE, one of the ends is snapped to a spot determined by a
* transform function passed as parameter (e.g. it can be snapped to a grid), instead of having
* the line center snapped to a point.
*/
class EC_SNAPLINE : public EDIT_CONSTRAINT<EDIT_LINE>
{
public:
///< Typedef for a function that determines snapping point.
typedef std::function<VECTOR2D( const VECTOR2D& )> V2D_TRANSFORM_FUN;
EC_SNAPLINE( EDIT_LINE& aLine, V2D_TRANSFORM_FUN aSnapFun );
virtual ~EC_SNAPLINE()
{}
///< @copydoc EDIT_CONSTRAINT::Apply()
virtual void Apply( EDIT_LINE& aHandle ) override;
private:
///< Function that determines snapping point.
V2D_TRANSFORM_FUN m_snapFun;
};
/** /**
* #EDIT_CONSTRAINT for a EDIT_LINE, that constrains the line to move perpendicular * #EDIT_CONSTRAINT for a EDIT_LINE, that constrains the line to move perpendicular
* to the line itself. * to the line itself.
@ -262,7 +253,7 @@ public:
{} {}
///< @copydoc EDIT_CONSTRAINT::Apply() ///< @copydoc EDIT_CONSTRAINT::Apply()
virtual void Apply( EDIT_LINE& aHandle ) override; virtual void Apply( EDIT_LINE& aHandle, const GRID_HELPER& aGrid ) override;
private: private:
VECTOR2I m_mid; VECTOR2I m_mid;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2014-2017 CERN * Copyright (C) 2014-2017 CERN
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
@ -55,6 +55,7 @@ public:
m_isActive( false ), m_isActive( false ),
m_isHover( false ), m_isHover( false ),
m_gridConstraint( SNAP_TO_GRID ), m_gridConstraint( SNAP_TO_GRID ),
m_snapConstraint( OBJECT_LAYERS ),
m_connected( aConnected ) m_connected( aConnected )
{ {
} }
@ -162,10 +163,10 @@ public:
/** /**
* Correct coordinates of an EDIT_POINT by applying previously set constraint. * Correct coordinates of an EDIT_POINT by applying previously set constraint.
*/ */
virtual void ApplyConstraint() virtual void ApplyConstraint( const GRID_HELPER& aGrid )
{ {
if( m_constraint ) if( m_constraint )
m_constraint->Apply(); m_constraint->Apply( aGrid );
} }
bool IsActive() const { return m_isActive; } bool IsActive() const { return m_isActive; }
@ -177,6 +178,9 @@ public:
GRID_CONSTRAINT_TYPE GetGridConstraint() const { return m_gridConstraint; } GRID_CONSTRAINT_TYPE GetGridConstraint() const { return m_gridConstraint; }
void SetGridConstraint( GRID_CONSTRAINT_TYPE aConstraint ) { m_gridConstraint = aConstraint; } void SetGridConstraint( GRID_CONSTRAINT_TYPE aConstraint ) { m_gridConstraint = aConstraint; }
SNAP_CONSTRAINT_TYPE GetSnapConstraint() const { return m_snapConstraint; }
void SetSnapConstraint( SNAP_CONSTRAINT_TYPE aConstraint ) { m_snapConstraint = aConstraint; }
bool operator==( const EDIT_POINT& aOther ) const bool operator==( const EDIT_POINT& aOther ) const
{ {
return m_position == aOther.m_position; return m_position == aOther.m_position;
@ -196,6 +200,7 @@ private:
bool m_isActive; ///< True if this point is being manipulated. bool m_isActive; ///< True if this point is being manipulated.
bool m_isHover; ///< True if this point is being hovered over. bool m_isHover; ///< True if this point is being hovered over.
GRID_CONSTRAINT_TYPE m_gridConstraint; ///< Describe the grid snapping behavior. GRID_CONSTRAINT_TYPE m_gridConstraint; ///< Describe the grid snapping behavior.
SNAP_CONSTRAINT_TYPE m_snapConstraint; ///< Describe the object snapping behavior.
///< An optional connected item record used to mimic polyLine behavior with individual ///< An optional connected item record used to mimic polyLine behavior with individual
///< line segments. ///< line segments.
@ -243,13 +248,13 @@ public:
} }
///< @copydoc EDIT_POINT::ApplyConstraint() ///< @copydoc EDIT_POINT::ApplyConstraint()
virtual void ApplyConstraint() override virtual void ApplyConstraint( const GRID_HELPER& aGrid ) override
{ {
if( m_constraint ) if( m_constraint )
m_constraint->Apply(); m_constraint->Apply( aGrid );
m_origin.ApplyConstraint(); m_origin.ApplyConstraint( aGrid );
m_end.ApplyConstraint(); m_end.ApplyConstraint( aGrid );
} }
/** /**

View File

@ -836,6 +836,16 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() ); grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
if( step == SET_HEIGHT )
{
if( dimension->GetStart().x != dimension->GetEnd().x
&& dimension->GetStart().y != dimension->GetEnd().y )
{
// Not cardinal. Grid snapping doesn't make sense for height.
grid.SetUseGrid( false );
}
}
VECTOR2I cursorPos = evt->HasPosition() ? evt->Position() : m_controls->GetMousePosition(); VECTOR2I cursorPos = evt->HasPosition() ? evt->Position() : m_controls->GetMousePosition();
cursorPos = grid.BestSnapAnchor( cursorPos, nullptr ); cursorPos = grid.BestSnapAnchor( cursorPos, nullptr );

View File

@ -322,6 +322,9 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
points->AddPoint( dimension->GetCrossbarStart() ); points->AddPoint( dimension->GetCrossbarStart() );
points->AddPoint( dimension->GetCrossbarEnd() ); points->AddPoint( dimension->GetCrossbarEnd() );
points->Point( DIM_START ).SetSnapConstraint( ALL_LAYERS );
points->Point( DIM_END ).SetSnapConstraint( ALL_LAYERS );
if( aItem->Type() == PCB_DIM_ALIGNED_T ) if( aItem->Type() == PCB_DIM_ALIGNED_T )
{ {
// Dimension height setting - edit points should move only along the feature lines // Dimension height setting - edit points should move only along the feature lines
@ -344,8 +347,11 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
points->AddPoint( dimension->GetStart() ); points->AddPoint( dimension->GetStart() );
points->AddPoint( dimension->GetEnd() ); points->AddPoint( dimension->GetEnd() );
points->Point( DIM_START ).SetSnapConstraint( ALL_LAYERS );
points->Point( DIM_END ).SetConstraint( new EC_45DEGREE( points->Point( DIM_END ), points->Point( DIM_END ).SetConstraint( new EC_45DEGREE( points->Point( DIM_END ),
points->Point( DIM_START ) ) ); points->Point( DIM_START ) ) );
points->Point( DIM_END ).SetSnapConstraint( IGNORE_SNAPS );
break; break;
} }
@ -360,12 +366,16 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
points->AddPoint( dimension->Text().GetPosition() ); points->AddPoint( dimension->Text().GetPosition() );
points->AddPoint( dimension->GetKnee() ); points->AddPoint( dimension->GetKnee() );
points->Point( DIM_START ).SetSnapConstraint( ALL_LAYERS );
points->Point( DIM_END ).SetSnapConstraint( ALL_LAYERS );
points->Point( DIM_KNEE ).SetConstraint( new EC_LINE( points->Point( DIM_START ), points->Point( DIM_KNEE ).SetConstraint( new EC_LINE( points->Point( DIM_START ),
points->Point( DIM_END ) ) ); points->Point( DIM_END ) ) );
points->Point( DIM_KNEE ).SetSnapConstraint( IGNORE_SNAPS );
points->Point( DIM_TEXT ).SetConstraint( new EC_45DEGREE( points->Point( DIM_TEXT ), points->Point( DIM_TEXT ).SetConstraint( new EC_45DEGREE( points->Point( DIM_TEXT ),
points->Point( DIM_KNEE ) ) ); points->Point( DIM_KNEE ) ) );
points->Point( DIM_TEXT ).SetGridConstraint( IGNORE_GRID ); points->Point( DIM_TEXT ).SetSnapConstraint( IGNORE_SNAPS );
break; break;
} }
@ -379,9 +389,12 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
points->AddPoint( dimension->GetEnd() ); points->AddPoint( dimension->GetEnd() );
points->AddPoint( dimension->Text().GetPosition() ); points->AddPoint( dimension->Text().GetPosition() );
points->Point( DIM_START ).SetSnapConstraint( ALL_LAYERS );
points->Point( DIM_END ).SetSnapConstraint( ALL_LAYERS );
points->Point( DIM_TEXT ).SetConstraint( new EC_45DEGREE( points->Point( DIM_TEXT ), points->Point( DIM_TEXT ).SetConstraint( new EC_45DEGREE( points->Point( DIM_TEXT ),
points->Point( DIM_END ) ) ); points->Point( DIM_END ) ) );
points->Point( DIM_TEXT ).SetGridConstraint( IGNORE_GRID ); points->Point( DIM_TEXT ).SetSnapConstraint( IGNORE_SNAPS );
break; break;
} }
@ -470,10 +483,6 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
bool lock45 = false; bool lock45 = false;
BOARD_COMMIT commit( editFrame ); BOARD_COMMIT commit( editFrame );
LSET snapLayers = item->GetLayerSet();
if( BaseType( item->Type() ) == PCB_DIMENSION_T )
snapLayers = LSET::AllLayersMask();
// Main loop: keep receiving events // Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
@ -524,19 +533,16 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
} }
VECTOR2I pos = evt->Position(); VECTOR2I pos = evt->Position();
LSET snapLayers;
//TODO: unify the constraints to solve simultaneously instead of sequentially switch( m_editedPoint->GetSnapConstraint() )
switch( m_editedPoint->GetGridConstraint() )
{ {
case IGNORE_GRID: case IGNORE_SNAPS: break;
m_editedPoint->SetPosition( pos ); case OBJECT_LAYERS: snapLayers = item->GetLayerSet(); break;
break; case ALL_LAYERS: snapLayers = LSET::AllLayersMask(); break;
}
case SNAP_TO_GRID: if( m_editedPoint->GetGridConstraint() == SNAP_BY_GRID )
m_editedPoint->SetPosition( grid.BestSnapAnchor( pos, snapLayers, { item } ) );
break;
case SNAP_BY_GRID:
{ {
if( grid.GetUseGrid() ) if( grid.GetUseGrid() )
{ {
@ -544,31 +550,31 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
VECTOR2I last = m_editedPoint->GetPosition(); VECTOR2I last = m_editedPoint->GetPosition();
VECTOR2I delta = pos - last; VECTOR2I delta = pos - last;
VECTOR2I deltaGrid = gridPt - grid.BestSnapAnchor( last, {}, { item } );
if( abs( delta.x ) > grid.GetGrid().x / 2 ) if( abs( delta.x ) > grid.GetGrid().x / 2 )
pos.x = last.x + deltaGrid.x; pos.x = last.x + ( grid.GetGrid().x * sign( delta.x ) );
else else
pos.x = last.x; pos.x = last.x;
if( abs( delta.y ) > grid.GetGrid().y / 2 ) if( abs( delta.y ) > grid.GetGrid().y / 2 )
pos.y = last.y + deltaGrid.y; pos.y = last.y + ( grid.GetGrid().y * sign( delta.y ) );
else else
pos.y = last.y; pos.y = last.y;
} }
}
m_editedPoint->SetPosition( pos ); m_editedPoint->SetPosition( pos );
break;
}
}
// The alternative constraint limits to 45 degrees // The alternative constraint limits to 45 degrees
if( lock45 ) if( lock45 )
m_altConstraint->Apply(); {
else m_altConstraint->Apply( grid );
m_editedPoint->ApplyConstraint(); }
else if( m_editedPoint->IsConstrained() )
if( m_editedPoint->GetGridConstraint() == SNAP_TO_GRID ) {
m_editedPoint->ApplyConstraint( grid );
}
else if( m_editedPoint->GetGridConstraint() == SNAP_TO_GRID )
{ {
m_editedPoint->SetPosition( grid.BestSnapAnchor( m_editedPoint->GetPosition(), m_editedPoint->SetPosition( grid.BestSnapAnchor( m_editedPoint->GetPosition(),
snapLayers, { item } ) ); snapLayers, { item } ) );