Multiple fixes:

- ratsnest is updated now when undoing in legacy view
- select whole net regression
- local ratsnest in the GAL regression
- pick correct zone net for stitching vias
- mark nets as dirty on net propagation to force ratsnest update

Todo:
- cleanup board algorithm is still broken
This commit is contained in:
Tomasz Włostowski 2017-05-05 00:43:43 +02:00
parent 81dbd930ae
commit a7759efc59
10 changed files with 247 additions and 297 deletions

View File

@ -558,6 +558,12 @@ void PCB_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
galCanvas->GetGAL()->SetGridVisibility( myframe->IsGridVisible() );
galCanvas->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
}
else if ( aId == LAYER_RATSNEST )
{
// don't touch the layers. ratsnest is enabled on per-item basis.
galCanvas->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
galCanvas->GetView()->SetLayerVisible( aId, true );
}
else
galCanvas->GetView()->SetLayerVisible( aId, isEnabled );

View File

@ -38,6 +38,7 @@
#include <dialog_cleaning_options.h>
#include <board_commit.h>
#include <connectivity.h>
#include <connectivity_algo.h>
// Helper class used to clean tracks and vias
class TRACKS_CLEANER
@ -158,18 +159,19 @@ void TRACKS_CLEANER::buildTrackConnectionInfo()
connectivity->Build(m_brd);
// clear flags and variables used in cleanup
for( TRACK* track = m_brd->m_Track; track != NULL; track = track->Next() )
for( auto track : m_brd->Tracks() )
{
track->start = NULL;
track->end = NULL;
track->SetState( START_ON_PAD | END_ON_PAD | BUSY, false );
}
for( TRACK* track = m_brd->m_Track; track != NULL; track = track->Next() )
for( auto track : m_brd->Tracks() )
{
// Mark track if connected to pads
for( auto pad : connectivity->GetConnectedPads( track ) )
{
printf("take pad %p\n", pad);
if( pad->HitTest( track->GetStart() ) )
{
track->start = pad;
@ -313,6 +315,10 @@ bool TRACKS_CLEANER::cleanupVias()
for( VIA* via = GetFirstVia( m_brd->m_Track ); via != NULL;
via = GetFirstVia( via->Next() ) )
{
if( via->GetFlags() & TRACK_LOCKED )
continue;
// Correct via m_End defects (if any), should never happen
if( via->GetStart() != via->GetEnd() )
{
@ -351,66 +357,27 @@ bool TRACKS_CLEANER::cleanupVias()
}
/// Utility for checking if a track/via ends on a zone
const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK* aTrack,
ENDPOINT_T aEndPoint )
{
// Vias are special cased, since they get a layer range, not a single one
PCB_LAYER_ID top_layer, bottom_layer;
const VIA* via = dyn_cast<const VIA*>( aTrack );
if( via )
via->LayerPair( &top_layer, &bottom_layer );
else
{
top_layer = aTrack->GetLayer();
bottom_layer = top_layer;
}
return m_brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ),
top_layer, bottom_layer, aTrack->GetNetCode() );
}
/** Utility: does the endpoint unconnected processed for one endpoint of one track
* Returns true if the track must be deleted, false if not necessarily */
bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPoint )
{
bool flag_erase = false;
auto connectivity = m_brd->GetConnectivity();
VECTOR2I endpoint ;
TRACK* other = aTrack->GetTrack( m_brd->m_Track, NULL, aEndPoint, true, false );
if( !other && !zoneForTrackEndpoint( aTrack, aEndPoint ) )
flag_erase = true; // Start endpoint is neither on pad, zone or other track
else // segment, via or zone connected to this end
{
// Fill connectivity informations
if( aEndPoint == ENDPOINT_START )
aTrack->start = other;
if ( aTrack->Type() == PCB_TRACE_T )
endpoint = aTrack->GetEndPoint( aEndPoint );
else
aTrack->end = other;
endpoint = aTrack->GetStart( );
/* If a via is connected to this end, test if this via has a second item connected.
* If not, remove the current segment (the via would then become
* unconnected and remove on the following pass) */
VIA* via = dyn_cast<VIA*>( other );
auto anchors = connectivity->GetConnectivityAlgo()->ItemEntry( aTrack ).GetItems().front()->Anchors();
if( via )
for ( auto anchor : anchors )
{
// search for another segment following the via
aTrack->SetState( BUSY, true );
other = via->GetTrack( m_brd->m_Track, NULL, aEndPoint, true, false );
// There is a via on the start but it goes nowhere
if( !other && !zoneForTrackEndpoint( via, aEndPoint ) )
flag_erase = true;
aTrack->SetState( BUSY, false );
}
if ( anchor->Pos() == endpoint && anchor->IsDangling() )
return true;
}
return flag_erase;
return false;
}

View File

@ -36,60 +36,8 @@
#include <pcbnew.h>
#include <class_board.h>
/*
* Function SortTracksByNetCode used in RebuildTrackChain()
* to sort track segments by net code.
*/
static bool SortTracksByNetCode( const TRACK* const & ref, const TRACK* const & compare )
{
// For items having the same Net, keep the order in list
if( ref->GetNetCode() == compare->GetNetCode())
return ref->m_Param < compare->m_Param;
return ref->GetNetCode() < compare->GetNetCode();
}
/**
* Helper function RebuildTrackChain
* rebuilds the track segment linked list in order to have a chain
* sorted by increasing netcodes.
* We try to keep order of track segments in list, when possible
* @param pcb = board to rebuild
*/
static void RebuildTrackChain( BOARD* pcb )
{
if( pcb->m_Track == NULL )
return;
int item_count = pcb->m_Track.GetCount();
std::vector<TRACK*> trackList;
trackList.reserve( item_count );
// Put track list in a temporary list to sort tracks by netcode
// We try to keep the initial order of track segments in list, when possible
// so we use m_Param (a member variable used for temporary storage)
// to temporary keep trace of the order of segments
// The sort function uses this variable to sort items that
// have the same net code.
// Without this, during sorting, the initial order is sometimes lost
// by the sort algorithm
for( int ii = 0; ii < item_count; ++ii )
{
pcb->m_Track->m_Param = ii;
trackList.push_back( pcb->m_Track.PopFront() );
}
// the list is empty now
wxASSERT( pcb->m_Track == NULL && pcb->m_Track.GetCount()==0 );
sort( trackList.begin(), trackList.end(), SortTracksByNetCode );
// add them back to the list
for( int i = 0; i < item_count; ++i )
pcb->m_Track.PushBack( trackList[i] );
}
void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
{
Compile_Ratsnest( aDC, false );
}

View File

@ -354,9 +354,18 @@ const std::list<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
const std::list<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetNetItems( int aNetCode,
const KICAD_T aTypes[] ) const
{
std::list<BOARD_CONNECTED_ITEM*> rv;
std::set<BOARD_CONNECTED_ITEM *> items;
std::list<BOARD_CONNECTED_ITEM *> rv;
// fixme: apply aTypes
m_connAlgo->ForEachItem( [&items, aNetCode] ( CN_ITEM* aItem) {
if ( aItem->Net() == aNetCode )
items.insert( aItem->Parent() );
} );
std::copy( items.begin(), items.end(), std::front_inserter( rv ) );
// FIXME!
return rv;
}

View File

@ -211,6 +211,11 @@ public:
void BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aItems );
std::shared_ptr<CN_CONNECTIVITY_ALGO> GetConnectivityAlgo() const
{
return m_connAlgo;
}
private:
void updateRatsnest();

View File

@ -738,6 +738,7 @@ void CN_CONNECTIVITY_ALGO::propagateConnections()
if( item->CanChangeNet() )
{
item->Parent()->SetNetCode( cluster->OriginNet() );
markNetAsDirty( cluster->OriginNet() );
n_changed++;
}
}
@ -902,6 +903,18 @@ void CN_CONNECTIVITY_ALGO::Clear()
}
void CN_CONNECTIVITY_ALGO::ForEachItem( std::function<void(CN_ITEM*)> aFunc )
{
for ( auto item : m_padList )
aFunc( item );
for ( auto item : m_viaList )
aFunc( item );
for ( auto item : m_trackList )
aFunc( item );
for ( auto item : m_zoneList )
aFunc( item );
}
void CN_CONNECTIVITY_ALGO::ForEachAnchor( std::function<void(CN_ANCHOR_PTR)> aFunc )
{
for ( auto anchor : m_padList.Anchors() )
@ -913,3 +926,8 @@ void CN_CONNECTIVITY_ALGO::ForEachAnchor( std::function<void(CN_ANCHOR_PTR)> aF
for ( auto anchor : m_zoneList.Anchors() )
aFunc( anchor );
}
bool CN_ANCHOR::IsDangling() const
{
return m_cluster->Size() <= 1;
}

View File

@ -119,6 +119,8 @@ public:
return m_cluster;
}
bool IsDangling() const;
// Tag used for unconnected items.
static const int TAG_UNCONNECTED = -1;
@ -948,6 +950,7 @@ public:
CN_PAD_LIST& PadList() { return m_padList; }
void ForEachAnchor( std::function<void(CN_ANCHOR_PTR)> aFunc );
void ForEachItem( std::function<void(CN_ITEM*)> aFunc );
};
bool operator<( const CN_ANCHOR_PTR a, const CN_ANCHOR_PTR b );

View File

@ -214,6 +214,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
{
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
DRAWSEGMENT* line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
boost::optional<VECTOR2D> startingPoint;
BOARD_COMMIT commit( m_frame );
@ -311,6 +312,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
// Add a VIEW_GROUP that serves as a preview for the new item
SELECTION preview;
m_view->Add( &preview );
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -349,7 +351,6 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
if( evt->IsActivate() ) // now finish unconditionally
break;
}
else if( text && evt->Category() == TC_COMMAND )
{
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) )
@ -366,12 +367,10 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
m_view->Update( &preview );
}
}
else if( evt->IsClick( BUT_RIGHT ) )
{
m_menu.ShowContextMenu();
}
else if( evt->IsClick( BUT_LEFT ) )
{
if( !text )
@ -389,7 +388,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
DialogEditModuleText textDialog( m_frame, textMod, NULL );
bool placing;
RunMainStack( [&]() {
RunMainStack([&]() {
placing = textDialog.ShowModal() && ( textMod->GetText().Length() > 0 );
} );
@ -415,7 +414,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
textPcb->SetThickness( dsnSettings.m_PcbTextWidth );
textPcb->SetTextPos( wxPoint( cursorPos.x, cursorPos.y ) );
RunMainStack( [&]() {
RunMainStack([&]() {
getEditFrame<PCB_EDIT_FRAME>()->InstallTextPCBOptionsFrame( textPcb, NULL );
} );
@ -430,14 +429,14 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
m_controls->CaptureCursor( true );
m_controls->SetAutoPan( true );
//m_controls->ShowCursor( false );
// m_controls->ShowCursor( false );
preview.Add( text );
}
else
{
//assert( text->GetText().Length() > 0 );
//assert( text->GetTextSize().x > 0 && text->GetTextSize().y > 0 );
// assert( text->GetText().Length() > 0 );
// assert( text->GetTextSize().x > 0 && text->GetTextSize().y > 0 );
text->ClearFlags();
preview.Remove( text );
@ -465,7 +464,6 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
m_frame->SetNoToolSelected();
return 0;
}
@ -477,6 +475,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
// Add a VIEW_GROUP that serves as a preview for the new item
SELECTION preview;
m_view->Add( &preview );
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -518,14 +517,12 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
if( evt->IsActivate() ) // now finish unconditionally
break;
}
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) && step != SET_ORIGIN )
{
m_lineWidth += WIDTH_STEP;
dimension->SetWidth( m_lineWidth );
m_view->Update( &preview );
}
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && step != SET_ORIGIN )
{
if( m_lineWidth > WIDTH_STEP )
@ -535,12 +532,10 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
m_view->Update( &preview );
}
}
else if( evt->IsClick( BUT_RIGHT ) )
{
m_menu.ShowContextMenu();
}
else if( evt->IsClick( BUT_LEFT ) )
{
switch( step )
@ -582,6 +577,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
// Dimensions that have origin and end in the same spot are not valid
if( dimension->GetOrigin() == dimension->GetEnd() )
--step;
break;
case SET_HEIGHT:
@ -595,7 +591,6 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
commit.Add( dimension );
commit.Push( _( "Draw a dimension" ) );
}
}
break;
@ -608,7 +603,6 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
m_controls->CaptureCursor( false );
}
}
else if( evt->IsMotion() )
{
switch( step )
@ -648,6 +642,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
{
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zones" ) );
return drawZone( false, ZONE_MODE::ADD );
@ -657,6 +652,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawZoneKeepout( const TOOL_EVENT& aEvent )
{
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::KEEPOUT );
m_frame->SetToolID( ID_PCB_KEEPOUT_AREA_BUTT, wxCURSOR_PENCIL, _( "Add keepout" ) );
return drawZone( true, ZONE_MODE::ADD );
@ -666,6 +662,7 @@ int DRAWING_TOOL::DrawZoneKeepout( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawZoneCutout( const TOOL_EVENT& aEvent )
{
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zone cutout" ) );
return drawZone( false, ZONE_MODE::CUTOUT );
@ -675,6 +672,7 @@ int DRAWING_TOOL::DrawZoneCutout( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawSimilarZone( const TOOL_EVENT& aEvent )
{
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ZONE );
m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add similar zone" ) );
return drawZone( false, ZONE_MODE::SIMILAR );
@ -733,7 +731,6 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
m_view->Update( &preview );
}
else if( evt->Category() == TC_COMMAND )
{
// TODO it should be handled by EDIT_TOOL, so add items and select?
@ -763,12 +760,10 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
break;
}
}
else if( evt->IsClick( BUT_RIGHT ) )
{
m_menu.ShowContextMenu();
}
else if( evt->IsClick( BUT_LEFT ) )
{
// Place the drawing
@ -1016,10 +1011,11 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
}
else
{
if( aGraphic->GetEnd() == aGraphic->GetStart() ||
( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) )
if( aGraphic->GetEnd() == aGraphic->GetStart()
|| ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) )
// User has clicked twice in the same spot
{ // a clear sign that the current drawing is finished
{
// a clear sign that the current drawing is finished
// Now we have to add the helper line as well
if( direction45 )
{
@ -1044,7 +1040,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
break;
}
}
else if( evt->IsMotion() )
{
// 45 degree lines
@ -1055,7 +1050,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
m_view->Update( &preview );
}
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
{
m_lineWidth += WIDTH_STEP;
@ -1063,7 +1057,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
line45.SetWidth( m_lineWidth );
m_view->Update( &preview );
}
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && ( m_lineWidth > WIDTH_STEP ) )
{
m_lineWidth -= WIDTH_STEP;
@ -1085,8 +1078,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
* Update an arc DRAWSEGMENT from the current state
* of an Arc Geometry Manager
*/
static void updateArcFromConstructionMgr(
const KIGFX::PREVIEW::ARC_GEOM_MANAGER& aMgr,
static void updateArcFromConstructionMgr( const KIGFX::PREVIEW::ARC_GEOM_MANAGER& aMgr,
DRAWSEGMENT& aArc )
{
auto vec = aMgr.GetOrigin();
@ -1148,12 +1140,10 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
arcManager.AddPoint( cursorPos, true );
}
else if( evt->IsAction( &deleteLastPoint ) )
{
arcManager.RemoveLastPoint();
}
else if( evt->IsMotion() )
{
// set angle snap
@ -1162,7 +1152,6 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
// update, but don't step the manager state
arcManager.AddPoint( cursorPos, false );
}
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
preview.Clear();
@ -1174,21 +1163,18 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
{
m_menu.ShowContextMenu();
}
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
{
m_lineWidth += WIDTH_STEP;
aGraphic->SetWidth( m_lineWidth );
m_view->Update( &preview );
}
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && m_lineWidth > WIDTH_STEP )
{
m_lineWidth -= WIDTH_STEP;
aGraphic->SetWidth( m_lineWidth );
m_view->Update( &preview );
}
else if( evt->IsAction( &PCB_ACTIONS::arcPosture ) )
{
arcManager.ToggleClockwise();
@ -1269,12 +1255,10 @@ void DRAWING_TOOL::runPolygonEventLoop( POLYGON_GEOM_MANAGER& polyGeomMgr )
controls.SetAutoPan( false );
controls.CaptureCursor( false );
}
else if( evt->IsClick( BUT_RIGHT ) )
{
m_menu.ShowContextMenu();
}
// events that lock in nodes
else if( evt->IsClick( BUT_LEFT )
|| evt->IsDblClick( BUT_LEFT )
@ -1307,7 +1291,6 @@ void DRAWING_TOOL::runPolygonEventLoop( POLYGON_GEOM_MANAGER& polyGeomMgr )
}
}
}
else if( evt->IsAction( &deleteLastPoint ) )
{
polyGeomMgr.DeleteLastCorner();
@ -1323,7 +1306,6 @@ void DRAWING_TOOL::runPolygonEventLoop( POLYGON_GEOM_MANAGER& polyGeomMgr )
controls.CaptureCursor( false );
}
}
else if( polyGeomMgr.IsPolygonInProgress()
&& ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
{
@ -1396,68 +1378,86 @@ void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper )
}
}
int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
{
struct VIA_PLACER : public INTERACTIVE_PLACER_BASE
{
int findStitchedZoneNet( VIA *aVia )
int findStitchedZoneNet( VIA* aVia )
{
const auto pos = aVia->GetPosition();
const auto lset = aVia->GetLayerSet();
for ( auto tv : m_board->Tracks() ) // fixme: move to BOARD class?
if( tv->HitTest(pos) && (tv->GetLayerSet() &
for( auto tv : m_board->Tracks() ) // fixme: move to BOARD class?
if( tv->HitTest( pos ) && (tv->GetLayerSet() &
lset ).any() )
return -1;
for ( auto mod : m_board->Modules() )
for ( auto pad : mod->Pads() )
if( pad->HitTest(pos) && (pad->GetLayerSet() &
for( auto mod : m_board->Modules() )
for( auto pad : mod->Pads() )
if( pad->HitTest( pos ) && (pad->GetLayerSet() &
lset ).any() )
return -1;
std::set<ZONE_CONTAINER* > foundZones;
std::vector<ZONE_CONTAINER*> foundZones;
for( auto zone : m_board->Zones() )
{
if ( zone->HitTestFilledArea ( pos ) )
if( zone->HitTestFilledArea( pos ) )
{
foundZones.insert ( zone );
foundZones.push_back( zone );
}
}
printf( "Found zones : %d\n", foundZones.size() );
std::sort( foundZones.begin(), foundZones.end(),
[] ( const ZONE_CONTAINER* a, const ZONE_CONTAINER* b ) {
return a->GetLayer() < b->GetLayer();
} );
// first take the net of the active layer
for( auto z : foundZones )
{
if ( m_frame->GetActiveLayer() == z->GetLayer() )
if( m_frame->GetActiveLayer() == z->GetLayer() )
return z->GetNetCode();
}
// none? take the topmost visible layer
for( auto z : foundZones )
{
if( m_board->IsLayerVisible( z->GetLayer() ) )
return z->GetNetCode();
}
return -1;
}
bool PlaceItem( BOARD_ITEM *aItem ) override
bool PlaceItem( BOARD_ITEM* aItem ) override
{
auto via = static_cast<VIA*>(aItem);
int newNet = findStitchedZoneNet(via);
auto via = static_cast<VIA*>( aItem );
int newNet = findStitchedZoneNet( via );
if(newNet > 0 )
if( newNet > 0 )
via->SetNetCode( newNet );
return false;
}
std::unique_ptr<BOARD_ITEM> CreateItem() override
{
auto& ds = m_board->GetDesignSettings();
VIA* via = new VIA ( m_board );
VIA* via = new VIA( m_board );
via->SetNetCode( 0 );
via->SetViaType( ds.m_CurrentViaType );
// for microvias, the size and hole will be changed later.
via->SetWidth( ds.GetCurrentViaSize());
via->SetWidth( ds.GetCurrentViaSize() );
via->SetDrill( ds.GetCurrentViaDrill() );
// Usual via is from copper to component.
@ -1482,7 +1482,8 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
case VIA_MICROVIA: // from external to the near neighbor inner layer
{
PCB_LAYER_ID last_inner_layer = ToLAYER_ID( ( m_board->GetCopperLayerCount() - 2 ) );
PCB_LAYER_ID last_inner_layer =
ToLAYER_ID( ( m_board->GetCopperLayerCount() - 2 ) );
if( first_layer == B_Cu )
last_layer = last_inner_layer;
@ -1492,12 +1493,14 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
last_layer = B_Cu;
else if( first_layer == In1_Cu )
last_layer = F_Cu;
// else error: will be removed later
via->SetLayerPair( first_layer, last_layer );
// Update diameter and hole size, which where set previously
// for normal vias
NETINFO_ITEM* net = via->GetNet();
if( net )
{
via->SetWidth( net->GetMicroViaSize() );
@ -1511,8 +1514,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
}
return std::unique_ptr<BOARD_ITEM>(via);
return std::unique_ptr<BOARD_ITEM>( via );
}
};
@ -1520,13 +1522,16 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
frame()->SetToolID( ID_PCB_DRAW_VIA_BUTT, wxCURSOR_PENCIL, _( "Add vias" ) );
doInteractiveItemPlacement( &placer, _( "Place via" ), IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES );
doInteractiveItemPlacement( &placer, _(
"Place via" ),
IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES );
frame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0;
}
void DRAWING_TOOL::SetTransitions()
{
Go( &DRAWING_TOOL::DrawLine, PCB_ACTIONS::drawLine.MakeEvent() );
@ -1576,4 +1581,5 @@ PCB_LAYER_ID DRAWING_TOOL::getDrawingLayer() const
return layer;
}
const unsigned int DRAWING_TOOL::WIDTH_STEP = 100000;

View File

@ -1116,12 +1116,8 @@ static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition
int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent )
{
printf("ShowLocalRTool!\n");
Activate();
auto picker = m_toolMgr->GetTool<PICKER_TOOL>();
assert( picker );

View File

@ -556,17 +556,9 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) );
// Rebuild pointers and connectivity that can be changed.
if( reBuild_ratsnest )
if( reBuild_ratsnest || deep_reBuild_ratsnest )
{
// Compile ratsnest propagates nets from pads to tracks
/// @todo LEGACY Compile_Ratsnest() has to be rewritten and moved to RN_DATA
if( deep_reBuild_ratsnest )
Compile_Ratsnest( NULL, false );
if( IsGalCanvasActive() )
{
connectivity->RecalculateRatsnest();
}
}
}