Horizon
pns_line.h
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2017 CERN
5  * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
6  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  *
8  * This program is free software: you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation, either version 3 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef __PNS_LINE_H
23 #define __PNS_LINE_H
24 
25 #include <math/vector2d.h>
26 
27 #include <geometry/direction45.h>
28 #include <geometry/seg.h>
29 #include <geometry/shape.h>
30 #include <geometry/shape_line_chain.h>
31 
32 #include "pns_item.h"
33 #include "pns_via.h"
34 
35 namespace PNS {
36 
37 class NODE;
38 class SEGMENT;
39 class VIA;
40 
58 #define PNS_HULL_MARGIN 10
59 
60 class LINE : public ITEM
61 {
62 public:
63  typedef std::vector<SEGMENT*> SEGMENT_REFS;
64 
69  LINE() : ITEM( LINE_T )
70  {
71  m_hasVia = false;
72  m_width = 1; // Dummy value
73  }
74 
75  LINE( const LINE& aOther );
76 
82  LINE( const LINE& aBase, const SHAPE_LINE_CHAIN& aLine ) :
83  ITEM( aBase ),
84  m_line( aLine ),
85  m_width( aBase.m_width )
86  {
87  m_net = aBase.m_net;
88  m_layers = aBase.m_layers;
89  m_hasVia = false;
90  }
91 
92  ~LINE();
93 
94  static inline bool ClassOf( const ITEM* aItem )
95  {
96  return aItem && LINE_T == aItem->Kind();
97  }
98 
100  virtual LINE* Clone() const override;
101 
102  const LINE& operator=( const LINE& aOther );
103 
105  void SetShape( const SHAPE_LINE_CHAIN& aLine )
106  {
107  m_line = aLine;
108  }
109 
111  const SHAPE* Shape() const override
112  {
113  return &m_line;
114  }
115 
118  {
119  return m_line;
120  }
121 
123  const SHAPE_LINE_CHAIN& CLine() const
124  {
125  return m_line;
126  }
127 
129  int SegmentCount() const
130  {
131  return m_line.SegmentCount();
132  }
133 
135  int PointCount() const
136  {
137  return m_line.PointCount();
138  }
139 
141  const VECTOR2I& CPoint( int aIdx ) const
142  {
143  return m_line.CPoint( aIdx );
144  }
145 
147  const SEG CSegment( int aIdx ) const
148  {
149  return m_line.CSegment( aIdx );
150  }
151 
153  void SetWidth( int aWidth )
154  {
155  m_width = aWidth;
156  }
157 
159  int Width() const
160  {
161  return m_width;
162  }
163 
165  bool CompareGeometry( const LINE& aOther );
166 
168  void Reverse();
169 
170 
171  /* Linking functions */
172 
174  void LinkSegment( SEGMENT* aSeg )
175  {
176  m_segmentRefs.push_back( aSeg );
177  }
178 
181  SEGMENT_REFS& LinkedSegments()
182  {
183  return m_segmentRefs;
184  }
185 
186  bool IsLinked() const
187  {
188  return m_segmentRefs.size() != 0;
189  }
190 
191  bool IsLinkedChecked() const
192  {
193  return IsLinked() && LinkCount() == SegmentCount();
194  }
195 
197  bool ContainsSegment( SEGMENT* aSeg ) const
198  {
199  return std::find( m_segmentRefs.begin(), m_segmentRefs.end(),
200  aSeg ) != m_segmentRefs.end();
201  }
202 
203  SEGMENT* GetLink( int aIndex ) const
204  {
205  return m_segmentRefs[aIndex];
206  }
207 
209  void ClearSegmentLinks();
210 
212  int LinkCount() const
213  {
214  return m_segmentRefs.size();
215  }
216 
219  const LINE ClipToNearestObstacle( NODE* aNode ) const;
220 
222  void ClipVertexRange ( int aStart, int aEnd );
223 
225  int CountCorners( int aAngles ) const;
226 
233  bool Walkaround( SHAPE_LINE_CHAIN aObstacle,
234  SHAPE_LINE_CHAIN& aPre,
235  SHAPE_LINE_CHAIN& aWalk,
236  SHAPE_LINE_CHAIN& aPost,
237  bool aCw ) const;
238 
239  bool Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
240  SHAPE_LINE_CHAIN& aPath,
241  bool aCw ) const;
242 
243  bool Is45Degree() const;
244 
246  void ShowLinks() const;
247 
248  bool EndsWithVia() const { return m_hasVia; }
249 
250  void AppendVia( const VIA& aVia );
251  void RemoveVia() { m_hasVia = false; }
252 
253  const VIA& Via() const { return m_via; }
254 
255  virtual void Mark( int aMarker ) override;
256  virtual void Unmark( int aMarker = -1 ) override;
257  virtual int Marker() const override;
258 
259  void DragSegment( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0, bool aFreeAngle = false );
260  void DragCorner( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0, bool aFreeAngle = false );
261 
262  void SetRank( int aRank ) override;
263  int Rank() const override;
264 
265  bool HasLoops() const;
266  bool HasLockedSegments() const;
267 
268  OPT_BOX2I ChangedArea( const LINE* aOther ) const;
269 
270 private:
271 
272  void dragSegment45( const VECTOR2I& aP, int aIndex, int aSnappingThreshold );
273  void dragCorner45( const VECTOR2I& aP, int aIndex, int aSnappingThreshold );
274  void dragSegmentFree( const VECTOR2I& aP, int aIndex, int aSnappingThreshold );
275  void dragCornerFree( const VECTOR2I& aP, int aIndex, int aSnappingThreshold );
276 
277  VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
278  int aIndex, int aThreshold) const;
279 
280  VECTOR2I snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
281  int aIndex, int aThreshold ) const;
282 
284  void copyLinks( const LINE* aParent ) ;
285 
288  SEGMENT_REFS m_segmentRefs;
289 
291  SHAPE_LINE_CHAIN m_line;
292 
294  int m_width;
295 
297  bool m_hasVia;
298 
300  VIA m_via;
301 };
302 
303 }
304 
305 #endif // __PNS_LINE_H
PNS::LINE
Definition: pns_line.h:60
PNS::LINE::Walkaround
bool Walkaround(SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN &aPre, SHAPE_LINE_CHAIN &aWalk, SHAPE_LINE_CHAIN &aPost, bool aCw) const
Calculates a line thightly wrapping a convex hull of an obstacle object (aObstacle).
Definition: pns_line.cpp:158
PNS::LINE::LinkSegment
void LinkSegment(SEGMENT *aSeg)
Adds a reference to a segment registered in a NODE that is a part of this line.
Definition: pns_line.h:174
PNS::LINE::CountCorners
int CountCorners(int aAngles) const
Returns the number of corners of angles specified by mask aAngles.
Definition: pns_line.cpp:136
PNS::LINE::CLine
const SHAPE_LINE_CHAIN & CLine() const
Const accessor to the underlying shape
Definition: pns_line.h:123
PNS::SEGMENT
Definition: pns_segment.h:38
SHAPE_LINE_CHAIN::SegmentCount
int SegmentCount() const
Function SegmentCount()
Definition: shape_line_chain.h:171
SHAPE_LINE_CHAIN::CSegment
const SEG CSegment(int aIndex) const
Function CSegment()
Definition: shape_line_chain.h:218
PNS::LINE::CPoint
const VECTOR2I & CPoint(int aIdx) const
Returns the aIdx-th point of the line
Definition: pns_line.h:141
VECTOR2< int >
PNS::LINE::SetShape
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Assigns a shape to the line (a polyline/line chain)
Definition: pns_line.h:105
PNS::LINE::Reverse
void Reverse()
Reverses the point/vertex order
Definition: pns_line.cpp:733
PNS::LINE::ClipToNearestObstacle
const LINE ClipToNearestObstacle(NODE *aNode) const
Clips the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:302
PNS::LINE::SetWidth
void SetWidth(int aWidth)
Sets line width
Definition: pns_line.h:153
PNS::LINE::ClipVertexRange
void ClipVertexRange(int aStart, int aEnd)
Clips the line to a given range of vertices.
Definition: pns_line.cpp:783
PNS::LINE::PointCount
int PointCount() const
Returns the number of points in the line
Definition: pns_line.h:135
PNS::LINE::Shape
const SHAPE * Shape() const override
Returns the shape of the line
Definition: pns_line.h:111
SHAPE_LINE_CHAIN::PointCount
int PointCount() const
Function PointCount()
Definition: shape_line_chain.h:186
SHAPE_LINE_CHAIN::CPoint
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
Definition: shape_line_chain.h:253
PNS::LINE::ContainsSegment
bool ContainsSegment(SEGMENT *aSeg) const
Checks if the segment aSeg is a part of the line.
Definition: pns_line.h:197
SEG
Definition: seg.h:36
PNS::ITEM
Class ITEM.
Definition: pns_item.h:54
PNS::LINE::ClearSegmentLinks
void ClearSegmentLinks()
Erases the linking information. Used to detach the line from the owning node.
Definition: pns_line.cpp:818
PNS::LINE::LinkedSegments
SEGMENT_REFS & LinkedSegments()
Returns the list of segments from the owning node that constitute this line (or NULL if the line is n...
Definition: pns_line.h:181
PNS::LINE::Line
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:117
PNS::LINE::ShowLinks
void ShowLinks() const
Prints out all linked segments
Definition: pns_line.cpp:328
PNS::NODE
Class NODE.
Definition: pns_node.h:136
SHAPE_LINE_CHAIN
Class SHAPE_LINE_CHAIN.
Definition: shape_line_chain.h:47
PNS::ITEM::Kind
PnsKind Kind() const
Function Kind()
Definition: pns_item.h:123
SHAPE
Class SHAPE.
Definition: shape.h:58
PNS::LINE::LINE
LINE(const LINE &aBase, const SHAPE_LINE_CHAIN &aLine)
Constructor Copies properties (net, layers, etc.) from a base line and replaces the shape by another.
Definition: pns_line.h:82
PNS::LINE::Clone
virtual LINE * Clone() const override
Function Clone()
Definition: pns_line.cpp:76
PNS::LINE::LinkCount
int LinkCount() const
Returns the number of segments that were assembled together to form this line.
Definition: pns_line.h:212
PNS::LINE::CompareGeometry
bool CompareGeometry(const LINE &aOther)
Returns true if the line is geometrically identical as line aOther
Definition: pns_line.cpp:727
PNS::LINE::LINE
LINE()
Constructor Makes an empty line.
Definition: pns_line.h:69
PNS::LINE::Width
int Width() const
Returns line width
Definition: pns_line.h:159
PNS::LINE::SegmentCount
int SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:129
PNS::LINE::CSegment
const SEG CSegment(int aIdx) const
Returns the aIdx-th segment of the line
Definition: pns_line.h:147