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.

1340 lines
32 KiB

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