OPT_VECTOR2I PNS_DIFF_PAIR_PLACER::getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem ) { switch( aItem->Kind() ) { case PNS_ITEM::VIA: case PNS_ITEM::SOLID: return aItem->Anchor( 0 ); case PNS_ITEM::SEGMENT: { PNS_SEGMENT* s =static_cast<PNS_SEGMENT*>( aItem ); PNS_JOINT* jA = aNode->FindJoint( s->Seg().A, s ); PNS_JOINT* jB = aNode->FindJoint( s->Seg().B, s ); if( jA->LinkCount() == 1 ) return s->Seg().A; else if( jB->LinkCount() == 1 ) return s->Seg().B; else return OPT_VECTOR2I(); } default: return OPT_VECTOR2I(); break; } }
bool PNS_TOPOLOGY::LeadingRatLine( const PNS_LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine ) { PNS_LINE track( *aTrack ); VECTOR2I end; if( !track.PointCount() ) return false; std::unique_ptr<PNS_NODE> tmpNode( m_world->Branch() ); tmpNode->Add( &track ); PNS_JOINT* jt = tmpNode->FindJoint( track.CPoint( -1 ), &track ); if( !jt ) return false; if( ( !track.EndsWithVia() && jt->LinkCount() >= 2 ) || ( track.EndsWithVia() && jt->LinkCount() >= 3 ) ) // we got something connected { end = jt->Pos(); } else { int anchor; PNS_TOPOLOGY topo( tmpNode.get() ); PNS_ITEM* it = topo.NearestUnconnectedItem( jt, &anchor ); if( !it ) return false; end = it->Anchor( anchor ); } aRatLine.Clear(); aRatLine.Append( track.CPoint( -1 ) ); aRatLine.Append( end ); return true; }
void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP ) { if( aSeg && aSeg->OfKind( PNS_ITEM::SEGMENT ) ) { PNS_JOINT* jt = aNode->FindJoint( aP, aSeg ); if( jt && jt->LinkCount() >= 1 ) return; PNS_SEGMENT* s_old = static_cast<PNS_SEGMENT*>( aSeg ); PNS_SEGMENT* s_new[2]; s_new[0] = s_old->Clone(); s_new[1] = s_old->Clone(); s_new[0]->SetEnds( s_old->Seg().A, aP ); s_new[1]->SetEnds( aP, s_old->Seg().B ); aNode->Remove( s_old ); aNode->Add( s_new[0], true ); aNode->Add( s_new[1], true ); } }