You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
7.8 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  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. #ifndef __PNS_LINE_H
  22. #define __PNS_LINE_H
  23. #include <math/box2.h>
  24. #include <math/vector2d.h>
  25. #include <geometry/direction45.h>
  26. #include <geometry/seg.h>
  27. #include <geometry/shape.h>
  28. #include <geometry/shape_line_chain.h>
  29. #include "pns_item.h"
  30. #include "pns_via.h"
  31. #include "pns_link_holder.h"
  32. namespace PNS {
  33. class LINKED_ITEM;
  34. class NODE;
  35. class VIA;
  36. /**
  37. * LINE
  38. *
  39. * Represents a track on a PCB, connecting two non-trivial joints (that is,
  40. * vias, pads, junctions between multiple traces or two traces different widths
  41. * and combinations of these). PNS_LINEs are NOT stored in the model (NODE).
  42. * Instead, they are assembled on-the-fly, based on a via/pad/segment that
  43. * belongs to/starts/ends them.
  44. *
  45. * PNS_LINEs can be either loose (consisting of segments that do not belong to
  46. * any NODE) or owned (with segments taken from a NODE) - these are
  47. * returned by NODE::AssembleLine and friends.
  48. *
  49. * A LINE may have a VIA attached at its end (i.e. the last point) - this is used by via
  50. * dragging/force propagation stuff.
  51. */
  52. #define PNS_HULL_MARGIN 10
  53. class LINE : public LINK_HOLDER
  54. {
  55. public:
  56. /**
  57. * Constructor
  58. * Makes an empty line.
  59. */
  60. LINE() : LINK_HOLDER( LINE_T )
  61. {
  62. m_hasVia = false;
  63. m_width = 1; // Dummy value
  64. m_snapThreshhold = 0;
  65. }
  66. LINE( const LINE& aOther );
  67. /**
  68. * Constructor
  69. * Copies properties (net, layers, etc.) from a base line and replaces the shape
  70. * by another
  71. **/
  72. LINE( const LINE& aBase, const SHAPE_LINE_CHAIN& aLine )
  73. : LINK_HOLDER( aBase ),
  74. m_line( aLine ),
  75. m_width( aBase.m_width ),
  76. m_snapThreshhold( aBase.m_snapThreshhold )
  77. {
  78. m_net = aBase.m_net;
  79. m_layers = aBase.m_layers;
  80. m_hasVia = false;
  81. }
  82. /**
  83. * Constructor
  84. * Constructs a LINE for a lone VIA (ie a stitching via).
  85. * @param aVia
  86. */
  87. LINE( const VIA& aVia ) :
  88. LINK_HOLDER( LINE_T )
  89. {
  90. m_hasVia = true;
  91. m_via = aVia;
  92. m_width = aVia.Diameter();
  93. m_net = aVia.Net();
  94. m_layers = aVia.Layers();
  95. m_rank = aVia.Rank();
  96. m_snapThreshhold = 0;
  97. }
  98. ~LINE();
  99. static inline bool ClassOf( const ITEM* aItem )
  100. {
  101. return aItem && LINE_T == aItem->Kind();
  102. }
  103. /// @copydoc ITEM::Clone()
  104. virtual LINE* Clone() const override;
  105. LINE& operator=( const LINE& aOther );
  106. bool IsLinkedChecked() const
  107. {
  108. return IsLinked() && LinkCount() == SegmentCount();
  109. }
  110. ///> Assigns a shape to the line (a polyline/line chain)
  111. void SetShape( const SHAPE_LINE_CHAIN& aLine )
  112. {
  113. m_line = aLine;
  114. m_line.SetWidth( m_width );
  115. }
  116. ///> Returns the shape of the line
  117. const SHAPE* Shape() const override
  118. {
  119. return &m_line;
  120. }
  121. ///> Modifiable accessor to the underlying shape
  122. SHAPE_LINE_CHAIN& Line()
  123. {
  124. return m_line;
  125. }
  126. ///> Const accessor to the underlying shape
  127. const SHAPE_LINE_CHAIN& CLine() const
  128. {
  129. return m_line;
  130. }
  131. ///> Returns the number of segments in the line
  132. int SegmentCount() const
  133. {
  134. return m_line.SegmentCount();
  135. }
  136. ///> Returns the number of points in the line
  137. int PointCount() const
  138. {
  139. return m_line.PointCount();
  140. }
  141. ///> Returns the number of arcs in the line
  142. int ArcCount() const
  143. {
  144. return m_line.ArcCount();
  145. }
  146. ///> Returns the aIdx-th point of the line
  147. const VECTOR2I& CPoint( int aIdx ) const
  148. {
  149. return m_line.CPoint( aIdx );
  150. }
  151. ///> Returns the aIdx-th segment of the line
  152. const SEG CSegment( int aIdx ) const
  153. {
  154. return m_line.CSegment( aIdx );
  155. }
  156. ///> Sets line width
  157. void SetWidth( int aWidth )
  158. {
  159. m_width = aWidth;
  160. m_line.SetWidth( aWidth );
  161. }
  162. ///> Returns line width
  163. int Width() const
  164. {
  165. return m_width;
  166. }
  167. ///> Returns true if the line is geometrically identical as line aOther
  168. bool CompareGeometry( const LINE& aOther );
  169. ///> Reverses the point/vertex order
  170. void Reverse();
  171. ///> Clips the line to the nearest obstacle, traversing from the line's start vertex (0).
  172. ///> Returns the clipped line.
  173. const LINE ClipToNearestObstacle( NODE* aNode ) const;
  174. ///> Clips the line to a given range of vertices.
  175. void ClipVertexRange ( int aStart, int aEnd );
  176. ///> Returns the number of corners of angles specified by mask aAngles.
  177. int CountCorners( int aAngles ) const;
  178. ///> Calculates a line thightly wrapping a convex hull
  179. ///> of an obstacle object (aObstacle).
  180. ///> aPrePath = path from origin to the obstacle
  181. ///> aWalkaroundPath = path around the obstacle
  182. ///> aPostPath = past from obstacle till the end
  183. ///> aCW = whether to walk around in clockwise or counter-clockwise direction.
  184. bool Walkaround( SHAPE_LINE_CHAIN aObstacle,
  185. SHAPE_LINE_CHAIN& aPre,
  186. SHAPE_LINE_CHAIN& aWalk,
  187. SHAPE_LINE_CHAIN& aPost,
  188. bool aCw ) const;
  189. bool Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
  190. SHAPE_LINE_CHAIN& aPath,
  191. bool aCw ) const;
  192. bool Is45Degree() const;
  193. ///> Prints out all linked segments
  194. void ShowLinks() const;
  195. bool EndsWithVia() const { return m_hasVia; }
  196. void AppendVia( const VIA& aVia );
  197. void RemoveVia() { m_hasVia = false; }
  198. const VIA& Via() const { return m_via; }
  199. virtual void Mark( int aMarker ) const override;
  200. virtual void Unmark( int aMarker = -1 ) const override;
  201. virtual int Marker() const override;
  202. void DragSegment( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
  203. void DragCorner( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
  204. void SetRank( int aRank ) override;
  205. int Rank() const override;
  206. bool HasLoops() const;
  207. bool HasLockedSegments() const;
  208. void Clear();
  209. void Merge ( const LINE& aOther );
  210. OPT_BOX2I ChangedArea( const LINE* aOther ) const;
  211. void SetSnapThreshhold( int aThreshhold )
  212. {
  213. m_snapThreshhold = aThreshhold;
  214. }
  215. int GetSnapThreshhold() const
  216. {
  217. return m_snapThreshhold;
  218. }
  219. private:
  220. void dragSegment45( const VECTOR2I& aP, int aIndex );
  221. void dragCorner45( const VECTOR2I& aP, int aIndex );
  222. void dragSegmentFree( const VECTOR2I& aP, int aIndex );
  223. void dragCornerFree( const VECTOR2I& aP, int aIndex );
  224. VECTOR2I snapToNeighbourSegments(
  225. const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP, int aIndex ) const;
  226. VECTOR2I snapDraggedCorner(
  227. const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP, int aIndex ) const;
  228. ///> The actual shape of the line
  229. SHAPE_LINE_CHAIN m_line;
  230. ///> our width
  231. int m_width;
  232. ///> If true, the line ends with a via
  233. bool m_hasVia;
  234. ///> Width to smooth out jagged segments
  235. int m_snapThreshhold;
  236. ///> Via at the end point, if m_hasVia == true
  237. VIA m_via;
  238. };
  239. }
  240. #endif // __PNS_LINE_H