1 /* 2 * KiRouter - a push-and-(sometimes-)shove PCB router 3 * 4 * Copyright (C) 2013-2014 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_ROUTER_H 23 #define __PNS_ROUTER_H 24 25 #include <list> 26 #include <memory> 27 #include <core/optional.h> 28 #include <math/box2.h> 29 30 #include "pns_routing_settings.h" 31 #include "pns_sizes_settings.h" 32 #include "pns_node.h" 33 34 namespace KIGFX 35 { 36 37 class VIEW; 38 class VIEW_GROUP; 39 40 } 41 42 namespace PNS { 43 44 class DEBUG_DECORATOR; 45 class NODE; 46 class DIFF_PAIR_PLACER; 47 class PLACEMENT_ALGO; 48 class LINE_PLACER; 49 class ITEM; 50 class ARC; 51 class LINE; 52 class SOLID; 53 class SEGMENT; 54 class JOINT; 55 class VIA; 56 class RULE_RESOLVER; 57 class SHOVE; 58 class DRAGGER; 59 class DRAG_ALGO; 60 class LOGGER; 61 62 enum ROUTER_MODE { 63 PNS_MODE_ROUTE_SINGLE = 1, 64 PNS_MODE_ROUTE_DIFF_PAIR, 65 PNS_MODE_TUNE_SINGLE, 66 PNS_MODE_TUNE_DIFF_PAIR, 67 PNS_MODE_TUNE_DIFF_PAIR_SKEW 68 }; 69 70 enum DRAG_MODE 71 { 72 DM_CORNER = 0x1, 73 DM_SEGMENT = 0x2, 74 DM_VIA = 0x4, 75 DM_FREE_ANGLE = 0x8, 76 DM_ARC = 0x10, 77 DM_ANY = 0x17, 78 DM_COMPONENT = 0x20 79 }; 80 /** 81 * ROUTER 82 * 83 * Main router class. 84 */ 85 86 class ROUTER_IFACE 87 { 88 public: ROUTER_IFACE()89 ROUTER_IFACE() {}; ~ROUTER_IFACE()90 virtual ~ROUTER_IFACE() {}; 91 92 virtual void SyncWorld( NODE* aNode ) = 0; 93 virtual void AddItem( ITEM* aItem ) = 0; 94 virtual void UpdateItem( ITEM* aItem ) = 0; 95 virtual void RemoveItem( ITEM* aItem ) = 0; 96 virtual bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const = 0; 97 virtual bool IsItemVisible( const PNS::ITEM* aItem ) const = 0; 98 virtual bool IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer ) const = 0; 99 virtual void DisplayItem( const ITEM* aItem, int aClearance, bool aEdit = false ) = 0; 100 virtual void DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, int aColor = -1 ) = 0; 101 virtual void HideItem( ITEM* aItem ) = 0; 102 virtual void Commit() = 0; 103 virtual bool ImportSizes( SIZES_SETTINGS& aSizes, ITEM* aStartItem, int aNet ) = 0; 104 virtual int StackupHeight( int aFirstLayer, int aSecondLayer ) const = 0; 105 106 virtual void EraseView() = 0; 107 virtual void UpdateNet( int aNetCode ) = 0; 108 109 virtual PNS::NODE* GetWorld() const = 0; 110 111 virtual RULE_RESOLVER* GetRuleResolver() = 0; 112 virtual DEBUG_DECORATOR* GetDebugDecorator() = 0; 113 }; 114 115 class ROUTER 116 { 117 public: 118 enum RouterState 119 { 120 IDLE, 121 DRAG_SEGMENT, 122 DRAG_COMPONENT, 123 ROUTE_TRACK 124 }; 125 126 public: 127 ROUTER(); 128 ~ROUTER(); 129 130 void SetInterface( ROUTER_IFACE* aIface ); 131 void SetMode ( ROUTER_MODE aMode ); Mode()132 ROUTER_MODE Mode() const { return m_mode; } 133 GetState()134 RouterState GetState() const { return m_state; } 135 GetDragger()136 DRAG_ALGO* GetDragger() { return m_dragger.get(); } 137 138 static ROUTER* GetInstance(); 139 140 void ClearWorld(); 141 void SyncWorld(); 142 143 bool RoutingInProgress() const; 144 bool StartRouting( const VECTOR2I& aP, ITEM* aItem, int aLayer ); 145 void Move( const VECTOR2I& aP, ITEM* aItem ); 146 bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish = false ); 147 void BreakSegment( ITEM *aItem, const VECTOR2I& aP ); 148 149 void UndoLastSegment(); 150 void CommitRouting(); 151 void StopRouting(); 152 void ClearViewDecorations(); 153 GetWorld()154 NODE* GetWorld() const { return m_world.get(); } 155 156 void FlipPosture(); 157 158 bool SwitchLayer( int layer ); 159 160 void ToggleViaPlacement(); 161 void SetOrthoMode( bool aEnable ); 162 163 void ToggleCornerMode(); 164 165 int GetCurrentLayer() const; 166 const std::vector<int> GetCurrentNets() const; 167 168 LOGGER* Logger(); 169 GetRuleResolver()170 RULE_RESOLVER* GetRuleResolver() const { return m_iface->GetRuleResolver(); } 171 172 bool IsPlacingVia() const; 173 174 const ITEM_SET QueryHoverItems( const VECTOR2I& aP, bool aUseClearance = false ); 175 176 bool StartDragging( const VECTOR2I& aP, ITEM* aItem, int aDragMode = DM_ANY ); 177 bool StartDragging( const VECTOR2I& aP, ITEM_SET aItems, int aDragMode = DM_COMPONENT ); 178 SetIterLimit(int aX)179 void SetIterLimit( int aX ) { m_iterLimit = aX; } GetIterLimit()180 int GetIterLimit() const { return m_iterLimit; }; 181 Settings()182 ROUTING_SETTINGS& Settings() { return *m_settings; } 183 184 void CommitRouting( NODE* aNode ); 185 186 /** 187 * Applies stored settings. 188 * @see Settings() 189 */ 190 void UpdateSizes( const SIZES_SETTINGS& aSizes ); 191 192 /** 193 * Changes routing settings to ones passed in the parameter. 194 * @param aSettings are the new settings. 195 */ LoadSettings(ROUTING_SETTINGS * aSettings)196 void LoadSettings( ROUTING_SETTINGS* aSettings ) 197 { 198 m_settings = aSettings; 199 } 200 Sizes()201 SIZES_SETTINGS& Sizes() { return m_sizes; } 202 SetFailureReason(const wxString & aReason)203 void SetFailureReason( const wxString& aReason ) { m_failureReason = aReason; } FailureReason()204 const wxString& FailureReason() const { return m_failureReason; } 205 Placer()206 PLACEMENT_ALGO* Placer() { return m_placer.get(); } 207 GetInterface()208 ROUTER_IFACE* GetInterface() const { return m_iface; } 209 SetVisibleViewArea(const BOX2I & aExtents)210 void SetVisibleViewArea( const BOX2I& aExtents ) { m_visibleViewArea = aExtents; } VisibleViewArea()211 const BOX2I& VisibleViewArea() const { return m_visibleViewArea; } 212 213 private: 214 void movePlacing( const VECTOR2I& aP, ITEM* aItem ); 215 void moveDragging( const VECTOR2I& aP, ITEM* aItem ); 216 217 void updateView( NODE* aNode, ITEM_SET& aCurrent, bool aDragging = false ); 218 219 // optHoverItem queryHoverItemEx(const VECTOR2I& aP); 220 221 void markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved ); 222 bool isStartingPointRoutable( const VECTOR2I& aWhere, ITEM* aItem, int aLayer ); 223 224 private: 225 BOX2I m_visibleViewArea; 226 RouterState m_state; 227 228 std::unique_ptr<NODE> m_world; 229 NODE* m_lastNode; 230 231 std::unique_ptr<PLACEMENT_ALGO> m_placer; 232 std::unique_ptr<DRAG_ALGO> m_dragger; 233 std::unique_ptr<SHOVE> m_shove; 234 235 ROUTER_IFACE* m_iface; 236 237 int m_iterLimit; 238 bool m_forceMarkObstaclesMode = false; 239 240 ROUTING_SETTINGS* m_settings; 241 SIZES_SETTINGS m_sizes; 242 ROUTER_MODE m_mode; 243 LOGGER* m_logger; 244 245 wxString m_toolStatusbarName; 246 wxString m_failureReason; 247 }; 248 249 } 250 251 #endif 252