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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <limits>
|
||||
|
||||
#include <preview_items/polygon_geom_manager.h>
|
||||
|
||||
|
@ -67,6 +68,7 @@ bool POLYGON_GEOM_MANAGER::AddPoint( const VECTOR2I& aPt )
|
|||
|
||||
void POLYGON_GEOM_MANAGER::SetFinished()
|
||||
{
|
||||
|
||||
m_client.OnComplete( *this );
|
||||
}
|
||||
|
||||
|
@ -144,16 +146,44 @@ void POLYGON_GEOM_MANAGER::updateLeaderPoints( const VECTOR2I& aEndPoint, LEADER
|
|||
{
|
||||
wxCHECK( m_lockedPoints.PointCount() > 0, /*void*/ );
|
||||
const VECTOR2I& lastPt = m_lockedPoints.CLastPoint();
|
||||
auto newEnd = VECTOR2I( aEndPoint );
|
||||
|
||||
if( m_leaderMode == LEADER_MODE::DEG45 || aModifier == LEADER_MODE::DEG45 )
|
||||
{
|
||||
const VECTOR2I lineVector( aEndPoint - lastPt );
|
||||
// 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 );
|
||||
|
||||
if( pt )
|
||||
m_leaderPts.Append( *pt );
|
||||
}
|
||||
else
|
||||
{
|
||||
// direct segment
|
||||
m_leaderPts = SHAPE_LINE_CHAIN( lastPt, aEndPoint );
|
||||
}
|
||||
|
||||
m_client.OnGeometryChange( *this );
|
||||
}
|
||||
|
|
|
@ -95,6 +95,11 @@ public:
|
|||
*/
|
||||
void SetLeaderMode( LEADER_MODE aMode );
|
||||
|
||||
LEADER_MODE GetLeaderMode() const
|
||||
{
|
||||
return m_leaderMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables/disables self-intersecting polygons.
|
||||
* @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 ) :
|
||||
EDA_ITEM( NOT_USED ), m_parent( aParent )
|
||||
EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent )
|
||||
: EDA_ITEM( NOT_USED ), m_parent( aParent ), m_allowPoints( true )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
for( pit = m_points.begin(), pitEnd = m_points.end(); pit != pitEnd; ++pit )
|
||||
if( m_allowPoints )
|
||||
{
|
||||
for( auto& point : m_points )
|
||||
{
|
||||
EDIT_POINT& point = *pit;
|
||||
|
||||
if( point.WithinPoint( aLocation, size ) )
|
||||
return &point;
|
||||
}
|
||||
}
|
||||
|
||||
std::deque<EDIT_LINE>::iterator lit, litEnd;
|
||||
for( lit = m_lines.begin(), litEnd = m_lines.end(); lit != litEnd; ++lit )
|
||||
for( auto& line : m_lines )
|
||||
{
|
||||
EDIT_LINE& line = *lit;
|
||||
|
||||
if( line.WithinPoint( aLocation, size ) )
|
||||
return &line;
|
||||
}
|
||||
|
|
|
@ -219,11 +219,11 @@ public:
|
|||
///> @copydoc EDIT_POINT::ApplyConstraint()
|
||||
virtual void ApplyConstraint() override
|
||||
{
|
||||
m_origin.ApplyConstraint();
|
||||
m_end.ApplyConstraint();
|
||||
|
||||
if( m_constraint )
|
||||
m_constraint->Apply();
|
||||
|
||||
m_origin.ApplyConstraint();
|
||||
m_end.ApplyConstraint();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -492,6 +492,17 @@ public:
|
|||
return m_lines.size();
|
||||
}
|
||||
|
||||
void SetAllowPoints( bool aAllow = true )
|
||||
{
|
||||
m_allowPoints = aAllow;
|
||||
}
|
||||
|
||||
bool GetAllowPoints() const
|
||||
{
|
||||
return m_allowPoints;
|
||||
}
|
||||
|
||||
|
||||
///> @copydoc VIEW_ITEM::ViewBBox()
|
||||
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_LINE> m_lines; ///< EDIT_LINEs for modifying m_parent
|
||||
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_ */
|
||||
|
|
|
@ -200,6 +200,7 @@ public:
|
|||
{
|
||||
auto zone = static_cast<const ZONE_CONTAINER*>( aItem );
|
||||
buildForPolyOutline( points, zone->Outline(), aGal );
|
||||
points->SetAllowPoints( !zone->GetHV45() );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -367,7 +368,10 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
|||
//TODO: unify the constraints to solve simultaneously instead of sequentially
|
||||
m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(),
|
||||
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
|
||||
setAltConstraint( enableAltConstraint );
|
||||
|
|
|
@ -295,6 +295,22 @@ void ZONE_CREATE_HELPER::OnComplete( const POLYGON_GEOM_MANAGER& aMgr )
|
|||
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->RemoveNullSegments();
|
||||
|
||||
|
|
Loading…
Reference in New Issue