bool PNS_DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP ) { PNS_VIA virtHead = makeVia( aP, -1 ); if( m_placingVia ) virtHead.SetDiameter( viaGap() + 2 * virtHead.Diameter() ); else { virtHead.SetLayer( m_currentLayer ); virtHead.SetDiameter( m_sizes.DiffPairGap() + 2 * m_sizes.TrackWidth() ); } VECTOR2I lead( 0, 0 );// = aP - m_currentStart ; VECTOR2I force; bool solidsOnly = true; if( m_currentMode == RM_MarkObstacles ) { aNewP = aP; return true; } else if( m_currentMode == RM_Walkaround ) { solidsOnly = false; } // fixme: I'm too lazy to do it well. Circular approximaton will do for the moment. if( virtHead.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) ) { aNewP = aP + force; return true; } return false; }
void PNS_ROUTER::CommitRouting( PNS_NODE* aNode ) { PNS_NODE::ITEM_VECTOR removed, added; aNode->GetUpdatedItems( removed, added ); for( unsigned int i = 0; i < removed.size(); i++ ) { BOARD_CONNECTED_ITEM* parent = removed[i]->Parent(); if( parent ) { m_view->Remove( parent ); m_board->Remove( parent ); m_undoBuffer.PushItem( ITEM_PICKER( parent, UR_DELETED ) ); } } for( PNS_ITEM* item : added ) { BOARD_CONNECTED_ITEM* newBI = NULL; switch( item->Kind() ) { case PNS_ITEM::SEGMENT: { PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item ); TRACK* track = new TRACK( m_board ); const SEG& s = seg->Seg(); track->SetStart( wxPoint( s.A.x, s.A.y ) ); track->SetEnd( wxPoint( s.B.x, s.B.y ) ); track->SetWidth( seg->Width() ); track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) ); track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 ); newBI = track; break; } case PNS_ITEM::VIA: { VIA* via_board = new VIA( m_board ); PNS_VIA* via = static_cast<PNS_VIA*>( item ); via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) ); via_board->SetWidth( via->Diameter() ); via_board->SetDrill( via->Drill() ); via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 ); via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair() via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ), ToLAYER_ID( via->Layers().End() ) ); newBI = via_board; break; } default: break; } if( newBI ) { item->SetParent( newBI ); newBI->ClearFlags(); m_view->Add( newBI ); m_board->Add( newBI ); m_undoBuffer.PushItem( ITEM_PICKER( newBI, UR_NEW ) ); newBI->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } m_board->GetRatsnest()->Recalculate(); m_world->Commit( aNode ); }