pcbnew: Retain 45° constraint
This also finishes the polygon with 45° lines when chosen as a create option. Fixes: lp:1833673 * https://bugs.launchpad.net/kicad/+bug/1833673
This commit is contained in:
parent
a43a228f78
commit
fccce265aa
|
@ -20,6 +20,7 @@
|
||||||
* or you may write to the Free Software Foundation, Inc.,
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include <preview_items/polygon_geom_manager.h>
|
#include <preview_items/polygon_geom_manager.h>
|
||||||
|
|
||||||
|
@ -67,6 +68,7 @@ bool POLYGON_GEOM_MANAGER::AddPoint( const VECTOR2I& aPt )
|
||||||
|
|
||||||
void POLYGON_GEOM_MANAGER::SetFinished()
|
void POLYGON_GEOM_MANAGER::SetFinished()
|
||||||
{
|
{
|
||||||
|
|
||||||
m_client.OnComplete( *this );
|
m_client.OnComplete( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,16 +146,44 @@ void POLYGON_GEOM_MANAGER::updateLeaderPoints( const VECTOR2I& aEndPoint, LEADER
|
||||||
{
|
{
|
||||||
wxCHECK( m_lockedPoints.PointCount() > 0, /*void*/ );
|
wxCHECK( m_lockedPoints.PointCount() > 0, /*void*/ );
|
||||||
const VECTOR2I& lastPt = m_lockedPoints.CLastPoint();
|
const VECTOR2I& lastPt = m_lockedPoints.CLastPoint();
|
||||||
auto newEnd = VECTOR2I( aEndPoint );
|
|
||||||
|
|
||||||
if( m_leaderMode == LEADER_MODE::DEG45 || aModifier == LEADER_MODE::DEG45 )
|
if( m_leaderMode == LEADER_MODE::DEG45 || aModifier == LEADER_MODE::DEG45 )
|
||||||
{
|
{
|
||||||
const VECTOR2I lineVector( aEndPoint - lastPt );
|
const VECTOR2I lineVector( aEndPoint - lastPt );
|
||||||
// get a restricted 45/H/V line from the last fixed point to the cursor
|
// get a restricted 45/H/V line from the last fixed point to the cursor
|
||||||
newEnd = lastPt + GetVectorSnapped45( lineVector );
|
auto newEnd = lastPt + GetVectorSnapped45( lineVector );
|
||||||
|
|
||||||
|
SEG first( lastPt, newEnd );
|
||||||
|
SEG test_seg = m_lockedPoints.CSegment( 0 );
|
||||||
|
|
||||||
|
auto pt = first.IntersectLines( m_lockedPoints.CSegment( 0 ) );
|
||||||
|
int dist = pt ? ( aEndPoint - *pt ).EuclideanNorm() : std::numeric_limits<int>::max();
|
||||||
|
|
||||||
|
for( int i = 1; i < 8; i++ )
|
||||||
|
{
|
||||||
|
test_seg.B = ( test_seg.B - test_seg.A ).Rotate( M_PI_4 ) + test_seg.A;
|
||||||
|
auto pt2 = first.IntersectLines( test_seg );
|
||||||
|
if( pt2 )
|
||||||
|
{
|
||||||
|
int dist2 = ( aEndPoint - *pt2 ).EuclideanNorm();
|
||||||
|
if( dist2 < dist )
|
||||||
|
{
|
||||||
|
dist = dist2;
|
||||||
|
pt = pt2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// direct segment
|
|
||||||
m_leaderPts = SHAPE_LINE_CHAIN( lastPt, newEnd );
|
m_leaderPts = SHAPE_LINE_CHAIN( lastPt, newEnd );
|
||||||
|
|
||||||
|
if( pt )
|
||||||
|
m_leaderPts.Append( *pt );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// direct segment
|
||||||
|
m_leaderPts = SHAPE_LINE_CHAIN( lastPt, aEndPoint );
|
||||||
|
}
|
||||||
|
|
||||||
m_client.OnGeometryChange( *this );
|
m_client.OnGeometryChange( *this );
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetLeaderMode( LEADER_MODE aMode );
|
void SetLeaderMode( LEADER_MODE aMode );
|
||||||
|
|
||||||
|
LEADER_MODE GetLeaderMode() const
|
||||||
|
{
|
||||||
|
return m_leaderMode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables/disables self-intersecting polygons.
|
* Enables/disables self-intersecting polygons.
|
||||||
* @param aEnabled true if self-intersecting polygons are enabled.
|
* @param aEnabled true if self-intersecting polygons are enabled.
|
||||||
|
|
|
@ -36,30 +36,27 @@ bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent ) :
|
EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent )
|
||||||
EDA_ITEM( NOT_USED ), m_parent( aParent )
|
: EDA_ITEM( NOT_USED ), m_parent( aParent ), m_allowPoints( true )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation, KIGFX::VIEW *aView ) // fixme: ugly
|
EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation, KIGFX::VIEW *aView ) // fixme: ugly
|
||||||
{
|
{
|
||||||
float size = aView->ToWorld( EDIT_POINT::POINT_SIZE );
|
unsigned size = std::abs<int>( KiROUND( aView->ToWorld( EDIT_POINT::POINT_SIZE ) ) );
|
||||||
|
|
||||||
std::deque<EDIT_POINT>::iterator pit, pitEnd;
|
if( m_allowPoints )
|
||||||
for( pit = m_points.begin(), pitEnd = m_points.end(); pit != pitEnd; ++pit )
|
{
|
||||||
|
for( auto& point : m_points )
|
||||||
{
|
{
|
||||||
EDIT_POINT& point = *pit;
|
|
||||||
|
|
||||||
if( point.WithinPoint( aLocation, size ) )
|
if( point.WithinPoint( aLocation, size ) )
|
||||||
return &point;
|
return &point;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::deque<EDIT_LINE>::iterator lit, litEnd;
|
for( auto& line : m_lines )
|
||||||
for( lit = m_lines.begin(), litEnd = m_lines.end(); lit != litEnd; ++lit )
|
|
||||||
{
|
{
|
||||||
EDIT_LINE& line = *lit;
|
|
||||||
|
|
||||||
if( line.WithinPoint( aLocation, size ) )
|
if( line.WithinPoint( aLocation, size ) )
|
||||||
return &line;
|
return &line;
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,11 +219,11 @@ public:
|
||||||
///> @copydoc EDIT_POINT::ApplyConstraint()
|
///> @copydoc EDIT_POINT::ApplyConstraint()
|
||||||
virtual void ApplyConstraint() override
|
virtual void ApplyConstraint() override
|
||||||
{
|
{
|
||||||
m_origin.ApplyConstraint();
|
|
||||||
m_end.ApplyConstraint();
|
|
||||||
|
|
||||||
if( m_constraint )
|
if( m_constraint )
|
||||||
m_constraint->Apply();
|
m_constraint->Apply();
|
||||||
|
|
||||||
|
m_origin.ApplyConstraint();
|
||||||
|
m_end.ApplyConstraint();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -492,6 +492,17 @@ public:
|
||||||
return m_lines.size();
|
return m_lines.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetAllowPoints( bool aAllow = true )
|
||||||
|
{
|
||||||
|
m_allowPoints = aAllow;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetAllowPoints() const
|
||||||
|
{
|
||||||
|
return m_allowPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///> @copydoc VIEW_ITEM::ViewBBox()
|
///> @copydoc VIEW_ITEM::ViewBBox()
|
||||||
virtual const BOX2I ViewBBox() const override;
|
virtual const BOX2I ViewBBox() const override;
|
||||||
|
|
||||||
|
@ -524,6 +535,7 @@ private:
|
||||||
std::deque<EDIT_POINT> m_points; ///< EDIT_POINTs for modifying m_parent
|
std::deque<EDIT_POINT> m_points; ///< EDIT_POINTs for modifying m_parent
|
||||||
std::deque<EDIT_LINE> m_lines; ///< EDIT_LINEs for modifying m_parent
|
std::deque<EDIT_LINE> m_lines; ///< EDIT_LINEs for modifying m_parent
|
||||||
std::list<int> m_contours; ///< Indices of end contour points
|
std::list<int> m_contours; ///< Indices of end contour points
|
||||||
|
bool m_allowPoints; ///< If false, only allow editing of EDIT_LINES
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* EDIT_POINTS_H_ */
|
#endif /* EDIT_POINTS_H_ */
|
||||||
|
|
|
@ -200,6 +200,7 @@ public:
|
||||||
{
|
{
|
||||||
auto zone = static_cast<const ZONE_CONTAINER*>( aItem );
|
auto zone = static_cast<const ZONE_CONTAINER*>( aItem );
|
||||||
buildForPolyOutline( points, zone->Outline(), aGal );
|
buildForPolyOutline( points, zone->Outline(), aGal );
|
||||||
|
points->SetAllowPoints( !zone->GetHV45() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +368,10 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
||||||
//TODO: unify the constraints to solve simultaneously instead of sequentially
|
//TODO: unify the constraints to solve simultaneously instead of sequentially
|
||||||
m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(),
|
m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(),
|
||||||
snapLayers, { item } ) );
|
snapLayers, { item } ) );
|
||||||
bool enableAltConstraint = !!evt->Modifier( MD_CTRL );
|
|
||||||
|
// The alternative constraint limits to 45°
|
||||||
|
bool enableAltConstraint =
|
||||||
|
( !!evt->Modifier( MD_CTRL ) || !m_editPoints->GetAllowPoints() );
|
||||||
|
|
||||||
if( enableAltConstraint != (bool) m_altConstraint ) // alternative constraint
|
if( enableAltConstraint != (bool) m_altConstraint ) // alternative constraint
|
||||||
setAltConstraint( enableAltConstraint );
|
setAltConstraint( enableAltConstraint );
|
||||||
|
|
|
@ -295,6 +295,22 @@ void ZONE_CREATE_HELPER::OnComplete( const POLYGON_GEOM_MANAGER& aMgr )
|
||||||
outline->Append( finalPoints.CPoint( i ) );
|
outline->Append( finalPoints.CPoint( i ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In DEG45 mode, we may have intermediate points in the leader that should be
|
||||||
|
// included as they are shown in the preview. These typically maintain the
|
||||||
|
// 45 constraint
|
||||||
|
if( aMgr.GetLeaderMode() == POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 )
|
||||||
|
{
|
||||||
|
auto pts = aMgr.GetLeaderLinePoints();
|
||||||
|
|
||||||
|
if( outline->TotalVertices() > 0 )
|
||||||
|
outline->RemoveVertex( outline->TotalVertices() - 1 );
|
||||||
|
|
||||||
|
// The first 2 points of the leader are the continuation of the previous segment
|
||||||
|
// The third point is where it intersects with the extension from the 0-th segment
|
||||||
|
for( int i = 2; i < pts.PointCount(); i++ )
|
||||||
|
outline->Append( pts.CPoint( i ) );
|
||||||
|
}
|
||||||
|
|
||||||
outline->Outline( 0 ).SetClosed( true );
|
outline->Outline( 0 ).SetClosed( true );
|
||||||
outline->RemoveNullSegments();
|
outline->RemoveNullSegments();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue