KiCad PCB EDA Suite
POLYGON_GEOM_MANAGER Class Reference

Class that handles the drawing of a polygon, including management of last corner deletion and drawing of leader lines with various constraints (eg 45 deg only). More...

#include <polygon_geom_manager.h>

Classes

class  CLIENT
 "Listener" interface for a class that wants to be updated about polygon geometry changes More...
 

Public Types

enum class  LEADER_MODE { DIRECT , DEG45 }
 The kind of the leader line. More...
 

Public Member Functions

 POLYGON_GEOM_MANAGER (CLIENT &aClient)
 
bool AddPoint (const VECTOR2I &aPt)
 Lock in a polygon point. More...
 
void SetFinished ()
 Mark the polygon finished and update the client. More...
 
void Reset ()
 Clear the manager state and start again. More...
 
void SetLeaderMode (LEADER_MODE aMode)
 Set the leader mode to use when calculating the leader/returner lines. More...
 
LEADER_MODE GetLeaderMode () const
 
void AllowIntersections (bool aEnabled)
 Enables/disables self-intersecting polygons. More...
 
bool IntersectionsAllowed () const
 Check whether self-intersecting polygons are enabled. More...
 
bool IsSelfIntersecting (bool aIncludeLeaderPts) const
 Check whether the locked points constitute a self-intersecting outline. More...
 
void SetCursorPosition (const VECTOR2I &aPos)
 Set the current cursor position. More...
 
bool IsPolygonInProgress () const
 
bool NewPointClosesOutline (const VECTOR2I &aPt) const
 
void DeleteLastCorner ()
 Remove the last-added point from the polygon. More...
 
const SHAPE_LINE_CHAINGetLockedInPoints () const
 Get the "locked-in" points that describe the polygon itself. More...
 
const SHAPE_LINE_CHAINGetLeaderLinePoints () const
 Get the points comprising the leader line (the line from the last locked-in point to the current cursor position. More...
 

Private Member Functions

void updateLeaderPoints (const VECTOR2I &aEndPoint, LEADER_MODE aModifier=LEADER_MODE::DIRECT)
 Update the leader line points based on a new endpoint (probably a cursor position) More...
 

Private Attributes

CLIENTm_client
 The current mode of the leader line. More...
 
LEADER_MODE m_leaderMode
 Flag enabling self-intersecting polygons. More...
 
bool m_intersectionsAllowed
 Point that have been "locked in". More...
 
SHAPE_LINE_CHAIN m_lockedPoints
 Points in the temporary "leader" line(s) More...
 
SHAPE_LINE_CHAIN m_leaderPts
 

Detailed Description

Class that handles the drawing of a polygon, including management of last corner deletion and drawing of leader lines with various constraints (eg 45 deg only).

This class handles only the geometry of the process.

Definition at line 35 of file polygon_geom_manager.h.

Member Enumeration Documentation

◆ LEADER_MODE

The kind of the leader line.

Enumerator
DIRECT 

Unconstrained point-to-point.

DEG45 

45 Degree only

Definition at line 69 of file polygon_geom_manager.h.

70 {
71 DIRECT,
72 DEG45,
73 };

Constructor & Destructor Documentation

◆ POLYGON_GEOM_MANAGER()

POLYGON_GEOM_MANAGER::POLYGON_GEOM_MANAGER ( CLIENT aClient)
Parameters
aClientis the client to pass the results onto

Definition at line 32 of file polygon_geom_manager.cpp.

32 :
33 m_client( aClient ),
36{}
CLIENT & m_client
The current mode of the leader line.
@ DIRECT
Unconstrained point-to-point.
LEADER_MODE m_leaderMode
Flag enabling self-intersecting polygons.
bool m_intersectionsAllowed
Point that have been "locked in".

References DIRECT.

Member Function Documentation

◆ AddPoint()

bool POLYGON_GEOM_MANAGER::AddPoint ( const VECTOR2I aPt)

Lock in a polygon point.

Definition at line 39 of file polygon_geom_manager.cpp.

40{
41 // if this is the first point, make sure the client is happy
42 // for us to continue
43 if( !IsPolygonInProgress() && !m_client.OnFirstPoint( *this ) )
44 return false;
45
46 if( m_leaderPts.PointCount() > 1 )
47 {
48 // there are enough leader points - the next
49 // locked-in point is the end of the first leader
50 // segment
52 }
53 else
54 {
55 // no leader lines, directly add the cursor
57 }
58
59 // check for self-intersections
61 {
63 return false;
64 }
65
67 return true;
68}
virtual void OnGeometryChange(const POLYGON_GEOM_MANAGER &aMgr)=0
Called when the polygon is complete.
virtual bool OnFirstPoint(POLYGON_GEOM_MANAGER &aMgr)=0
Called before the first point is added - clients can do initialization here, and can veto the start o...
SHAPE_LINE_CHAIN m_leaderPts
bool IsSelfIntersecting(bool aIncludeLeaderPts) const
Check whether the locked points constitute a self-intersecting outline.
SHAPE_LINE_CHAIN m_lockedPoints
Points in the temporary "leader" line(s)
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.

References SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::CPoint(), IsPolygonInProgress(), IsSelfIntersecting(), m_client, m_intersectionsAllowed, m_leaderPts, m_lockedPoints, POLYGON_GEOM_MANAGER::CLIENT::OnFirstPoint(), POLYGON_GEOM_MANAGER::CLIENT::OnGeometryChange(), SHAPE_LINE_CHAIN::PointCount(), and SHAPE_LINE_CHAIN::Remove().

Referenced by DRAWING_TOOL::DrawZone().

◆ AllowIntersections()

void POLYGON_GEOM_MANAGER::AllowIntersections ( bool  aEnabled)
inline

Enables/disables self-intersecting polygons.

Parameters
aEnabledtrue if self-intersecting polygons are enabled.

Definition at line 110 of file polygon_geom_manager.h.

111 {
113 }

References m_intersectionsAllowed.

◆ DeleteLastCorner()

void POLYGON_GEOM_MANAGER::DeleteLastCorner ( )

Remove the last-added point from the polygon.

Definition at line 122 of file polygon_geom_manager.cpp.

123{
124 if( m_lockedPoints.PointCount() > 0 )
126
127 // update the new last segment (was previously
128 // locked in), reusing last constraints
129 if( m_lockedPoints.PointCount() > 0 )
131
132 m_client.OnGeometryChange( *this );
133}
void updateLeaderPoints(const VECTOR2I &aEndPoint, LEADER_MODE aModifier=LEADER_MODE::DIRECT)
Update the leader line points based on a new endpoint (probably a cursor position)
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.

References SHAPE_LINE_CHAIN::CLastPoint(), m_client, m_leaderPts, m_lockedPoints, POLYGON_GEOM_MANAGER::CLIENT::OnGeometryChange(), SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::Remove(), and updateLeaderPoints().

Referenced by DRAWING_TOOL::DrawZone().

◆ GetLeaderLinePoints()

const SHAPE_LINE_CHAIN & POLYGON_GEOM_MANAGER::GetLeaderLinePoints ( ) const
inline

Get the points comprising the leader line (the line from the last locked-in point to the current cursor position.

How this is drawn will depend on the LEADER_MODE

Definition at line 172 of file polygon_geom_manager.h.

173 {
174 return m_leaderPts;
175 }

References m_leaderPts.

Referenced by ZONE_CREATE_HELPER::OnComplete(), and ZONE_CREATE_HELPER::OnGeometryChange().

◆ GetLeaderMode()

LEADER_MODE POLYGON_GEOM_MANAGER::GetLeaderMode ( ) const
inline

Definition at line 100 of file polygon_geom_manager.h.

101 {
102 return m_leaderMode;
103 }

References m_leaderMode.

Referenced by ZONE_CREATE_HELPER::OnComplete().

◆ GetLockedInPoints()

const SHAPE_LINE_CHAIN & POLYGON_GEOM_MANAGER::GetLockedInPoints ( ) const
inline

Get the "locked-in" points that describe the polygon itself.

Definition at line 161 of file polygon_geom_manager.h.

162 {
163 return m_lockedPoints;
164 }

References m_lockedPoints.

Referenced by ZONE_CREATE_HELPER::OnComplete(), and ZONE_CREATE_HELPER::OnGeometryChange().

◆ IntersectionsAllowed()

bool POLYGON_GEOM_MANAGER::IntersectionsAllowed ( ) const
inline

Check whether self-intersecting polygons are enabled.

Returns
true if self-intersecting polygons are enabled.

Definition at line 120 of file polygon_geom_manager.h.

121 {
123 }

References m_intersectionsAllowed.

◆ IsPolygonInProgress()

bool POLYGON_GEOM_MANAGER::IsPolygonInProgress ( ) const
Returns
true if the polygon in "in progress", i.e. it has at least one locked-in point

Definition at line 110 of file polygon_geom_manager.cpp.

111{
112 return m_lockedPoints.PointCount() > 0;
113}

References m_lockedPoints, and SHAPE_LINE_CHAIN::PointCount().

Referenced by AddPoint(), and DRAWING_TOOL::DrawZone().

◆ IsSelfIntersecting()

bool POLYGON_GEOM_MANAGER::IsSelfIntersecting ( bool  aIncludeLeaderPts) const

Check whether the locked points constitute a self-intersecting outline.

Parameters
aIncludeLeaderPtswhen true, also the leading points (not placed ones) will be tested.
Returns
True when the outline is self-intersecting.

Definition at line 84 of file polygon_geom_manager.cpp.

85{
87
88 if( aIncludeLeaderPts )
89 {
90 for( int i = 0; i < m_leaderPts.PointCount(); ++i )
91 {
92 if( m_leaderPts.CPoint( i ) != pts.CPoint( 0 ) )
93 pts.Append( m_leaderPts.CPoint( i ) );
94 }
95 }
96
97 // line chain needs to be set as closed for proper checks
98 pts.SetClosed( true );
99
100 return !!pts.SelfIntersecting();
101}
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...

References SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::CPoint(), m_leaderPts, m_lockedPoints, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::SelfIntersecting(), and SHAPE_LINE_CHAIN::SetClosed().

Referenced by AddPoint(), and DRAWING_TOOL::DrawZone().

◆ NewPointClosesOutline()

bool POLYGON_GEOM_MANAGER::NewPointClosesOutline ( const VECTOR2I aPt) const
Returns
true if locking in the given point would close the current polygon.

Definition at line 116 of file polygon_geom_manager.cpp.

117{
118 return m_lockedPoints.PointCount() > 0 && m_lockedPoints.CPoint( 0 ) == aPt;
119}

References SHAPE_LINE_CHAIN::CPoint(), m_lockedPoints, and SHAPE_LINE_CHAIN::PointCount().

Referenced by DRAWING_TOOL::DrawZone().

◆ Reset()

void POLYGON_GEOM_MANAGER::Reset ( )

Clear the manager state and start again.

Definition at line 136 of file polygon_geom_manager.cpp.

137{
140
141 m_client.OnGeometryChange( *this );
142}
void Clear()
Remove all points from the line chain.

References SHAPE_LINE_CHAIN::Clear(), m_client, m_leaderPts, m_lockedPoints, and POLYGON_GEOM_MANAGER::CLIENT::OnGeometryChange().

Referenced by DRAWING_TOOL::DrawZone().

◆ SetCursorPosition()

void POLYGON_GEOM_MANAGER::SetCursorPosition ( const VECTOR2I aPos)

Set the current cursor position.

Definition at line 104 of file polygon_geom_manager.cpp.

105{
106 updateLeaderPoints( aPos );
107}

References updateLeaderPoints().

Referenced by DRAWING_TOOL::DrawZone().

◆ SetFinished()

void POLYGON_GEOM_MANAGER::SetFinished ( )

Mark the polygon finished and update the client.

Definition at line 71 of file polygon_geom_manager.cpp.

72{
73
74 m_client.OnComplete( *this );
75}
virtual void OnComplete(const POLYGON_GEOM_MANAGER &aMgr)=0

References m_client, and POLYGON_GEOM_MANAGER::CLIENT::OnComplete().

Referenced by DRAWING_TOOL::DrawZone().

◆ SetLeaderMode()

void POLYGON_GEOM_MANAGER::SetLeaderMode ( LEADER_MODE  aMode)

Set the leader mode to use when calculating the leader/returner lines.

Definition at line 78 of file polygon_geom_manager.cpp.

79{
80 m_leaderMode = aMode;
81}

References m_leaderMode.

Referenced by DRAWING_TOOL::DrawZone(), and ZONE_CREATE_HELPER::OnFirstPoint().

◆ updateLeaderPoints()

void POLYGON_GEOM_MANAGER::updateLeaderPoints ( const VECTOR2I aEndPoint,
LEADER_MODE  aModifier = LEADER_MODE::DIRECT 
)
private

Update the leader line points based on a new endpoint (probably a cursor position)

The "user" of the polygon data that is informed when the geometry changes

Definition at line 145 of file polygon_geom_manager.cpp.

146{
147 wxCHECK( m_lockedPoints.PointCount() > 0, /*void*/ );
148 const VECTOR2I& last_pt = m_lockedPoints.CLastPoint();
149
150 if( m_leaderMode == LEADER_MODE::DEG45 || aModifier == LEADER_MODE::DEG45 )
151 {
152 const VECTOR2I line_vec( aEndPoint - last_pt );
153 // get a restricted 45/H/V line from the last fixed point to the cursor
154 auto new_end = last_pt + GetVectorSnapped45( line_vec );
155 OPT_VECTOR2I pt = boost::make_optional( false, VECTOR2I() );
156
157 if( m_lockedPoints.SegmentCount() > 1 )
158 {
159 const VECTOR2I& start_pt = m_lockedPoints.CPoint( 0 );
160 VECTOR2I completed_vec( start_pt - new_end );
161
162 if( completed_vec != GetVectorSnapped45( completed_vec ) )
163 {
164 SEG v_first( new_end, VECTOR2I( new_end.x, start_pt.y ) );
165 SEG h_first( new_end, VECTOR2I( start_pt.x, new_end.y ) );
166
168 auto v_hits = m_lockedPoints.Intersect( v_first, intersections );
169 v_hits += m_lockedPoints.Intersect( SEG( v_first.B, start_pt ), intersections );
170 pt = v_first.B;
171
172 if( v_hits > 0 )
173 {
174 intersections.clear();
175 auto h_hits = m_lockedPoints.Intersect( h_first, intersections );
176 h_hits += m_lockedPoints.Intersect( SEG( h_first.B, start_pt ), intersections );
177
178 if( h_hits < v_hits )
179 pt = h_first.B;
180 }
181 }
182 }
183
184 m_leaderPts = SHAPE_LINE_CHAIN( { last_pt, new_end } );
185
186 if( pt )
187 {
188 SEG drawn( last_pt, new_end );
189 SEG completed( new_end, *pt );
190
191 /*
192 * Check for backtracking from the point to intersection. If the snapped path to
193 * completion is shorter than what the user actually drew, we want to discard the
194 * drawn point and just use the snapped completion point.
195 */
196 if( drawn.Collinear( completed ) && drawn.SquaredLength() > completed.SquaredLength() )
197 m_leaderPts = SHAPE_LINE_CHAIN( { last_pt, *pt } );
198 else
199 m_leaderPts.Append( *pt );
200 }
201 }
202 else
203 {
204 // direct segment
205 m_leaderPts = SHAPE_LINE_CHAIN( { last_pt, aEndPoint } );
206 }
207
208 m_client.OnGeometryChange( *this );
209}
Definition: seg.h:42
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Find all intersection points between our line chain and the segment aSeg.
int SegmentCount() const
Return the number of segments in this line chain.
std::vector< INTERSECTION > INTERSECTIONS
VECTOR2< T > GetVectorSnapped45(const VECTOR2< T > &aVec, bool only45=false)
Snap a vector onto the nearest 0, 45 or 90 degree line.
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
VECTOR2< int > VECTOR2I
Definition: vector2d.h:607

References SHAPE_LINE_CHAIN::Append(), SEG::B, SHAPE_LINE_CHAIN::CLastPoint(), SEG::Collinear(), SHAPE_LINE_CHAIN::CPoint(), DEG45, GetVectorSnapped45(), SHAPE_LINE_CHAIN::Intersect(), m_client, m_leaderMode, m_leaderPts, m_lockedPoints, POLYGON_GEOM_MANAGER::CLIENT::OnGeometryChange(), SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::SegmentCount(), SEG::SquaredLength(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by DeleteLastCorner(), and SetCursorPosition().

Member Data Documentation

◆ m_client

CLIENT& POLYGON_GEOM_MANAGER::m_client
private

The current mode of the leader line.

Definition at line 187 of file polygon_geom_manager.h.

Referenced by AddPoint(), DeleteLastCorner(), Reset(), SetFinished(), and updateLeaderPoints().

◆ m_intersectionsAllowed

bool POLYGON_GEOM_MANAGER::m_intersectionsAllowed
private

Point that have been "locked in".

Definition at line 193 of file polygon_geom_manager.h.

Referenced by AddPoint(), AllowIntersections(), and IntersectionsAllowed().

◆ m_leaderMode

LEADER_MODE POLYGON_GEOM_MANAGER::m_leaderMode
private

Flag enabling self-intersecting polygons.

Definition at line 190 of file polygon_geom_manager.h.

Referenced by GetLeaderMode(), SetLeaderMode(), and updateLeaderPoints().

◆ m_leaderPts

SHAPE_LINE_CHAIN POLYGON_GEOM_MANAGER::m_leaderPts
private

◆ m_lockedPoints

SHAPE_LINE_CHAIN POLYGON_GEOM_MANAGER::m_lockedPoints
private

The documentation for this class was generated from the following files: