1 /* 2 * KiRouter - a push-and-(sometimes-)shove PCB router 3 * 4 * Copyright (C) 2013-2014 CERN 5 * Copyright (C) 2016-2021 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 23 #ifndef __PNS_DIFF_PLACER_H 24 #define __PNS_DIFF_PLACER_H 25 26 #include <math/vector2d.h> 27 28 #include "pns_sizes_settings.h" 29 #include "pns_node.h" 30 #include "pns_via.h" 31 #include "pns_line.h" 32 #include "pns_algo_base.h" 33 #include "pns_diff_pair.h" 34 35 #include "pns_placement_algo.h" 36 37 namespace PNS { 38 39 class ROUTER; 40 class SHOVE; 41 class OPTIMIZER; 42 class VIA; 43 class SIZES_SETTINGS; 44 45 46 /** 47 * Single track placement algorithm. 48 * 49 * Interactively routes a track and applies shove and walk around algorithms when needed. 50 */ 51 52 class DIFF_PAIR_PLACER : public PLACEMENT_ALGO 53 { 54 public: 55 DIFF_PAIR_PLACER( ROUTER* aRouter ); 56 ~DIFF_PAIR_PLACER(); 57 58 static bool FindDpPrimitivePair( NODE* aWorld, const VECTOR2I& aP, ITEM* aItem, 59 DP_PRIMITIVE_PAIR& aPair, wxString* aErrorMsg = nullptr ); 60 61 /** 62 * Start routing a single track at point aP, taking item aStartItem as anchor (unless NULL). 63 */ 64 bool Start( const VECTOR2I& aP, ITEM* aStartItem ) override; 65 66 /** 67 * Move the end of the currently routed trace to the point \a aP, taking \a aEndItem as 68 * anchor (if not NULL). 69 */ 70 bool Move( const VECTOR2I& aP, ITEM* aEndItem ) override; 71 72 /** 73 * Commit the currently routed track to the parent node, taking \a aP as the final end 74 * point and \a aEndItem as the final anchor (if provided). 75 * 76 * @return true if route has been committed. May return false if the routing result is 77 * violating design rules. In such cases, the track is only committed if 78 * #Settings.CanViolateDRC() is on. 79 */ 80 bool FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish ) override; 81 82 /// @copydoc PLACEMENT_ALGO::CommitPlacement() 83 bool CommitPlacement() override; 84 85 /// @copydoc PLACEMENT_ALGO::AbortPlacement() 86 bool AbortPlacement() override; 87 88 /// @copydoc PLACEMENT_ALGO::HasPlacedAnything() 89 bool HasPlacedAnything() const override; 90 91 /** 92 * Enable/disable a via at the end of currently routed trace. 93 */ 94 bool ToggleVia( bool aEnabled ) override; 95 96 /** 97 * Set the current routing layer. 98 */ 99 bool SetLayer( int aLayer ) override; 100 101 /** 102 * Return the complete routed line, as a single-member ITEM_SET. 103 */ 104 const ITEM_SET Traces() override; 105 106 /** 107 * Return the current end of the line being placed. It may not be equal to the cursor 108 * position due to collisions. 109 */ CurrentEnd()110 const VECTOR2I& CurrentEnd() const override 111 { 112 return m_currentEnd; 113 } 114 115 /** 116 * Return the net code of currently routed track. 117 */ 118 const std::vector<int> CurrentNets() const override; 119 120 /** 121 * Return the layer of currently routed track. 122 */ CurrentLayer()123 int CurrentLayer() const override 124 { 125 return m_currentLayer; 126 } 127 128 /** 129 * Return the most recent world state. 130 */ 131 NODE* CurrentNode( bool aLoopsRemoved = false ) const override; 132 133 /** 134 * Toggle the current posture (straight/diagonal) of the trace head. 135 */ 136 void FlipPosture() override; 137 138 /** 139 * Perform on-the-fly update of the width, via diameter & drill size from a settings class. 140 * 141 * Used to dynamically change these parameters as the track is routed. 142 */ 143 void UpdateSizes( const SIZES_SETTINGS& aSizes ) override; 144 IsPlacingVia()145 bool IsPlacingVia() const override { return m_placingVia; } 146 147 void SetOrthoMode( bool aOrthoMode ) override; 148 149 void GetModifiedNets( std::vector<int>& aNets ) const override; 150 151 private: 152 int viaGap() const; 153 int gap() const; 154 155 /** 156 * Re-route the current track to point \a aP. 157 * 158 * Returns true, when routing has completed successfully (i.e. the trace end has reached 159 * point aP), and false if the trace was stuck somewhere on the way. May call routeStep() 160 * repetitively due to mouse smoothing. 161 * 162 * @param aP is the ending point of current route. 163 * @return true if the routing is complete. 164 */ 165 bool route( const VECTOR2I& aP ); 166 167 /** 168 * Draw the "leading" ratsnest line, which connects the end of currently routed track and 169 * the nearest yet unrouted item. If the routing for current net is complete, draws nothing. 170 */ 171 void updateLeadingRatLine(); 172 173 /** 174 * Set the board to route. 175 */ 176 void setWorld( NODE* aWorld ); 177 178 /** 179 * Initialize placement of a new line with given parameters. 180 */ 181 void initPlacement( ); 182 183 /** 184 * Set preferred direction of the very first track segment to be laid. 185 * 186 * Used by posture switching mechanism. 187 */ 188 void setInitialDirection( const DIRECTION_45& aDirection ); 189 190 191 bool routeHead( const VECTOR2I& aP ); 192 bool tryWalkDp( NODE* aNode, DIFF_PAIR& aPair, bool aSolidsOnly ); 193 194 ///< route step, walk around mode 195 bool rhWalkOnly( const VECTOR2I& aP ); 196 197 ///< route step, shove mode 198 bool rhShoveOnly ( const VECTOR2I& aP ); 199 200 ///< route step, mark obstacles mode 201 bool rhMarkObstacles( const VECTOR2I& aP ); 202 203 const VIA makeVia ( const VECTOR2I& aP, int aNet ); 204 205 bool attemptWalk( NODE* aNode, DIFF_PAIR* aCurrent, DIFF_PAIR& aWalk, bool aPFirst, 206 bool aWindCw, bool aSolidsOnly ); 207 bool propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP ); 208 209 enum State { 210 RT_START = 0, 211 RT_ROUTE = 1, 212 RT_FINISH = 2 213 }; 214 215 State m_state; 216 217 bool m_chainedPlacement; 218 bool m_initialDiagonal; 219 bool m_startDiagonal; 220 bool m_fitOk; 221 222 int m_netP, m_netN; 223 224 DP_PRIMITIVE_PAIR m_start; 225 OPT<DP_PRIMITIVE_PAIR> m_prevPair; 226 227 ///< current algorithm iteration 228 int m_iteration; 229 230 ///< pointer to world to search colliding items 231 NODE* m_world; 232 233 ///< current routing start point (end of tail, beginning of head) 234 VECTOR2I m_p_start; 235 236 ///< The shove engine 237 std::unique_ptr<SHOVE> m_shove; 238 239 ///< Current world state 240 NODE* m_currentNode; 241 242 ///< Postprocessed world state (including marked collisions & removed loops) 243 NODE* m_lastNode; 244 245 SIZES_SETTINGS m_sizes; 246 247 ///< Are we placing a via? 248 bool m_placingVia; 249 250 ///< current via diameter 251 int m_viaDiameter; 252 253 ///< current via drill 254 int m_viaDrill; 255 256 ///< current track width 257 int m_currentWidth; 258 259 int m_currentNet; 260 int m_currentLayer; 261 262 bool m_startsOnVia; 263 bool m_orthoMode; 264 bool m_snapOnTarget; 265 266 VECTOR2I m_currentEnd, m_currentStart; 267 DIFF_PAIR m_currentTrace; 268 bool m_currentTraceOk; 269 270 ITEM* m_currentEndItem; 271 272 bool m_idle; 273 }; 274 275 } 276 277 #endif // __PNS_LINE_PLACER_H 278