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.

392 lines
12 KiB

5 years ago
5 years ago
5 years ago
5 years ago
11 years ago
11 years ago
5 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
5 years ago
5 years ago
5 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. /*
  2. * KiRouter - a push-and-(sometimes-)shove PCB router
  3. *
  4. * Copyright (C) 2013-2017 CERN
  5. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  8. *
  9. * This program is free software: you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the
  11. * Free Software Foundation, either version 3 of the License, or (at your
  12. * option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License along
  20. * with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. #ifndef __PNS_LINE_PLACER_H
  23. #define __PNS_LINE_PLACER_H
  24. #include <math/vector2d.h>
  25. #include <geometry/shape.h>
  26. #include <geometry/shape_line_chain.h>
  27. #include "pns_line.h"
  28. #include "pns_mouse_trail_tracer.h"
  29. #include "pns_node.h"
  30. #include "pns_placement_algo.h"
  31. #include "pns_sizes_settings.h"
  32. #include "pns_via.h"
  33. #include "pns_walkaround.h"
  34. namespace PNS {
  35. class ROUTER;
  36. class SHOVE;
  37. class OPTIMIZER;
  38. class VIA;
  39. class SIZES_SETTINGS;
  40. class NODE;
  41. class FIXED_TAIL
  42. {
  43. public:
  44. FIXED_TAIL( int aLineCount = 1);
  45. ~FIXED_TAIL();
  46. struct FIX_POINT
  47. {
  48. int layer;
  49. bool placingVias;
  50. VECTOR2I p;
  51. DIRECTION_45 direction;
  52. };
  53. struct STAGE
  54. {
  55. NODE* commit;
  56. std::vector<FIX_POINT> pts;
  57. };
  58. void Clear();
  59. void AddStage( const VECTOR2I& aStart, int aLayer, bool placingVias, DIRECTION_45 direction,
  60. NODE* aNode );
  61. bool PopStage( STAGE& aStage );
  62. int StageCount() const;
  63. private:
  64. std::vector<STAGE> m_stages;
  65. };
  66. /**
  67. * Single track placement algorithm. Interactively routes a track.
  68. * Applies shove and walkaround algorithms when needed.
  69. */
  70. class LINE_PLACER : public PLACEMENT_ALGO
  71. {
  72. public:
  73. LINE_PLACER( ROUTER* aRouter );
  74. ~LINE_PLACER();
  75. /**
  76. * Start routing a single track at point aP, taking item aStartItem as anchor (unless NULL).
  77. */
  78. bool Start( const VECTOR2I& aP, ITEM* aStartItem ) override;
  79. /**
  80. * Move the end of the currently routed trace to the point \a aP, taking \a aEndItem as
  81. * anchor (if not NULL).
  82. */
  83. bool Move( const VECTOR2I& aP, ITEM* aEndItem ) override;
  84. /**
  85. * Commit the currently routed track to the parent node taking \a aP as the final end point
  86. * and \a aEndItem as the final anchor (if provided).
  87. *
  88. * @return true if route has been committed. May return false if the routing result is
  89. * violating design rules. In such cases, the track is only committed if
  90. * CanViolateDRC() is on.
  91. */
  92. bool FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish ) override;
  93. std::optional<VECTOR2I> UnfixRoute() override;
  94. bool CommitPlacement() override;
  95. bool AbortPlacement() override;
  96. bool HasPlacedAnything() const override;
  97. /**
  98. * Enable/disable a via at the end of currently routed trace.
  99. */
  100. bool ToggleVia( bool aEnabled ) override;
  101. /**
  102. * Set the current routing layer.
  103. */
  104. bool SetLayer( int aLayer ) override;
  105. /**
  106. * Return the "head" of the line being placed, that is the volatile part that has not been
  107. * "fixed" yet.
  108. */
  109. const LINE& Head() const { return m_head; }
  110. /**
  111. * Return the "tail" of the line being placed, the part which has already wrapped around
  112. * and shoved some obstacles.
  113. */
  114. const LINE& Tail() const { return m_tail; }
  115. /**
  116. * Return the complete routed line.
  117. */
  118. const LINE Trace() const;
  119. /**
  120. * Return the complete routed line, as a single-member ITEM_SET.
  121. */
  122. const ITEM_SET Traces() override;
  123. /**
  124. * Return the current start of the line being placed.
  125. */
  126. const VECTOR2I& CurrentStart() const override
  127. {
  128. return m_currentStart;
  129. }
  130. /**
  131. * Return the current end of the line being placed. It may not be equal to the cursor
  132. * position due to collisions.
  133. */
  134. const VECTOR2I& CurrentEnd() const override
  135. {
  136. return m_currentEnd;
  137. }
  138. /**
  139. * Return the net of currently routed track.
  140. */
  141. const std::vector<NET_HANDLE> CurrentNets() const override
  142. {
  143. return std::vector<NET_HANDLE>( 1, m_currentNet );
  144. }
  145. /**
  146. * Return the layer of currently routed track.
  147. */
  148. int CurrentLayer() const override
  149. {
  150. return m_currentLayer;
  151. }
  152. /**
  153. * Return the most recent world state.
  154. */
  155. NODE* CurrentNode( bool aLoopsRemoved = false ) const override;
  156. /**
  157. * Toggle the current posture (straight/diagonal) of the trace head.
  158. */
  159. void FlipPosture() override;
  160. /**
  161. * Perform on-the-fly update of the width, via diameter & drill size from a settings class.
  162. *
  163. * Performs on-the-fly update of the width, via diameter & drill size from a settings class.
  164. * Used to dynamically change these parameters as the track is routed.
  165. */
  166. void UpdateSizes( const SIZES_SETTINGS& aSizes ) override;
  167. void SetOrthoMode( bool aOrthoMode ) override;
  168. bool IsPlacingVia() const override { return m_placingVia; }
  169. void GetModifiedNets( std::vector<NET_HANDLE>& aNets ) const override;
  170. /**
  171. * Snaps the point \a aP to segment \a aSeg. Splits the segment in two, forming a
  172. * joint at \a aP and stores updated topology in node \a aNode.
  173. */
  174. bool SplitAdjacentSegments( NODE* aNode, ITEM* aSeg, const VECTOR2I& aP );
  175. /**
  176. * Snaps the point \a aP to arc \a aArc. Splits the arc in two, forming a
  177. * joint at \a aP and stores updated topology in node \a aNode.
  178. */
  179. bool SplitAdjacentArcs( NODE* aNode, ITEM* aArc, const VECTOR2I& aP );
  180. private:
  181. /**
  182. * Re-route the current track to point aP. Returns true, when routing has completed
  183. * successfully (i.e. the trace end has reached point \a aP), and false if the trace was
  184. * stuck somewhere on the way. May call routeStep() repetitively due to mouse smoothing.
  185. *
  186. * @param aP ending point of current route.
  187. * @return true, if the routing is complete.
  188. */
  189. bool route( const VECTOR2I& aP );
  190. /**
  191. * Draw the "leading" rats nest line, which connects the end of currently routed track and
  192. * the nearest yet unrouted item. If the routing for current net is complete, draws nothing.
  193. */
  194. void updateLeadingRatLine();
  195. /**
  196. * Set the board to route.
  197. */
  198. void setWorld( NODE* aWorld );
  199. /**
  200. * Initialize placement of a new line with given parameters.
  201. */
  202. void initPlacement();
  203. /**
  204. * Set preferred direction of the very first track segment to be laid.
  205. * Used by posture switching mechanism.
  206. */
  207. void setInitialDirection( const DIRECTION_45& aDirection );
  208. /**
  209. * Searches aNode for traces concurrent to aLatest and removes them. Updated
  210. * topology is stored in aNode.
  211. */
  212. void removeLoops( NODE* aNode, LINE& aLatest );
  213. /**
  214. * Assemble a line starting from segment or arc aLatest, removes collinear segments
  215. * and redundant vertices. If a simplification has been found, replaces the old line
  216. * with the simplified one in \a aNode.
  217. */
  218. void simplifyNewLine( NODE* aNode, LINKED_ITEM* aLatest );
  219. /**
  220. * Check if the head of the track intersects its tail. If so, cuts the tail up to the
  221. * intersecting segment and fixes the head direction to match the last segment before
  222. * the cut.
  223. *
  224. * @return true if the line has been changed.
  225. */
  226. bool handleSelfIntersections();
  227. /**
  228. * Deal with pull-back: reduces the tail if head trace is moved backwards wrs to the
  229. * current tail direction.
  230. *
  231. * @return true if the line has been changed.
  232. */
  233. bool handlePullback();
  234. /**
  235. * Moves "established" segments from the head to the tail if certain conditions are met.
  236. *
  237. * @return true, if the line has been changed.
  238. */
  239. bool mergeHead();
  240. /**
  241. * Attempt to reduce the number of segments in the tail by trying to replace a certain
  242. * number of latest tail segments with a direct trace leading to \a aEnd that does not
  243. * collide with anything.
  244. *
  245. * @param aEnd is the current routing destination point.
  246. * @return true if the line has been changed.
  247. */
  248. bool reduceTail( const VECTOR2I& aEnd );
  249. /**
  250. * Try to reduce the corner count of the most recent part of tail/head by merging
  251. * obtuse/collinear segments.
  252. *
  253. * @return true if the line has been changed.
  254. */
  255. bool optimizeTailHeadTransition();
  256. /**
  257. * Compute the head trace between the current start point (m_p_start) and point \a aP,
  258. * starting with direction defined in m_direction. The trace walks around all
  259. * colliding solid or non-movable items. Movable segments are ignored, as they'll be
  260. * handled later by the shove algorithm.
  261. */
  262. bool routeHead( const VECTOR2I& aP, LINE& aNewHead, LINE& aNewTail );
  263. /**
  264. * Perform a single routing algorithm step, for the end point \a aP.
  265. *
  266. * @param aP is the ending point of current route.
  267. * @return true if the line has been changed.
  268. */
  269. void routeStep( const VECTOR2I& aP );
  270. ///< Route step walk around mode.
  271. bool rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead, LINE& aNewTail );
  272. bool rhWalkBase( const VECTOR2I& aP, LINE& aWalkLine, int aCollisionMask, PNS::PNS_MODE aMode, bool& aViaOk );
  273. bool splitHeadTail( const LINE& aNewLine, const LINE& aOldTail, LINE& aNewHead, LINE& aNewTail );
  274. bool cursorDistMinimum( const SHAPE_LINE_CHAIN& aL, const VECTOR2I& aCursor, double lengthThreshold, SHAPE_LINE_CHAIN& aOut );
  275. bool clipAndCheckCollisions( const VECTOR2I& aP, const SHAPE_LINE_CHAIN& aL, SHAPE_LINE_CHAIN& aOut, int &thresholdDist );
  276. void updatePStart( const LINE& tail );
  277. //bool rhPostSplitHeadTail( )
  278. ///< Route step shove mode.
  279. bool rhShoveOnly( const VECTOR2I& aP, LINE& aNewHead, LINE& aNewTail );
  280. ///< Route step mark obstacles mode.
  281. bool rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead, LINE& aNewTail );
  282. const VIA makeVia( const VECTOR2I& aP );
  283. bool buildInitialLine( const VECTOR2I& aP, LINE& aHead, PNS::PNS_MODE aMode, bool aForceNoVia = false );
  284. DIRECTION_45 m_direction; ///< current routing direction
  285. DIRECTION_45 m_initial_direction; ///< routing direction for new traces
  286. LINE m_head; ///< the volatile part of the track from the previously
  287. ///< analyzed point to the current routing destination
  288. LINE m_tail; ///< routing "tail": part of the track that has been already
  289. ///< fixed due to collisions with obstacles
  290. NODE* m_world; ///< pointer to world to search colliding items
  291. VECTOR2I m_p_start; ///< current routing start (end of tail, beginning of head)
  292. VECTOR2I m_fixStart; ///< start point of the last 'fix'
  293. std::optional<VECTOR2I> m_last_p_end;
  294. std::unique_ptr<SHOVE> m_shove; ///< The shove engine
  295. NODE* m_currentNode; ///< Current world state
  296. NODE* m_lastNode; ///< Postprocessed world state (including marked collisions &
  297. ///< removed loops)
  298. SIZES_SETTINGS m_sizes;
  299. bool m_placingVia;
  300. NET_HANDLE m_currentNet;
  301. int m_currentLayer;
  302. VECTOR2I m_currentEnd;
  303. VECTOR2I m_currentStart;
  304. LINE m_currentTrace;
  305. ITEM* m_startItem;
  306. ITEM* m_endItem;
  307. bool m_idle;
  308. bool m_chainedPlacement;
  309. bool m_orthoMode;
  310. bool m_placementCorrect;
  311. FIXED_TAIL m_fixedTail;
  312. MOUSE_TRAIL_TRACER m_mouseTrailTracer;
  313. };
  314. }
  315. #endif // __PNS_LINE_PLACER_H