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.

1458 lines
36 KiB

5 years ago
7 years ago
7 years ago
7 years ago
7 years ago
5 years ago
10 years ago
10 years ago
10 years ago
10 years ago
5 years ago
10 years ago
5 years ago
5 years ago
5 years ago
11 years ago
10 years ago
10 years ago
7 years ago
5 years ago
5 years ago
5 years ago
10 years ago
10 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
11 years ago
5 years ago
5 years ago
11 years ago
5 years ago
5 years ago
5 years ago
5 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
5 years ago
5 years ago
11 years ago
5 years ago
5 years ago
5 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 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
11 years ago
11 years ago
  1. /*
  2. * KiRouter - a push-and-(sometimes-)shove PCB router
  3. *
  4. * Copyright (C) 2013-2019 CERN
  5. * Copyright (C) 2016-2021 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. #include <vector>
  22. #include <cassert>
  23. #include <utility>
  24. #include <math/vector2d.h>
  25. #include <geometry/seg.h>
  26. #include <geometry/shape_line_chain.h>
  27. #include "pns_arc.h"
  28. #include "pns_item.h"
  29. #include "pns_line.h"
  30. #include "pns_node.h"
  31. #include "pns_via.h"
  32. #include "pns_solid.h"
  33. #include "pns_joint.h"
  34. #include "pns_index.h"
  35. #include "pns_debug_decorator.h"
  36. #include "pns_router.h"
  37. namespace PNS {
  38. #ifdef DEBUG
  39. static std::unordered_set<NODE*> allocNodes;
  40. #endif
  41. NODE::NODE()
  42. {
  43. m_depth = 0;
  44. m_root = this;
  45. m_parent = NULL;
  46. m_maxClearance = 800000; // fixme: depends on how thick traces are.
  47. m_ruleResolver = NULL;
  48. m_index = new INDEX;
  49. #ifdef DEBUG
  50. allocNodes.insert( this );
  51. #endif
  52. }
  53. NODE::~NODE()
  54. {
  55. if( !m_children.empty() )
  56. {
  57. wxLogTrace( "PNS", "attempting to free a node that has kids." );
  58. assert( false );
  59. }
  60. #ifdef DEBUG
  61. if( allocNodes.find( this ) == allocNodes.end() )
  62. {
  63. wxLogTrace( "PNS", "attempting to free an already-free'd node." );
  64. assert( false );
  65. }
  66. allocNodes.erase( this );
  67. #endif
  68. m_joints.clear();
  69. for( ITEM* item : *m_index )
  70. {
  71. if( item->BelongsTo( this ) )
  72. delete item;
  73. }
  74. releaseGarbage();
  75. unlinkParent();
  76. delete m_index;
  77. }
  78. int NODE::GetClearance( const ITEM* aA, const ITEM* aB ) const
  79. {
  80. if( !m_ruleResolver )
  81. return 100000;
  82. return m_ruleResolver->Clearance( aA, aB );
  83. }
  84. int NODE::GetHoleClearance( const ITEM* aA, const ITEM* aB ) const
  85. {
  86. if( !m_ruleResolver )
  87. return 0;
  88. return m_ruleResolver->HoleClearance( aA, aB );
  89. }
  90. int NODE::GetHoleToHoleClearance( const ITEM* aA, const ITEM* aB ) const
  91. {
  92. if( !m_ruleResolver )
  93. return 0;
  94. return m_ruleResolver->HoleToHoleClearance( aA, aB );
  95. }
  96. NODE* NODE::Branch()
  97. {
  98. NODE* child = new NODE;
  99. m_children.insert( child );
  100. child->m_depth = m_depth + 1;
  101. child->m_parent = this;
  102. child->m_ruleResolver = m_ruleResolver;
  103. child->m_root = isRoot() ? this : m_root;
  104. child->m_maxClearance = m_maxClearance;
  105. // Immmediate offspring of the root branch needs not copy anything. For the rest, deep-copy
  106. // joints, overridden item maps and pointers to stored items.
  107. if( !isRoot() )
  108. {
  109. JOINT_MAP::iterator j;
  110. for( ITEM* item : *m_index )
  111. child->m_index->Add( item );
  112. child->m_joints = m_joints;
  113. child->m_override = m_override;
  114. }
  115. #if 0
  116. wxLogTrace( "PNS", "%d items, %d joints, %d overrides",
  117. child->m_index->Size(),
  118. (int) child->m_joints.size(),
  119. (int) child->m_override.size() );
  120. #endif
  121. return child;
  122. }
  123. void NODE::unlinkParent()
  124. {
  125. if( isRoot() )
  126. return;
  127. m_parent->m_children.erase( this );
  128. }
  129. OBSTACLE_VISITOR::OBSTACLE_VISITOR( const ITEM* aItem ) :
  130. m_item( aItem ),
  131. m_node( NULL ),
  132. m_override( NULL ),
  133. m_extraClearance( 0 )
  134. {
  135. }
  136. void OBSTACLE_VISITOR::SetWorld( const NODE* aNode, const NODE* aOverride )
  137. {
  138. m_node = aNode;
  139. m_override = aOverride;
  140. }
  141. bool OBSTACLE_VISITOR::visit( ITEM* aCandidate )
  142. {
  143. // check if there is a more recent branch with a newer (possibily modified) version of this
  144. // item.
  145. if( m_override && m_override->Overrides( aCandidate ) )
  146. return true;
  147. return false;
  148. }
  149. // function object that visits potential obstacles and performs the actual collision refining
  150. struct NODE::DEFAULT_OBSTACLE_VISITOR : public OBSTACLE_VISITOR
  151. {
  152. OBSTACLES& m_tab;
  153. int m_kindMask; ///> (solids, vias, segments, etc...)
  154. int m_limitCount;
  155. int m_matchCount;
  156. int m_extraClearance;
  157. bool m_differentNetsOnly;
  158. DEFAULT_OBSTACLE_VISITOR( NODE::OBSTACLES& aTab, const ITEM* aItem, int aKindMask,
  159. bool aDifferentNetsOnly ) :
  160. OBSTACLE_VISITOR( aItem ),
  161. m_tab( aTab ),
  162. m_kindMask( aKindMask ),
  163. m_limitCount( -1 ),
  164. m_matchCount( 0 ),
  165. m_extraClearance( 0 ),
  166. m_differentNetsOnly( aDifferentNetsOnly )
  167. {
  168. if( aItem && aItem->Kind() == ITEM::LINE_T )
  169. {
  170. m_extraClearance += static_cast<const LINE*>( aItem )->Width() / 2;
  171. }
  172. }
  173. virtual ~DEFAULT_OBSTACLE_VISITOR()
  174. {
  175. }
  176. void SetCountLimit( int aLimit )
  177. {
  178. m_limitCount = aLimit;
  179. }
  180. bool operator()( ITEM* aCandidate ) override
  181. {
  182. if( !aCandidate->OfKind( m_kindMask ) )
  183. return true;
  184. if( visit( aCandidate ) )
  185. return true;
  186. if( !aCandidate->Collide( m_item, m_node, m_differentNetsOnly ) )
  187. return true;
  188. OBSTACLE obs;
  189. obs.m_item = aCandidate;
  190. obs.m_head = m_item;
  191. m_tab.push_back( obs );
  192. m_matchCount++;
  193. if( m_limitCount > 0 && m_matchCount >= m_limitCount )
  194. return false;
  195. return true;
  196. };
  197. };
  198. int NODE::QueryColliding( const ITEM* aItem, NODE::OBSTACLES& aObstacles, int aKindMask,
  199. int aLimitCount, bool aDifferentNetsOnly )
  200. {
  201. DEFAULT_OBSTACLE_VISITOR visitor( aObstacles, aItem, aKindMask, aDifferentNetsOnly );
  202. #ifdef DEBUG
  203. assert( allocNodes.find( this ) != allocNodes.end() );
  204. #endif
  205. visitor.SetCountLimit( aLimitCount );
  206. visitor.SetWorld( this, NULL );
  207. // first, look for colliding items in the local index
  208. m_index->Query( aItem, m_maxClearance, visitor );
  209. // if we haven't found enough items, look in the root branch as well.
  210. if( !isRoot() && ( visitor.m_matchCount < aLimitCount || aLimitCount < 0 ) )
  211. {
  212. visitor.SetWorld( m_root, this );
  213. m_root->m_index->Query( aItem, m_maxClearance, visitor );
  214. }
  215. return aObstacles.size();
  216. }
  217. NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine, int aKindMask,
  218. const std::set<ITEM*>* aRestrictedSet )
  219. {
  220. OBSTACLES obstacleList;
  221. obstacleList.reserve( 100 );
  222. for( int i = 0; i < aLine->CLine().SegmentCount(); i++ )
  223. {
  224. const SEGMENT s( *aLine, aLine->CLine().CSegment( i ) );
  225. QueryColliding( &s, obstacleList, aKindMask );
  226. }
  227. if( aLine->EndsWithVia() )
  228. QueryColliding( &aLine->Via(), obstacleList, aKindMask );
  229. if( obstacleList.empty() )
  230. return OPT_OBSTACLE();
  231. OBSTACLE nearest;
  232. nearest.m_item = NULL;
  233. nearest.m_distFirst = INT_MAX;
  234. auto updateNearest =
  235. [&]( VECTOR2I pt, ITEM* obstacle, const SHAPE_LINE_CHAIN& hull, bool isHole )
  236. {
  237. int dist = aLine->CLine().PathLength( pt );
  238. if( dist < nearest.m_distFirst )
  239. {
  240. nearest.m_distFirst = dist;
  241. nearest.m_ipFirst = pt;
  242. nearest.m_item = obstacle;
  243. nearest.m_hull = hull;
  244. obstacle->Mark( isHole ? obstacle->Marker() | MK_HOLE
  245. : obstacle->Marker() & ~MK_HOLE );
  246. }
  247. };
  248. SHAPE_LINE_CHAIN obstacleHull;
  249. DEBUG_DECORATOR* debugDecorator = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
  250. std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersectingPts;
  251. int layer = aLine->Layer();
  252. for( const OBSTACLE& obstacle : obstacleList )
  253. {
  254. if( aRestrictedSet && aRestrictedSet->find( obstacle.m_item ) == aRestrictedSet->end() )
  255. continue;
  256. int clearance = GetClearance( obstacle.m_item, aLine ) + aLine->Width() / 2;
  257. obstacleHull = obstacle.m_item->Hull( clearance + PNS_HULL_MARGIN, 0, layer );
  258. debugDecorator->AddLine( obstacleHull, 2 );
  259. intersectingPts.clear();
  260. obstacleHull.Intersect( aLine->CLine(), intersectingPts );
  261. for( const SHAPE_LINE_CHAIN::INTERSECTION& ip : intersectingPts )
  262. updateNearest( ip.p, obstacle.m_item, obstacleHull, false );
  263. if( aLine->EndsWithVia() )
  264. {
  265. const VIA& via = aLine->Via();
  266. // Don't use via.Drill(); it doesn't include the plating thickness
  267. int viaHoleRadius = static_cast<const SHAPE_CIRCLE*>( via.Hole() )->GetRadius();
  268. int viaClearance = GetClearance( obstacle.m_item, &via ) + via.Diameter() / 2;
  269. int holeClearance = GetHoleClearance( obstacle.m_item, &via ) + viaHoleRadius;
  270. if( holeClearance > viaClearance )
  271. viaClearance = holeClearance;
  272. obstacleHull = obstacle.m_item->Hull( viaClearance + PNS_HULL_MARGIN, 0, layer );
  273. debugDecorator->AddLine( obstacleHull, 3 );
  274. intersectingPts.clear();
  275. obstacleHull.Intersect( aLine->CLine(), intersectingPts );
  276. for( const SHAPE_LINE_CHAIN::INTERSECTION& ip : intersectingPts )
  277. updateNearest( ip.p, obstacle.m_item, obstacleHull, false );
  278. }
  279. if( obstacle.m_item->Hole() )
  280. {
  281. clearance = GetHoleClearance( obstacle.m_item, aLine ) + aLine->Width() / 2;
  282. obstacleHull = obstacle.m_item->HoleHull( clearance + PNS_HULL_MARGIN, 0, layer );
  283. debugDecorator->AddLine( obstacleHull, 4 );
  284. intersectingPts.clear();
  285. obstacleHull.Intersect( aLine->CLine(), intersectingPts );
  286. for( const SHAPE_LINE_CHAIN::INTERSECTION& ip : intersectingPts )
  287. updateNearest( ip.p, obstacle.m_item, obstacleHull, true );
  288. if( aLine->EndsWithVia() )
  289. {
  290. const VIA& via = aLine->Via();
  291. // Don't use via.Drill(); it doesn't include the plating thickness
  292. int viaHoleRadius = static_cast<const SHAPE_CIRCLE*>( via.Hole() )->GetRadius();
  293. int viaClearance = GetClearance( obstacle.m_item, &via ) + via.Diameter() / 2;
  294. int holeClearance = GetHoleClearance( obstacle.m_item, &via ) + viaHoleRadius;
  295. int holeToHole = GetHoleToHoleClearance( obstacle.m_item, &via ) + viaHoleRadius;
  296. if( holeClearance > viaClearance )
  297. viaClearance = holeClearance;
  298. if( holeToHole > viaClearance )
  299. viaClearance = holeToHole;
  300. obstacleHull = obstacle.m_item->Hull( viaClearance + PNS_HULL_MARGIN, 0, layer );
  301. debugDecorator->AddLine( obstacleHull, 5 );
  302. intersectingPts.clear();
  303. obstacleHull.Intersect( aLine->CLine(), intersectingPts );
  304. for( const SHAPE_LINE_CHAIN::INTERSECTION& ip : intersectingPts )
  305. updateNearest( ip.p, obstacle.m_item, obstacleHull, true );
  306. }
  307. }
  308. }
  309. if( nearest.m_distFirst == INT_MAX )
  310. nearest.m_item = obstacleList[0].m_item;
  311. return nearest;
  312. }
  313. NODE::OPT_OBSTACLE NODE::CheckColliding( const ITEM_SET& aSet, int aKindMask )
  314. {
  315. for( const ITEM* item : aSet.CItems() )
  316. {
  317. OPT_OBSTACLE obs = CheckColliding( item, aKindMask );
  318. if( obs )
  319. return obs;
  320. }
  321. return OPT_OBSTACLE();
  322. }
  323. NODE::OPT_OBSTACLE NODE::CheckColliding( const ITEM* aItemA, int aKindMask )
  324. {
  325. OBSTACLES obs;
  326. obs.reserve( 100 );
  327. if( aItemA->Kind() == ITEM::LINE_T )
  328. {
  329. int n = 0;
  330. const LINE* line = static_cast<const LINE*>( aItemA );
  331. const SHAPE_LINE_CHAIN& l = line->CLine();
  332. for( int i = 0; i < l.SegmentCount(); i++ )
  333. {
  334. const SEGMENT s( *line, l.CSegment( i ) );
  335. n += QueryColliding( &s, obs, aKindMask, 1 );
  336. if( n )
  337. return OPT_OBSTACLE( obs[0] );
  338. }
  339. if( line->EndsWithVia() )
  340. {
  341. n += QueryColliding( &line->Via(), obs, aKindMask, 1 );
  342. if( n )
  343. return OPT_OBSTACLE( obs[0] );
  344. }
  345. }
  346. else if( QueryColliding( aItemA, obs, aKindMask, 1 ) > 0 )
  347. {
  348. return OPT_OBSTACLE( obs[0] );
  349. }
  350. return OPT_OBSTACLE();
  351. }
  352. struct HIT_VISITOR : public OBSTACLE_VISITOR
  353. {
  354. ITEM_SET& m_items;
  355. const VECTOR2I& m_point;
  356. HIT_VISITOR( ITEM_SET& aTab, const VECTOR2I& aPoint ) :
  357. OBSTACLE_VISITOR( NULL ),
  358. m_items( aTab ),
  359. m_point( aPoint )
  360. {}
  361. virtual ~HIT_VISITOR()
  362. {
  363. }
  364. bool operator()( ITEM* aItem ) override
  365. {
  366. SHAPE_CIRCLE cp( m_point, 0 );
  367. int cl = 0;
  368. if( aItem->Shape()->Collide( &cp, cl ) )
  369. m_items.Add( aItem );
  370. return true;
  371. }
  372. };
  373. const ITEM_SET NODE::HitTest( const VECTOR2I& aPoint ) const
  374. {
  375. ITEM_SET items;
  376. // fixme: we treat a point as an infinitely small circle - this is inefficient.
  377. SHAPE_CIRCLE s( aPoint, 0 );
  378. HIT_VISITOR visitor( items, aPoint );
  379. visitor.SetWorld( this, NULL );
  380. m_index->Query( &s, m_maxClearance, visitor );
  381. if( !isRoot() ) // fixme: could be made cleaner
  382. {
  383. ITEM_SET items_root;
  384. visitor.SetWorld( m_root, NULL );
  385. HIT_VISITOR visitor_root( items_root, aPoint );
  386. m_root->m_index->Query( &s, m_maxClearance, visitor_root );
  387. for( ITEM* item : items_root.Items() )
  388. {
  389. if( !Overrides( item ) )
  390. items.Add( item );
  391. }
  392. }
  393. return items;
  394. }
  395. void NODE::addSolid( SOLID* aSolid )
  396. {
  397. if( aSolid->IsRoutable() )
  398. linkJoint( aSolid->Pos(), aSolid->Layers(), aSolid->Net(), aSolid );
  399. m_index->Add( aSolid );
  400. }
  401. void NODE::Add( std::unique_ptr< SOLID > aSolid )
  402. {
  403. aSolid->SetOwner( this );
  404. addSolid( aSolid.release() );
  405. }
  406. void NODE::addVia( VIA* aVia )
  407. {
  408. linkJoint( aVia->Pos(), aVia->Layers(), aVia->Net(), aVia );
  409. m_index->Add( aVia );
  410. }
  411. void NODE::Add( std::unique_ptr< VIA > aVia )
  412. {
  413. aVia->SetOwner( this );
  414. addVia( aVia.release() );
  415. }
  416. void NODE::Add( LINE& aLine, bool aAllowRedundant )
  417. {
  418. assert( !aLine.IsLinked() );
  419. SHAPE_LINE_CHAIN& l = aLine.Line();
  420. for( size_t i = 0; i < l.ArcCount(); i++ )
  421. {
  422. auto s = l.Arc( i );
  423. ARC* rarc;
  424. if( !aAllowRedundant && ( rarc = findRedundantArc( s.GetP0(), s.GetP1(), aLine.Layers(),
  425. aLine.Net() ) ) )
  426. {
  427. aLine.Link( rarc );
  428. }
  429. else
  430. {
  431. auto newarc = std::make_unique< ARC >( aLine, s );
  432. aLine.Link( newarc.get() );
  433. Add( std::move( newarc ), true );
  434. }
  435. }
  436. for( int i = 0; i < l.SegmentCount(); i++ )
  437. {
  438. if( l.isArc( i ) )
  439. continue;
  440. SEG s = l.CSegment( i );
  441. if( s.A != s.B )
  442. {
  443. SEGMENT* rseg;
  444. if( !aAllowRedundant && ( rseg = findRedundantSegment( s.A, s.B, aLine.Layers(),
  445. aLine.Net() ) ) )
  446. {
  447. // another line could be referencing this segment too :(
  448. aLine.Link( rseg );
  449. }
  450. else
  451. {
  452. std::unique_ptr<SEGMENT> newseg = std::make_unique<SEGMENT>( aLine, s );
  453. aLine.Link( newseg.get() );
  454. Add( std::move( newseg ), true );
  455. }
  456. }
  457. }
  458. }
  459. void NODE::addSegment( SEGMENT* aSeg )
  460. {
  461. linkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg );
  462. linkJoint( aSeg->Seg().B, aSeg->Layers(), aSeg->Net(), aSeg );
  463. m_index->Add( aSeg );
  464. }
  465. bool NODE::Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant )
  466. {
  467. if( aSegment->Seg().A == aSegment->Seg().B )
  468. {
  469. wxLogTrace( "PNS", "attempting to add a segment with same end coordinates, ignoring." );
  470. return false;
  471. }
  472. if( !aAllowRedundant && findRedundantSegment( aSegment.get() ) )
  473. return false;
  474. aSegment->SetOwner( this );
  475. addSegment( aSegment.release() );
  476. return true;
  477. }
  478. void NODE::addArc( ARC* aArc )
  479. {
  480. linkJoint( aArc->Anchor( 0 ), aArc->Layers(), aArc->Net(), aArc );
  481. linkJoint( aArc->Anchor( 1 ), aArc->Layers(), aArc->Net(), aArc );
  482. m_index->Add( aArc );
  483. }
  484. void NODE::Add( std::unique_ptr< ARC > aArc )
  485. {
  486. aArc->SetOwner( this );
  487. addArc( aArc.release() );
  488. }
  489. void NODE::Add( std::unique_ptr< ITEM > aItem, bool aAllowRedundant )
  490. {
  491. switch( aItem->Kind() )
  492. {
  493. case ITEM::SOLID_T: Add( ItemCast<SOLID>( std::move( aItem ) ) ); break;
  494. case ITEM::SEGMENT_T: Add( ItemCast<SEGMENT>( std::move( aItem ) ), aAllowRedundant ); break;
  495. case ITEM::VIA_T: Add( ItemCast<VIA>( std::move( aItem ) ) ); break;
  496. case ITEM::ARC_T:
  497. //todo(snh): Add redundant search
  498. Add( ItemCast<ARC>( std::move( aItem ) ) );
  499. break;
  500. case ITEM::LINE_T:
  501. default:
  502. assert( false );
  503. }
  504. }
  505. void NODE::doRemove( ITEM* aItem )
  506. {
  507. // case 1: removing an item that is stored in the root node from any branch:
  508. // mark it as overridden, but do not remove
  509. if( aItem->BelongsTo( m_root ) && !isRoot() )
  510. m_override.insert( aItem );
  511. // case 2: the item belongs to this branch or a parent, non-root branch,
  512. // or the root itself and we are the root: remove from the index
  513. else if( !aItem->BelongsTo( m_root ) || isRoot() )
  514. m_index->Remove( aItem );
  515. // the item belongs to this particular branch: un-reference it
  516. if( aItem->BelongsTo( this ) )
  517. {
  518. aItem->SetOwner( NULL );
  519. m_root->m_garbageItems.insert( aItem );
  520. }
  521. }
  522. void NODE::removeSegmentIndex( SEGMENT* aSeg )
  523. {
  524. unlinkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg );
  525. unlinkJoint( aSeg->Seg().B, aSeg->Layers(), aSeg->Net(), aSeg );
  526. }
  527. void NODE::removeArcIndex( ARC* aArc )
  528. {
  529. unlinkJoint( aArc->Anchor( 0 ), aArc->Layers(), aArc->Net(), aArc );
  530. unlinkJoint( aArc->Anchor( 1 ), aArc->Layers(), aArc->Net(), aArc );
  531. }
  532. void NODE::rebuildJoint( JOINT* aJoint, ITEM* aItem )
  533. {
  534. // We have to split a single joint (associated with a via or a pad, binding together multiple
  535. // layers) into multiple independent joints. As I'm a lazy bastard, I simply delete the
  536. // via/solid and all its links and re-insert them.
  537. JOINT::LINKED_ITEMS links( aJoint->LinkList() );
  538. JOINT::HASH_TAG tag;
  539. int net = aItem->Net();
  540. tag.net = net;
  541. tag.pos = aJoint->Pos();
  542. bool split;
  543. do
  544. {
  545. split = false;
  546. auto range = m_joints.equal_range( tag );
  547. if( range.first == m_joints.end() )
  548. break;
  549. // find and remove all joints containing the via to be removed
  550. for( auto f = range.first; f != range.second; ++f )
  551. {
  552. if( aItem->LayersOverlap( &f->second ) )
  553. {
  554. m_joints.erase( f );
  555. split = true;
  556. break;
  557. }
  558. }
  559. } while( split );
  560. // and re-link them, using the former via's link list
  561. for(ITEM* link : links)
  562. {
  563. if( link != aItem )
  564. linkJoint( tag.pos, link->Layers(), net, link );
  565. }
  566. }
  567. void NODE::removeViaIndex( VIA* aVia )
  568. {
  569. JOINT* jt = FindJoint( aVia->Pos(), aVia->Layers().Start(), aVia->Net() );
  570. assert( jt );
  571. rebuildJoint( jt, aVia );
  572. }
  573. void NODE::removeSolidIndex( SOLID* aSolid )
  574. {
  575. if( !aSolid->IsRoutable() )
  576. return;
  577. // fixme: redundant code
  578. JOINT* jt = FindJoint( aSolid->Pos(), aSolid->Layers().Start(), aSolid->Net() );
  579. assert( jt );
  580. rebuildJoint( jt, aSolid );
  581. }
  582. void NODE::Replace( ITEM* aOldItem, std::unique_ptr< ITEM > aNewItem )
  583. {
  584. Remove( aOldItem );
  585. Add( std::move( aNewItem ) );
  586. }
  587. void NODE::Replace( LINE& aOldLine, LINE& aNewLine )
  588. {
  589. Remove( aOldLine );
  590. Add( aNewLine );
  591. }
  592. void NODE::Remove( SOLID* aSolid )
  593. {
  594. removeSolidIndex( aSolid );
  595. doRemove( aSolid );
  596. }
  597. void NODE::Remove( VIA* aVia )
  598. {
  599. removeViaIndex( aVia );
  600. doRemove( aVia );
  601. }
  602. void NODE::Remove( SEGMENT* aSegment )
  603. {
  604. removeSegmentIndex( aSegment );
  605. doRemove( aSegment );
  606. }
  607. void NODE::Remove( ARC* aArc )
  608. {
  609. removeArcIndex( aArc );
  610. doRemove( aArc );
  611. }
  612. void NODE::Remove( ITEM* aItem )
  613. {
  614. switch( aItem->Kind() )
  615. {
  616. case ITEM::ARC_T:
  617. Remove( static_cast<ARC*>( aItem ) );
  618. break;
  619. case ITEM::SOLID_T:
  620. Remove( static_cast<SOLID*>( aItem ) );
  621. break;
  622. case ITEM::SEGMENT_T:
  623. Remove( static_cast<SEGMENT*>( aItem ) );
  624. break;
  625. case ITEM::LINE_T:
  626. {
  627. LINE* l = static_cast<LINE*>( aItem );
  628. for ( LINKED_ITEM* s : l->Links() )
  629. Remove( s );
  630. break;
  631. }
  632. case ITEM::VIA_T:
  633. Remove( static_cast<VIA*>( aItem ) );
  634. break;
  635. default:
  636. break;
  637. }
  638. }
  639. void NODE::Remove( LINE& aLine )
  640. {
  641. // LINE does not have a seperate remover, as LINEs are never truly a member of the tree
  642. std::vector<LINKED_ITEM*>& segRefs = aLine.Links();
  643. for( LINKED_ITEM* li : segRefs )
  644. {
  645. if( li->OfKind( ITEM::SEGMENT_T ) )
  646. Remove( static_cast<SEGMENT*>( li ) );
  647. else if( li->OfKind( ITEM::ARC_T ) )
  648. Remove( static_cast<ARC*>( li ) );
  649. }
  650. aLine.SetOwner( nullptr );
  651. aLine.ClearLinks();
  652. }
  653. void NODE::followLine( LINKED_ITEM* aCurrent, int aScanDirection, int& aPos, int aLimit,
  654. VECTOR2I* aCorners, LINKED_ITEM** aSegments, bool& aGuardHit,
  655. bool aStopAtLockedJoints )
  656. {
  657. bool prevReversed = false;
  658. const VECTOR2I guard = aCurrent->Anchor( aScanDirection );
  659. for( int count = 0 ; ; ++count )
  660. {
  661. const VECTOR2I p = aCurrent->Anchor( aScanDirection ^ prevReversed );
  662. const JOINT* jt = FindJoint( p, aCurrent );
  663. assert( jt );
  664. aCorners[aPos] = jt->Pos();
  665. aSegments[aPos] = aCurrent;
  666. aPos += ( aScanDirection ? 1 : -1 );
  667. if( count && guard == p)
  668. {
  669. aSegments[aPos] = NULL;
  670. aGuardHit = true;
  671. break;
  672. }
  673. bool locked = aStopAtLockedJoints ? jt->IsLocked() : false;
  674. if( locked || !jt->IsLineCorner() || aPos < 0 || aPos == aLimit )
  675. break;
  676. aCurrent = jt->NextSegment( aCurrent );
  677. prevReversed = ( jt->Pos() == aCurrent->Anchor( aScanDirection ) );
  678. }
  679. }
  680. const LINE NODE::AssembleLine( LINKED_ITEM* aSeg, int* aOriginSegmentIndex,
  681. bool aStopAtLockedJoints )
  682. {
  683. const int MaxVerts = 1024 * 16;
  684. VECTOR2I corners[MaxVerts + 1];
  685. LINKED_ITEM* segs[MaxVerts + 1];
  686. LINE pl;
  687. bool guardHit = false;
  688. int i_start = MaxVerts / 2, i_end = i_start + 1;
  689. pl.SetWidth( aSeg->Width() );
  690. pl.SetLayers( aSeg->Layers() );
  691. pl.SetNet( aSeg->Net() );
  692. pl.SetOwner( this );
  693. followLine( aSeg, false, i_start, MaxVerts, corners, segs, guardHit, aStopAtLockedJoints );
  694. if( !guardHit )
  695. followLine( aSeg, true, i_end, MaxVerts, corners, segs, guardHit, aStopAtLockedJoints );
  696. int n = 0;
  697. LINKED_ITEM* prev_seg = NULL;
  698. bool originSet = false;
  699. for( int i = i_start + 1; i < i_end; i++ )
  700. {
  701. const VECTOR2I& p = corners[i];
  702. LINKED_ITEM* li = segs[i];
  703. if( !li || li->Kind() != ITEM::ARC_T )
  704. pl.Line().Append( p );
  705. if( li && prev_seg != li )
  706. {
  707. if( li->Kind() == ITEM::ARC_T )
  708. {
  709. const ARC* arc = static_cast<const ARC*>( li );
  710. const SHAPE_ARC* sa = static_cast<const SHAPE_ARC*>( arc->Shape() );
  711. pl.Line().Append( *sa );
  712. }
  713. pl.Link( li );
  714. // latter condition to avoid loops
  715. if( li == aSeg && aOriginSegmentIndex && !originSet )
  716. {
  717. *aOriginSegmentIndex = n;
  718. originSet = true;
  719. }
  720. n++;
  721. }
  722. prev_seg = li;
  723. }
  724. // Remove duplicate verts, but do NOT remove colinear segments here!
  725. pl.Line().Simplify( false );
  726. assert( pl.SegmentCount() != 0 );
  727. return pl;
  728. }
  729. void NODE::FindLineEnds( const LINE& aLine, JOINT& aA, JOINT& aB )
  730. {
  731. aA = *FindJoint( aLine.CPoint( 0 ), &aLine );
  732. aB = *FindJoint( aLine.CPoint( -1 ), &aLine );
  733. }
  734. int NODE::FindLinesBetweenJoints( const JOINT& aA, const JOINT& aB, std::vector<LINE>& aLines )
  735. {
  736. for( ITEM* item : aA.LinkList() )
  737. {
  738. if( item->Kind() == ITEM::SEGMENT_T || item->Kind() == ITEM::ARC_T )
  739. {
  740. LINKED_ITEM* li = static_cast<LINKED_ITEM*>( item );
  741. LINE line = AssembleLine( li );
  742. if( !line.Layers().Overlaps( aB.Layers() ) )
  743. continue;
  744. JOINT j_start, j_end;
  745. FindLineEnds( line, j_start, j_end );
  746. int id_start = line.CLine().Find( aA.Pos() );
  747. int id_end = line.CLine().Find( aB.Pos() );
  748. if( id_end < id_start )
  749. std::swap( id_end, id_start );
  750. if( id_start >= 0 && id_end >= 0 )
  751. {
  752. line.ClipVertexRange( id_start, id_end );
  753. aLines.push_back( line );
  754. }
  755. }
  756. }
  757. return 0;
  758. }
  759. JOINT* NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet )
  760. {
  761. JOINT::HASH_TAG tag;
  762. tag.net = aNet;
  763. tag.pos = aPos;
  764. JOINT_MAP::iterator f = m_joints.find( tag ), end = m_joints.end();
  765. if( f == end && !isRoot() )
  766. {
  767. end = m_root->m_joints.end();
  768. f = m_root->m_joints.find( tag ); // m_root->FindJoint(aPos, aLayer, aNet);
  769. }
  770. if( f == end )
  771. return NULL;
  772. while( f != end )
  773. {
  774. if( f->second.Layers().Overlaps( aLayer ) )
  775. return &f->second;
  776. ++f;
  777. }
  778. return NULL;
  779. }
  780. void NODE::LockJoint( const VECTOR2I& aPos, const ITEM* aItem, bool aLock )
  781. {
  782. JOINT& jt = touchJoint( aPos, aItem->Layers(), aItem->Net() );
  783. jt.Lock( aLock );
  784. }
  785. JOINT& NODE::touchJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int aNet )
  786. {
  787. JOINT::HASH_TAG tag;
  788. tag.pos = aPos;
  789. tag.net = aNet;
  790. // try to find the joint in this node.
  791. JOINT_MAP::iterator f = m_joints.find( tag );
  792. std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range;
  793. // not found and we are not root? find in the root and copy results here.
  794. if( f == m_joints.end() && !isRoot() )
  795. {
  796. range = m_root->m_joints.equal_range( tag );
  797. for( f = range.first; f != range.second; ++f )
  798. m_joints.insert( *f );
  799. }
  800. // now insert and combine overlapping joints
  801. JOINT jt( aPos, aLayers, aNet );
  802. bool merged;
  803. do
  804. {
  805. merged = false;
  806. range = m_joints.equal_range( tag );
  807. if( range.first == m_joints.end() )
  808. break;
  809. for( f = range.first; f != range.second; ++f )
  810. {
  811. if( aLayers.Overlaps( f->second.Layers() ) )
  812. {
  813. jt.Merge( f->second );
  814. m_joints.erase( f );
  815. merged = true;
  816. break;
  817. }
  818. }
  819. }
  820. while( merged );
  821. return m_joints.insert( TagJointPair( tag, jt ) )->second;
  822. }
  823. void JOINT::Dump() const
  824. {
  825. wxLogTrace( "PNS", "joint layers %d-%d, net %d, pos %s, links: %d",
  826. m_layers.Start(),
  827. m_layers.End(),
  828. m_tag.net,
  829. m_tag.pos.Format().c_str(),
  830. LinkCount() );
  831. }
  832. void NODE::linkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int aNet, ITEM* aWhere )
  833. {
  834. JOINT& jt = touchJoint( aPos, aLayers, aNet );
  835. jt.Link( aWhere );
  836. }
  837. void NODE::unlinkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int aNet, ITEM* aWhere )
  838. {
  839. // fixme: remove dangling joints
  840. JOINT& jt = touchJoint( aPos, aLayers, aNet );
  841. jt.Unlink( aWhere );
  842. }
  843. void NODE::Dump( bool aLong )
  844. {
  845. #if 0
  846. std::unordered_set<SEGMENT*> all_segs;
  847. SHAPE_INDEX_LIST<ITEM*>::iterator i;
  848. for( i = m_items.begin(); i != m_items.end(); i++ )
  849. {
  850. if( (*i)->GetKind() == ITEM::SEGMENT_T )
  851. all_segs.insert( static_cast<SEGMENT*>( *i ) );
  852. }
  853. if( !isRoot() )
  854. {
  855. for( i = m_root->m_items.begin(); i != m_root->m_items.end(); i++ )
  856. {
  857. if( (*i)->GetKind() == ITEM::SEGMENT_T && !overrides( *i ) )
  858. all_segs.insert( static_cast<SEGMENT*>(*i) );
  859. }
  860. }
  861. JOINT_MAP::iterator j;
  862. if( aLong )
  863. for( j = m_joints.begin(); j != m_joints.end(); ++j )
  864. {
  865. wxLogTrace( "PNS", "joint : %s, links : %d\n",
  866. j->second.GetPos().Format().c_str(), j->second.LinkCount() );
  867. JOINT::LINKED_ITEMS::const_iterator k;
  868. for( k = j->second.GetLinkList().begin(); k != j->second.GetLinkList().end(); ++k )
  869. {
  870. const ITEM* m_item = *k;
  871. switch( m_item->GetKind() )
  872. {
  873. case ITEM::SEGMENT_T:
  874. {
  875. const SEGMENT* seg = static_cast<const SEGMENT*>( m_item );
  876. wxLogTrace( "PNS", " -> seg %s %s\n", seg->GetSeg().A.Format().c_str(),
  877. seg->GetSeg().B.Format().c_str() );
  878. break;
  879. }
  880. default:
  881. break;
  882. }
  883. }
  884. }
  885. int lines_count = 0;
  886. while( !all_segs.empty() )
  887. {
  888. SEGMENT* s = *all_segs.begin();
  889. LINE* l = AssembleLine( s );
  890. LINE::LinkedSegments* seg_refs = l->GetLinkedSegments();
  891. if( aLong )
  892. wxLogTrace( "PNS", "Line: %s, net %d ", l->GetLine().Format().c_str(), l->GetNet() );
  893. for( std::vector<SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
  894. {
  895. wxLogTrace( "PNS", "%s ", (*j)->GetSeg().A.Format().c_str() );
  896. if( j + 1 == seg_refs->end() )
  897. wxLogTrace( "PNS", "%s\n", (*j)->GetSeg().B.Format().c_str() );
  898. all_segs.erase( *j );
  899. }
  900. lines_count++;
  901. }
  902. wxLogTrace( "PNS", "Local joints: %d, lines : %d \n", m_joints.size(), lines_count );
  903. #endif
  904. }
  905. void NODE::GetUpdatedItems( ITEM_VECTOR& aRemoved, ITEM_VECTOR& aAdded )
  906. {
  907. if( isRoot() )
  908. return;
  909. if( m_override.size() )
  910. aRemoved.reserve( m_override.size() );
  911. if( m_index->Size() )
  912. aAdded.reserve( m_index->Size() );
  913. for( ITEM* item : m_override )
  914. aRemoved.push_back( item );
  915. for( INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
  916. aAdded.push_back( *i );
  917. }
  918. void NODE::releaseChildren()
  919. {
  920. // copy the kids as the NODE destructor erases the item from the parent node.
  921. std::set<NODE*> kids = m_children;
  922. for( NODE* node : kids )
  923. {
  924. node->releaseChildren();
  925. delete node;
  926. }
  927. }
  928. void NODE::releaseGarbage()
  929. {
  930. if( !isRoot() )
  931. return;
  932. for( ITEM* item : m_garbageItems )
  933. {
  934. if( !item->BelongsTo( this ) )
  935. delete item;
  936. }
  937. m_garbageItems.clear();
  938. }
  939. void NODE::Commit( NODE* aNode )
  940. {
  941. if( aNode->isRoot() )
  942. return;
  943. for( ITEM* item : aNode->m_override )
  944. Remove( item );
  945. for( auto i : *aNode->m_index )
  946. {
  947. i->SetRank( -1 );
  948. i->Unmark();
  949. Add( std::unique_ptr<ITEM>( i ) );
  950. }
  951. releaseChildren();
  952. releaseGarbage();
  953. }
  954. void NODE::KillChildren()
  955. {
  956. releaseChildren();
  957. }
  958. void NODE::AllItemsInNet( int aNet, std::set<ITEM*>& aItems, int aKindMask)
  959. {
  960. INDEX::NET_ITEMS_LIST* l_cur = m_index->GetItemsForNet( aNet );
  961. if( l_cur )
  962. {
  963. for( ITEM*item : *l_cur )
  964. if( item->OfKind( aKindMask ) )
  965. aItems.insert( item );
  966. }
  967. if( !isRoot() )
  968. {
  969. INDEX::NET_ITEMS_LIST* l_root = m_root->m_index->GetItemsForNet( aNet );
  970. if( l_root )
  971. {
  972. for( INDEX::NET_ITEMS_LIST::iterator i = l_root->begin(); i != l_root->end(); ++i )
  973. {
  974. if( !Overrides( *i ) && (*i)->OfKind( aKindMask ) )
  975. aItems.insert( *i );
  976. }
  977. }
  978. }
  979. }
  980. void NODE::ClearRanks( int aMarkerMask )
  981. {
  982. for( INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
  983. {
  984. (*i)->SetRank( -1 );
  985. (*i)->Mark( (*i)->Marker() & (~aMarkerMask) );
  986. }
  987. }
  988. void NODE::RemoveByMarker( int aMarker )
  989. {
  990. std::list<ITEM*> garbage;
  991. for( ITEM* item : *m_index )
  992. {
  993. if( item->Marker() & aMarker )
  994. garbage.push_back( item );
  995. }
  996. for( ITEM* item : garbage )
  997. Remove( item );
  998. }
  999. SEGMENT* NODE::findRedundantSegment( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
  1000. int aNet )
  1001. {
  1002. JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
  1003. if( !jtStart )
  1004. return nullptr;
  1005. for( ITEM* item : jtStart->LinkList() )
  1006. {
  1007. if( item->OfKind( ITEM::SEGMENT_T ) )
  1008. {
  1009. SEGMENT* seg2 = (SEGMENT*)item;
  1010. const VECTOR2I a2( seg2->Seg().A );
  1011. const VECTOR2I b2( seg2->Seg().B );
  1012. if( seg2->Layers().Start() == lr.Start()
  1013. && ( ( A == a2 && B == b2 ) || ( A == b2 && B == a2 ) ) )
  1014. {
  1015. return seg2;
  1016. }
  1017. }
  1018. }
  1019. return nullptr;
  1020. }
  1021. SEGMENT* NODE::findRedundantSegment( SEGMENT* aSeg )
  1022. {
  1023. return findRedundantSegment( aSeg->Seg().A, aSeg->Seg().B, aSeg->Layers(), aSeg->Net() );
  1024. }
  1025. ARC* NODE::findRedundantArc( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
  1026. int aNet )
  1027. {
  1028. JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
  1029. if( !jtStart )
  1030. return nullptr;
  1031. for( ITEM* item : jtStart->LinkList() )
  1032. {
  1033. if( item->OfKind( ITEM::ARC_T ) )
  1034. {
  1035. ARC* seg2 = static_cast<ARC*>( item );
  1036. const VECTOR2I a2( seg2->Anchor( 0 ) );
  1037. const VECTOR2I b2( seg2->Anchor( 1 ) );
  1038. if( seg2->Layers().Start() == lr.Start()
  1039. && ( ( A == a2 && B == b2 ) || ( A == b2 && B == a2 ) ) )
  1040. {
  1041. return seg2;
  1042. }
  1043. }
  1044. }
  1045. return nullptr;
  1046. }
  1047. ARC* NODE::findRedundantArc( ARC* aArc )
  1048. {
  1049. return findRedundantArc( aArc->Anchor( 0 ), aArc->Anchor( 1 ), aArc->Layers(), aArc->Net() );
  1050. }
  1051. int NODE::QueryJoints( const BOX2I& aBox, std::vector<JOINT*>& aJoints, LAYER_RANGE aLayerMask,
  1052. int aKindMask )
  1053. {
  1054. int n = 0;
  1055. aJoints.clear();
  1056. for( JOINT_MAP::value_type& j : m_joints )
  1057. {
  1058. if( !j.second.Layers().Overlaps( aLayerMask ) )
  1059. continue;
  1060. if( aBox.Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
  1061. {
  1062. aJoints.push_back( &j.second );
  1063. n++;
  1064. }
  1065. }
  1066. if( isRoot() )
  1067. return n;
  1068. for( JOINT_MAP::value_type& j : m_root->m_joints )
  1069. {
  1070. if( !Overrides( &j.second ) && j.second.Layers().Overlaps( aLayerMask ) )
  1071. {
  1072. if( aBox.Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
  1073. {
  1074. aJoints.push_back( &j.second );
  1075. n++;
  1076. }
  1077. }
  1078. }
  1079. return n;
  1080. }
  1081. ITEM *NODE::FindItemByParent( const BOARD_ITEM* aParent )
  1082. {
  1083. if( aParent->IsConnected() )
  1084. {
  1085. const BOARD_CONNECTED_ITEM* cItem = static_cast<const BOARD_CONNECTED_ITEM*>( aParent );
  1086. INDEX::NET_ITEMS_LIST* l_cur = m_index->GetItemsForNet( cItem->GetNetCode() );
  1087. if( l_cur )
  1088. {
  1089. for( ITEM* item : *l_cur )
  1090. {
  1091. if( item->Parent() == aParent )
  1092. return item;
  1093. }
  1094. }
  1095. }
  1096. return NULL;
  1097. }
  1098. }