Connectivity: local ratsnest for both legacy & GAL. Further removal of legacy code
This commit is contained in:
parent
07b7600ae5
commit
c4c329e393
|
@ -62,3 +62,12 @@ demos/**/_autosave-*
|
||||||
.*.swp
|
.*.swp
|
||||||
*~
|
*~
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.png
|
||||||
|
*.kiface
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.cmake
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
*.so
|
||||||
|
*.old
|
|
@ -37,8 +37,7 @@
|
||||||
#include <connectivity.h>
|
#include <connectivity.h>
|
||||||
|
|
||||||
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
|
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
|
||||||
BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED_ITEM ),
|
BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED_ITEM )
|
||||||
m_Subnet( 0 ), m_ZoneSubnet( 0 )
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,34 +116,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool SetNetCode( int aNetCode, bool aNoAssert=false );
|
bool SetNetCode( int aNetCode, bool aNoAssert=false );
|
||||||
|
|
||||||
/**
|
|
||||||
* Function GetSubNet
|
|
||||||
* @return int - the sub net code.
|
|
||||||
*/
|
|
||||||
int GetSubNet() const
|
|
||||||
{
|
|
||||||
return m_Subnet;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetSubNet( int aSubNetCode )
|
|
||||||
{
|
|
||||||
m_Subnet = aSubNetCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function GetZoneSubNet
|
|
||||||
* @return int - the sub net code in zone connections.
|
|
||||||
*/
|
|
||||||
int GetZoneSubNet() const
|
|
||||||
{
|
|
||||||
return m_ZoneSubnet;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetZoneSubNet( int aSubNetCode )
|
|
||||||
{
|
|
||||||
m_ZoneSubnet = aSubNetCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetNetname
|
* Function GetNetname
|
||||||
* @return wxString - the full netname
|
* @return wxString - the full netname
|
||||||
|
@ -189,17 +161,23 @@ public:
|
||||||
*/
|
*/
|
||||||
wxString GetNetClassName() const;
|
wxString GetNetClassName() const;
|
||||||
|
|
||||||
|
void SetLocalRatsnestVisible( bool aVisible )
|
||||||
|
{
|
||||||
|
m_localRatsnestVisible = aVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetLocalRatsnestVisible() const
|
||||||
|
{
|
||||||
|
return m_localRatsnestVisible;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Stores all informations about the net that item belongs to
|
/// Stores all informations about the net that item belongs to
|
||||||
NETINFO_ITEM* m_netinfo;
|
NETINFO_ITEM* m_netinfo;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_Subnet; /* In rastnest routines : for the current net, block number
|
|
||||||
* (number common to the current connected items found)
|
|
||||||
*/
|
|
||||||
|
|
||||||
int m_ZoneSubnet; // used in rastnest computations : for the current net,
|
bool m_localRatsnestVisible;
|
||||||
// handle cluster number in zone connection
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -658,13 +658,6 @@ void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList )
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) );
|
||||||
|
|
||||||
/* For test and debug only: display m_physical_connexion and
|
|
||||||
* m_logical_connexion */
|
|
||||||
#if 1 // Used only to debug connectivity calculations
|
|
||||||
Line.Printf( wxT( "%d-%d-%d " ), GetSubRatsnest(), GetSubNet(), GetZoneSubNet() );
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( wxT( "L-P-Z" ), Line, DARKGREEN ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
board = GetBoard();
|
board = GetBoard();
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Layer" ),
|
aList.push_back( MSG_PANEL_ITEM( _( "Layer" ),
|
||||||
|
|
|
@ -1094,7 +1094,7 @@ void TRACK::GetMsgPanelInfoBase_Common( std::vector< MSG_PANEL_ITEM >& aList )
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
|
||||||
|
|
||||||
// Display net code : (useful in test or debug)
|
// Display net code : (useful in test or debug)
|
||||||
msg.Printf( wxT( "%d.%d" ), GetNetCode(), GetSubNet() );
|
msg.Printf( wxT( "%d" ), GetNetCode() );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,72 +95,4 @@ static void RebuildTrackChain( BOARD* pcb )
|
||||||
|
|
||||||
void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
|
void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
// Skip dummy net -1, and "not connected" net 0 (grouping all not connected pads)
|
|
||||||
if( aNetCode <= 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
|
|
||||||
Compile_Ratsnest( aDC, true );
|
|
||||||
|
|
||||||
// Clear the cluster identifier (subnet) of pads for this net
|
|
||||||
// Pads are grouped by netcode (and in netname alphabetic order)
|
|
||||||
for( unsigned i = 0; i < m_Pcb->GetPadCount(); ++i )
|
|
||||||
{
|
|
||||||
D_PAD* pad = m_Pcb->GetPad(i);
|
|
||||||
|
|
||||||
if( m_Pcb->GetPad(i)->GetNetCode() == aNetCode )
|
|
||||||
pad->SetSubNet( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Pcb->Test_Connections_To_Copper_Areas( aNetCode );
|
|
||||||
|
|
||||||
// Search for the first and the last segment relative to the given net code
|
|
||||||
if( m_Pcb->m_Track )
|
|
||||||
{
|
|
||||||
CONNECTIONS connections( m_Pcb );
|
|
||||||
|
|
||||||
TRACK* lastTrack = NULL;
|
|
||||||
TRACK* firstTrack = m_Pcb->m_Track.GetFirst()->GetStartNetCode( aNetCode );
|
|
||||||
|
|
||||||
if( firstTrack )
|
|
||||||
lastTrack = firstTrack->GetEndNetCode( aNetCode );
|
|
||||||
|
|
||||||
if( firstTrack && lastTrack ) // i.e. if there are segments
|
|
||||||
{
|
|
||||||
connections.Build_CurrNet_SubNets_Connections( firstTrack, lastTrack, aNetCode );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Merge_SubNets_Connected_By_CopperAreas( m_Pcb, aNetCode );
|
|
||||||
|
|
||||||
// rebuild the active ratsnest for this net
|
|
||||||
DrawGeneralRatsnest( aDC, aNetCode );
|
|
||||||
TestForActiveLinksInRatsnest( aNetCode );
|
|
||||||
DrawGeneralRatsnest( aDC, aNetCode );
|
|
||||||
|
|
||||||
// Display results
|
|
||||||
wxString msg;
|
|
||||||
int net_notconnected_count = 0;
|
|
||||||
NETINFO_ITEM* net = m_Pcb->FindNet( aNetCode );
|
|
||||||
|
|
||||||
if( net ) // Should not occur, but ...
|
|
||||||
{
|
|
||||||
for( unsigned ii = net->m_RatsnestStartIdx; ii < net->m_RatsnestEndIdx; ii++ )
|
|
||||||
{
|
|
||||||
if( m_Pcb->m_FullRatsnest[ii].IsActive() )
|
|
||||||
net_notconnected_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Printf( wxT( "links %d nc %d net %d: not conn %d" ),
|
|
||||||
m_Pcb->GetRatsnestsCount(), m_Pcb->GetUnconnectedNetCount(), aNetCode,
|
|
||||||
net_notconnected_count );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
msg.Printf( wxT( "net not found: netcode %d" ), aNetCode );
|
|
||||||
|
|
||||||
SetStatusText( msg );
|
|
||||||
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,6 +285,8 @@ const std::vector<RN_DYNAMIC_LINE>& CONNECTIVITY_DATA::GetDynamicRatsnest() cons
|
||||||
|
|
||||||
void CONNECTIVITY_DATA::ClearDynamicRatsnest()
|
void CONNECTIVITY_DATA::ClearDynamicRatsnest()
|
||||||
{
|
{
|
||||||
|
m_connAlgo->ForEachAnchor( [] (CN_ANCHOR_PTR anchor ) { anchor->SetNoLine( false ); } );
|
||||||
|
|
||||||
m_dynamicConnectivity.reset();
|
m_dynamicConnectivity.reset();
|
||||||
m_dynamicRatsnest.clear();
|
m_dynamicRatsnest.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,7 +480,7 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones )
|
||||||
auto zoneItem = static_cast<CN_ZONE *> (item);
|
auto zoneItem = static_cast<CN_ZONE *> (item);
|
||||||
auto searchZones = std::bind( checkForConnection, _1, zoneItem );
|
auto searchZones = std::bind( checkForConnection, _1, zoneItem );
|
||||||
|
|
||||||
if( zoneItem->Dirty() )
|
if( zoneItem->Dirty() || m_padList.IsDirty() || m_trackList.IsDirty() || m_viaList.IsDirty() )
|
||||||
{
|
{
|
||||||
totalDirtyCount++;
|
totalDirtyCount++;
|
||||||
m_viaList.FindNearby( zoneItem->BBox(), searchZones );
|
m_viaList.FindNearby( zoneItem->BBox(), searchZones );
|
||||||
|
@ -901,3 +901,15 @@ void CN_CONNECTIVITY_ALGO::Clear()
|
||||||
m_zoneList.Clear();
|
m_zoneList.Clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CN_CONNECTIVITY_ALGO::ForEachAnchor( std::function<void(CN_ANCHOR_PTR)> aFunc )
|
||||||
|
{
|
||||||
|
for ( auto anchor : m_padList.Anchors() )
|
||||||
|
aFunc( anchor );
|
||||||
|
for ( auto anchor : m_viaList.Anchors() )
|
||||||
|
aFunc( anchor );
|
||||||
|
for ( auto anchor : m_trackList.Anchors() )
|
||||||
|
aFunc( anchor );
|
||||||
|
for ( auto anchor : m_zoneList.Anchors() )
|
||||||
|
aFunc( anchor );
|
||||||
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ public:
|
||||||
{
|
{
|
||||||
return m_target->Pos();
|
return m_target->Pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CN_ANCHOR_PTR m_source;
|
CN_ANCHOR_PTR m_source;
|
||||||
CN_ANCHOR_PTR m_target;
|
CN_ANCHOR_PTR m_target;
|
||||||
|
@ -504,6 +504,8 @@ public:
|
||||||
ITER begin() { return m_items.begin(); };
|
ITER begin() { return m_items.begin(); };
|
||||||
ITER end() { return m_items.end(); };
|
ITER end() { return m_items.end(); };
|
||||||
|
|
||||||
|
std::vector<CN_ANCHOR_PTR>& Anchors() { return m_anchors; }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, bool aDirtyOnly = false );
|
void FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, bool aDirtyOnly = false );
|
||||||
|
|
||||||
|
@ -940,6 +942,8 @@ public:
|
||||||
|
|
||||||
const CLUSTERS& GetClusters();
|
const CLUSTERS& GetClusters();
|
||||||
int GetUnconnectedCount();
|
int GetUnconnectedCount();
|
||||||
|
|
||||||
|
void ForEachAnchor( std::function<void(CN_ANCHOR_PTR)> aFunc );
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator<( const CN_ANCHOR_PTR a, const CN_ANCHOR_PTR b );
|
bool operator<( const CN_ANCHOR_PTR a, const CN_ANCHOR_PTR b );
|
||||||
|
|
|
@ -296,7 +296,6 @@ void PCB_EDIT_FRAME::Change_Side_Module( MODULE* Module, wxDC* DC )
|
||||||
|
|
||||||
if( !Module->IsMoving() ) /* This is a simple flip, no other edition in progress */
|
if( !Module->IsMoving() ) /* This is a simple flip, no other edition in progress */
|
||||||
{
|
{
|
||||||
GetBoard()->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK );
|
|
||||||
|
|
||||||
if( DC )
|
if( DC )
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,30 +97,31 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
|
||||||
|
|
||||||
auto connectivity = m_Pcb->GetConnectivity();
|
auto connectivity = m_Pcb->GetConnectivity();
|
||||||
|
|
||||||
COLOR4D color = g_ColorsSettings.GetItemColor(LAYER_RATSNEST);
|
COLOR4D color = g_ColorsSettings.GetItemColor( LAYER_RATSNEST );
|
||||||
|
|
||||||
for( int i = 1; i < connectivity->GetNetCount(); ++i )
|
for( int i = 1; i < connectivity->GetNetCount(); ++i )
|
||||||
{
|
{
|
||||||
RN_NET* net = connectivity->GetRatsnestForNet( i );
|
RN_NET* net = connectivity->GetRatsnestForNet( i );
|
||||||
|
|
||||||
if( ( aNetcode <= 0 ) || ( aNetcode == i ) )
|
if( ( aNetcode <= 0 ) || ( aNetcode == i ) )
|
||||||
|
{
|
||||||
|
for( const auto& edge : net->GetEdges() )
|
||||||
{
|
{
|
||||||
for ( const auto& edge : net->GetEdges() )
|
auto s = edge.GetSourcePos();
|
||||||
{
|
auto d = edge.GetTargetPos();
|
||||||
if ( edge.IsVisible() )
|
auto sn = edge.GetSourceNode();
|
||||||
{
|
auto dn = edge.GetTargetNode();
|
||||||
auto s = edge.GetSourcePos();
|
|
||||||
auto d = edge.GetTargetPos();
|
|
||||||
auto sn = edge.GetSourceNode();
|
|
||||||
auto dn = edge.GetTargetNode();
|
|
||||||
|
|
||||||
if ( !sn->GetNoLine() && !dn->GetNoLine() )
|
bool enable = !sn->GetNoLine() && !dn->GetNoLine();
|
||||||
GRLine( m_canvas->GetClipBox(), aDC, wxPoint(s.x, s.y), wxPoint(d.x, d.y), 0, color );
|
bool show = sn->Parent()->GetLocalRatsnestVisible()
|
||||||
}
|
|| dn->Parent()->GetLocalRatsnestVisible();
|
||||||
}
|
|
||||||
|
if( enable && show )
|
||||||
|
GRLine( m_canvas->GetClipBox(), aDC, wxPoint( s.x, s.y ), wxPoint( d.x,
|
||||||
|
d.y ), 0, color );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,7 +134,8 @@ void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC )
|
||||||
|
|
||||||
for( const auto& l : GetBoard()->GetConnectivity()->GetDynamicRatsnest() )
|
for( const auto& l : GetBoard()->GetConnectivity()->GetDynamicRatsnest() )
|
||||||
{
|
{
|
||||||
GRLine( m_canvas->GetClipBox(), DC, wxPoint(l.a.x, l.a.y), wxPoint(l.b.x, l.b.y), 0, tmpcolor );
|
GRLine( m_canvas->GetClipBox(), DC, wxPoint( l.a.x, l.a.y ), wxPoint( l.b.x,
|
||||||
|
l.b.y ), 0, tmpcolor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,8 +155,8 @@ void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC )
|
||||||
* drawn
|
* drawn
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static wxPoint s_CursorPos; // Coordinate of the moving point (mouse cursor and
|
static wxPoint s_CursorPos; // Coordinate of the moving point (mouse cursor and
|
||||||
// end of current track segment)
|
// end of current track segment)
|
||||||
|
|
||||||
/* Function BuildAirWiresTargetsList
|
/* Function BuildAirWiresTargetsList
|
||||||
* Build a list of candidates that can be a coonection point
|
* Build a list of candidates that can be a coonection point
|
||||||
|
@ -163,11 +165,11 @@ void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC )
|
||||||
* from the current new track to candidates during track creation
|
* from the current new track to candidates during track creation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static BOARD_CONNECTED_ITEM *s_ref = nullptr;
|
static BOARD_CONNECTED_ITEM* s_ref = nullptr;
|
||||||
static int s_refNet = -1;
|
static int s_refNet = -1;
|
||||||
|
|
||||||
void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
|
void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
|
||||||
const wxPoint& aPosition, int aNet )
|
const wxPoint& aPosition, int aNet )
|
||||||
{
|
{
|
||||||
s_CursorPos = aPosition; // needed for sort_by_distance
|
s_CursorPos = aPosition; // needed for sort_by_distance
|
||||||
s_ref = aItemRef;
|
s_ref = aItemRef;
|
||||||
|
@ -175,25 +177,24 @@ void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static MODULE movedModule( nullptr );
|
||||||
|
|
||||||
|
void PCB_BASE_FRAME::build_ratsnest_module( MODULE* mod, wxPoint aMoveVector )
|
||||||
static MODULE movedModule(nullptr);
|
|
||||||
|
|
||||||
void PCB_BASE_FRAME::build_ratsnest_module( MODULE *mod, wxPoint aMoveVector )
|
|
||||||
{
|
{
|
||||||
auto connectivity = GetBoard()->GetConnectivity();
|
auto connectivity = GetBoard()->GetConnectivity();
|
||||||
|
|
||||||
movedModule = *mod;
|
movedModule = *mod;
|
||||||
movedModule.Move( -aMoveVector );
|
movedModule.Move( -aMoveVector );
|
||||||
connectivity->ClearDynamicRatsnest();
|
connectivity->ClearDynamicRatsnest();
|
||||||
connectivity->BlockRatsnestItems( {mod} );
|
connectivity->BlockRatsnestItems( { mod } );
|
||||||
connectivity->ComputeDynamicRatsnest( {&movedModule} );
|
connectivity->ComputeDynamicRatsnest( { &movedModule } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_BASE_FRAME::TraceAirWiresToTargets( wxDC* aDC )
|
void PCB_BASE_FRAME::TraceAirWiresToTargets( wxDC* aDC )
|
||||||
{
|
{
|
||||||
auto connectivity = GetBoard()->GetConnectivity();
|
auto connectivity = GetBoard()->GetConnectivity();
|
||||||
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
|
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) GetDisplayOptions();
|
||||||
|
|
||||||
auto targets = connectivity->NearestUnconnectedTargets( s_ref, s_CursorPos, s_refNet );
|
auto targets = connectivity->NearestUnconnectedTargets( s_ref, s_CursorPos, s_refNet );
|
||||||
|
|
||||||
|
@ -202,23 +203,23 @@ void PCB_BASE_FRAME::TraceAirWiresToTargets( wxDC* aDC )
|
||||||
|
|
||||||
GRSetDrawMode( aDC, GR_XOR );
|
GRSetDrawMode( aDC, GR_XOR );
|
||||||
|
|
||||||
for (int i = 0; i < std::min( (int)displ_opts->m_MaxLinksShowed, (int)targets.size() ); i++)
|
for( int i = 0; i < std::min( (int) displ_opts->m_MaxLinksShowed, (int) targets.size() ); i++ )
|
||||||
{
|
{
|
||||||
auto p = targets[i];
|
auto p = targets[i];
|
||||||
GRLine( m_canvas->GetClipBox(), aDC, s_CursorPos, wxPoint(p.x, p.y), 0, YELLOW );
|
GRLine( m_canvas->GetClipBox(), aDC, s_CursorPos, wxPoint( p.x, p.y ), 0, YELLOW );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Redraw in XOR mode the outlines of the module.
|
// Redraw in XOR mode the outlines of the module.
|
||||||
void MODULE::DrawOutlinesWhenMoving( EDA_DRAW_PANEL* panel, wxDC* DC,
|
void MODULE::DrawOutlinesWhenMoving( EDA_DRAW_PANEL* panel, wxDC* DC,
|
||||||
const wxPoint& aMoveVector )
|
const wxPoint& aMoveVector )
|
||||||
{
|
{
|
||||||
int pad_fill_tmp;
|
int pad_fill_tmp;
|
||||||
D_PAD* pt_pad;
|
D_PAD* pt_pad;
|
||||||
|
|
||||||
DrawEdgesOnly( panel, DC, aMoveVector, GR_XOR );
|
DrawEdgesOnly( panel, DC, aMoveVector, GR_XOR );
|
||||||
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
|
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) panel->GetDisplayOptions();
|
||||||
|
|
||||||
// Show pads in sketch mode to speedu up drawings
|
// Show pads in sketch mode to speedu up drawings
|
||||||
pad_fill_tmp = displ_opts->m_DisplayPadFill;
|
pad_fill_tmp = displ_opts->m_DisplayPadFill;
|
||||||
|
@ -239,101 +240,18 @@ void MODULE::DrawOutlinesWhenMoving( EDA_DRAW_PANEL* panel, wxDC* DC,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_EDIT_FRAME::Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC )
|
void PCB_EDIT_FRAME::Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC )
|
||||||
{
|
{
|
||||||
if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) )
|
if( item->Type() == PCB_MODULE_T )
|
||||||
return;
|
|
||||||
|
|
||||||
Compile_Ratsnest( DC, true );
|
|
||||||
|
|
||||||
printf("show1r: %p\n", item);
|
|
||||||
|
|
||||||
auto connectivity = GetBoard()->GetConnectivity();
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if( item )
|
|
||||||
{
|
{
|
||||||
if( item->Type() == PCB_PAD_T )
|
auto mod = static_cast<MODULE*> (item);
|
||||||
|
|
||||||
|
for( auto pad : mod->PadsIter() )
|
||||||
{
|
{
|
||||||
pt_pad = (D_PAD*) item;
|
pad->SetLocalRatsnestVisible( true );
|
||||||
Module = pt_pad->GetParent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pt_pad ) // Displaying the ratsnest of the corresponding net.
|
m_canvas->Refresh();
|
||||||
{
|
|
||||||
SetMsgPanel( pt_pad );
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
|
|
||||||
{
|
|
||||||
RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
|
|
||||||
|
|
||||||
if( net->GetNet() == pt_pad->GetNetCode() )
|
|
||||||
{
|
|
||||||
if( ( net->m_Status & CH_VISIBLE ) != 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
net->m_Status |= CH_VISIBLE;
|
|
||||||
|
|
||||||
if( ( net->m_Status & CH_ACTIF ) == 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( item->Type() == PCB_MODULE_TEXT_T )
|
|
||||||
{
|
|
||||||
if( item->GetParent() && ( item->GetParent()->Type() == PCB_MODULE_T ) )
|
|
||||||
Module = static_cast<MODULE*>( item->GetParent() );
|
|
||||||
}
|
|
||||||
else if( item->Type() == PCB_MODULE_T )
|
|
||||||
{
|
|
||||||
Module = static_cast<MODULE*>( item );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Module )
|
|
||||||
{
|
|
||||||
SetMsgPanel( Module );
|
|
||||||
pt_pad = Module->Pads();
|
|
||||||
|
|
||||||
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
|
|
||||||
{
|
|
||||||
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
|
|
||||||
{
|
|
||||||
RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
|
|
||||||
|
|
||||||
if( ( net->m_PadStart == pt_pad ) || ( net->m_PadEnd == pt_pad ) )
|
|
||||||
{
|
|
||||||
if( net->m_Status & CH_VISIBLE )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
net->m_Status |= CH_VISIBLE;
|
|
||||||
|
|
||||||
if( (net->m_Status & CH_ACTIF) == 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pt_pad = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase if no pad or module has been selected.
|
|
||||||
if( ( pt_pad == NULL ) && ( Module == NULL ) )
|
|
||||||
{
|
|
||||||
DrawGeneralRatsnest( DC );
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
|
|
||||||
GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,16 +55,9 @@ const BOX2I RATSNEST_VIEWITEM::ViewBBox() const
|
||||||
return bbox;
|
return bbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <geometry/seg.h>
|
|
||||||
std::vector<SEG> delEdges;
|
|
||||||
|
|
||||||
void clearDEdges() { delEdges.clear(); }
|
|
||||||
void addDEdge ( SEG edge ) { delEdges.push_back(edge); }
|
|
||||||
|
|
||||||
|
|
||||||
void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||||
{
|
{
|
||||||
static const double crossSize = 100000.0;
|
constexpr int CROSS_SIZE = 200000;
|
||||||
|
|
||||||
auto gal = aView->GetGAL();
|
auto gal = aView->GetGAL();
|
||||||
gal->SetIsStroke( true );
|
gal->SetIsStroke( true );
|
||||||
|
@ -76,23 +69,19 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||||
int highlightedNet = rs->GetHighlightNetCode();
|
int highlightedNet = rs->GetHighlightNetCode();
|
||||||
|
|
||||||
gal->SetStrokeColor( color.Brightened( 0.8 ) );
|
gal->SetStrokeColor( color.Brightened( 0.8 ) );
|
||||||
for (auto s : delEdges)
|
|
||||||
gal->DrawLine( s.A, s.B );
|
|
||||||
|
|
||||||
|
|
||||||
// Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved)
|
// Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved)
|
||||||
for( const auto& l : m_data->GetDynamicRatsnest() )
|
for( const auto& l : m_data->GetDynamicRatsnest() )
|
||||||
{
|
{
|
||||||
if ( l.a == l.b )
|
if ( l.a == l.b )
|
||||||
{
|
{
|
||||||
gal->DrawLine( VECTOR2I( l.a.x - crossSize, l.a.y - crossSize ), VECTOR2I( l.b.x + crossSize, l.b.y + crossSize ) );
|
gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y - CROSS_SIZE ), VECTOR2I( l.b.x + CROSS_SIZE, l.b.y + CROSS_SIZE ) );
|
||||||
gal->DrawLine( VECTOR2I( l.a.x - crossSize, l.a.y + crossSize ), VECTOR2I( l.b.x + crossSize, l.b.y - crossSize ) );
|
gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y + CROSS_SIZE ), VECTOR2I( l.b.x + CROSS_SIZE, l.b.y - CROSS_SIZE ) );
|
||||||
} else {
|
} else {
|
||||||
gal->DrawLine( l.a, l.b );
|
gal->DrawLine( l.a, l.b );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic ratsnest (for e.g. dragged items)
|
|
||||||
for( int i = 1; i < m_data->GetNetCount(); ++i )
|
for( int i = 1; i < m_data->GetNetCount(); ++i )
|
||||||
{
|
{
|
||||||
RN_NET* net = m_data->GetRatsnestForNet( i );
|
RN_NET* net = m_data->GetRatsnestForNet( i );
|
||||||
|
@ -103,20 +92,21 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||||
|
|
||||||
for( const auto& edge : net->GetUnconnected() )
|
for( const auto& edge : net->GetUnconnected() )
|
||||||
{
|
{
|
||||||
if ( !edge.IsVisible() )
|
//if ( !edge.IsVisible() )
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
const auto& sourceNode = edge.GetSourceNode();
|
const auto& sourceNode = edge.GetSourceNode();
|
||||||
const auto& targetNode = edge.GetTargetNode();
|
const auto& targetNode = edge.GetTargetNode();
|
||||||
const VECTOR2I source( sourceNode->Pos() );
|
const VECTOR2I source( sourceNode->Pos() );
|
||||||
const VECTOR2I target( targetNode->Pos() );
|
const VECTOR2I target( targetNode->Pos() );
|
||||||
|
|
||||||
if ( !sourceNode->GetNoLine() && !targetNode->GetNoLine() )
|
bool enable = !sourceNode->GetNoLine() && !targetNode->GetNoLine();
|
||||||
|
bool show = sourceNode->Parent()->GetLocalRatsnestVisible() || targetNode->Parent()->GetLocalRatsnestVisible();
|
||||||
|
|
||||||
|
if ( enable && show )
|
||||||
{
|
{
|
||||||
if ( source == target )
|
if ( source == target )
|
||||||
{
|
{
|
||||||
constexpr int CROSS_SIZE = 200000;
|
|
||||||
|
|
||||||
gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y - CROSS_SIZE ), VECTOR2I( source.x + CROSS_SIZE, source.y + CROSS_SIZE ) );
|
gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y - CROSS_SIZE ), VECTOR2I( source.x + CROSS_SIZE, source.y + CROSS_SIZE ) );
|
||||||
gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y + CROSS_SIZE ), VECTOR2I( source.x + CROSS_SIZE, source.y - CROSS_SIZE ) );
|
gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y + CROSS_SIZE ), VECTOR2I( source.x + CROSS_SIZE, source.y - CROSS_SIZE ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -588,11 +588,6 @@ TOOL_ACTION COMMON_ACTIONS::toBeDone( "pcbnew.Control.toBeDone",
|
||||||
AS_GLOBAL, 0, // dialog saying it is not implemented yet
|
AS_GLOBAL, 0, // dialog saying it is not implemented yet
|
||||||
"", "" ); // so users are aware of that
|
"", "" ); // so users are aware of that
|
||||||
|
|
||||||
TOOL_ACTION COMMON_ACTIONS::showLocalRatsnest( "pcbnew.Control.showLocalRatsnest",
|
|
||||||
AS_GLOBAL, 0,
|
|
||||||
"", "" );
|
|
||||||
|
|
||||||
|
|
||||||
TOOL_ACTION COMMON_ACTIONS::routerActivateSingle( "pcbnew.InteractiveRouter.SingleTrack",
|
TOOL_ACTION COMMON_ACTIONS::routerActivateSingle( "pcbnew.InteractiveRouter.SingleTrack",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_NEW_TRACK ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_NEW_TRACK ),
|
||||||
_( "Interactive Router (Single Tracks)" ),
|
_( "Interactive Router (Single Tracks)" ),
|
||||||
|
|
|
@ -162,7 +162,7 @@ boost::optional<TOOL_EVENT> PCB_ACTIONS::TranslateLegacyId( int aId )
|
||||||
return PCB_ACTIONS::appendBoard.MakeEvent();
|
return PCB_ACTIONS::appendBoard.MakeEvent();
|
||||||
|
|
||||||
case ID_PCB_SHOW_1_RATSNEST_BUTT:
|
case ID_PCB_SHOW_1_RATSNEST_BUTT:
|
||||||
return PCB_ACTIONS::toBeDone.MakeEvent();
|
return PCB_ACTIONS::showLocalRatsnest.MakeEvent();
|
||||||
|
|
||||||
case ID_PCB_MUWAVE_TOOL_GAP_CMD:
|
case ID_PCB_MUWAVE_TOOL_GAP_CMD:
|
||||||
return PCB_ACTIONS::microwaveCreateGap.MakeEvent();
|
return PCB_ACTIONS::microwaveCreateGap.MakeEvent();
|
||||||
|
|
|
@ -148,6 +148,10 @@ TOOL_ACTION PCB_ACTIONS::highlightNetCursor( "pcbnew.EditorControl.highlightNetC
|
||||||
AS_GLOBAL, 0,
|
AS_GLOBAL, 0,
|
||||||
"", "" );
|
"", "" );
|
||||||
|
|
||||||
|
TOOL_ACTION PCB_ACTIONS::showLocalRatsnest( "pcbnew.Control.showLocalRatsnest",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"", "" );
|
||||||
|
|
||||||
|
|
||||||
class ZONE_CONTEXT_MENU : public CONTEXT_MENU
|
class ZONE_CONTEXT_MENU : public CONTEXT_MENU
|
||||||
{
|
{
|
||||||
|
@ -484,7 +488,7 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
|
||||||
controls->SetSnapping( false );
|
controls->SetSnapping( false );
|
||||||
controls->SetAutoPan( false );
|
controls->SetAutoPan( false );
|
||||||
controls->CaptureCursor( false );
|
controls->CaptureCursor( false );
|
||||||
|
|
||||||
view->Remove( &preview );
|
view->Remove( &preview );
|
||||||
m_frame->SetNoToolSelected();
|
m_frame->SetNoToolSelected();
|
||||||
|
|
||||||
|
@ -1058,25 +1062,45 @@ int PCB_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool showLocalRatsnest( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
||||||
KIGFX::ORIGIN_VIEWITEM* aItem, const VECTOR2D& aPosition )
|
|
||||||
{
|
{
|
||||||
aFrame->SetAuxOrigin( wxPoint( aPosition.x, aPosition.y ) );
|
auto selectionTool = aToolMgr->GetTool<SELECTION_TOOL>();
|
||||||
aItem->SetPosition( aPosition );
|
|
||||||
aView->MarkDirty();
|
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
||||||
|
|
||||||
|
const SELECTION& selection = selectionTool->GetSelection();
|
||||||
|
|
||||||
|
if( selection.Empty() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for ( auto item : selection )
|
||||||
|
{
|
||||||
|
if ( item->Type() == PCB_MODULE_T )
|
||||||
|
{
|
||||||
|
for ( auto pad : static_cast<MODULE *> (item)->PadsIter() )
|
||||||
|
{
|
||||||
|
pad->SetLocalRatsnestVisible( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent )
|
int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
|
printf("ShowLocalRTool!\n");
|
||||||
|
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
auto picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||||
assert( picker );
|
assert( picker );
|
||||||
|
|
||||||
m_frame->SetToolID( ID_PCB_SHOW_1_RATSNEST_BUTT, wxCURSOR_PENCIL, _( "Pick Components for Local Ratsnest" ) );
|
m_frame->SetToolID( ID_PCB_SHOW_1_RATSNEST_BUTT, wxCURSOR_PENCIL, _( "Pick Components for Local Ratsnest" ) );
|
||||||
//picker->SetClickHandler( std::bind( showLocalRatsnest, m_toolMgr, _1 ) );
|
picker->SetClickHandler( std::bind( showLocalRatsnest, m_toolMgr, _1 ) );
|
||||||
picker->SetSnapping( false );
|
picker->SetSnapping( false );
|
||||||
picker->Activate();
|
picker->Activate();
|
||||||
Wait();
|
Wait();
|
||||||
|
@ -1086,7 +1110,7 @@ int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent )
|
int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
/* SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||||
const SELECTION& selection = selTool->GetSelection();
|
const SELECTION& selection = selTool->GetSelection();
|
||||||
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
|
||||||
|
|
||||||
|
@ -1099,7 +1123,7 @@ int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent )
|
||||||
ratsnest->AddSimple( static_cast<BOARD_ITEM*>( item ) );
|
ratsnest->AddSimple( static_cast<BOARD_ITEM*>( item ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1132,6 +1156,7 @@ void PCB_EDITOR_CONTROL::SetTransitions()
|
||||||
Go( &PCB_EDITOR_CONTROL::DrillOrigin, PCB_ACTIONS::drillOrigin.MakeEvent() );
|
Go( &PCB_EDITOR_CONTROL::DrillOrigin, PCB_ACTIONS::drillOrigin.MakeEvent() );
|
||||||
Go( &PCB_EDITOR_CONTROL::HighlightNet, PCB_ACTIONS::highlightNet.MakeEvent() );
|
Go( &PCB_EDITOR_CONTROL::HighlightNet, PCB_ACTIONS::highlightNet.MakeEvent() );
|
||||||
Go( &PCB_EDITOR_CONTROL::HighlightNetCursor, PCB_ACTIONS::highlightNetCursor.MakeEvent() );
|
Go( &PCB_EDITOR_CONTROL::HighlightNetCursor, PCB_ACTIONS::highlightNetCursor.MakeEvent() );
|
||||||
|
Go( &PCB_EDITOR_CONTROL::ShowLocalRatsnest, PCB_ACTIONS::showLocalRatsnest.MakeEvent() );
|
||||||
Go( &PCB_EDITOR_CONTROL::UpdateSelectionRatsnest, PCB_ACTIONS::selectionModified.MakeEvent() );
|
Go( &PCB_EDITOR_CONTROL::UpdateSelectionRatsnest, PCB_ACTIONS::selectionModified.MakeEvent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include <protos.h>
|
#include <protos.h>
|
||||||
#include <zones_functions_for_undo_redo.h>
|
#include <zones_functions_for_undo_redo.h>
|
||||||
#include <drc_stuff.h>
|
#include <drc_stuff.h>
|
||||||
#include <ratsnest_data.h>
|
#include <connectivity.h>
|
||||||
|
|
||||||
// Outline creation:
|
// Outline creation:
|
||||||
static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC );
|
static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC );
|
||||||
|
@ -951,12 +951,12 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
|
||||||
if( zone->IsFilled() )
|
if( zone->IsFilled() )
|
||||||
{
|
{
|
||||||
Fill_Zone( zone );
|
Fill_Zone( zone );
|
||||||
GetBoard()->GetRatsnest()->Recalculate( zone->GetNetCode() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Stage( s_PickedList );
|
commit.Stage( s_PickedList );
|
||||||
commit.Push( _( "Modify zone properties" ) );
|
commit.Push( _( "Modify zone properties" ) );
|
||||||
|
GetBoard()->GetConnectivity()->RecalculateRatsnest();
|
||||||
|
|
||||||
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items
|
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,409 +0,0 @@
|
||||||
/**
|
|
||||||
* @file zones_polygons_test_connections.cpp
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
|
||||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, you may find one here:
|
|
||||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
||||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
||||||
* or you may write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm> // sort
|
|
||||||
|
|
||||||
#include <fctsys.h>
|
|
||||||
#include <common.h>
|
|
||||||
#include <macros.h>
|
|
||||||
|
|
||||||
#include <class_board.h>
|
|
||||||
#include <class_module.h>
|
|
||||||
#include <class_track.h>
|
|
||||||
#include <class_zone.h>
|
|
||||||
|
|
||||||
#include <pcbnew.h>
|
|
||||||
#include <zones.h>
|
|
||||||
#include <polygon_test_point_inside.h>
|
|
||||||
|
|
||||||
static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b );
|
|
||||||
|
|
||||||
void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode );
|
|
||||||
|
|
||||||
// This helper function sort a list of zones by netcode,
|
|
||||||
// and for a given netcode by zone size
|
|
||||||
// zone size = size of the m_FilledPolysList buffer
|
|
||||||
bool sort_areas( const ZONE_CONTAINER* ref, const ZONE_CONTAINER* tst )
|
|
||||||
{
|
|
||||||
if( ref->GetNetCode() == tst->GetNetCode() )
|
|
||||||
return ref->GetFilledPolysList().TotalVertices() <
|
|
||||||
tst->GetFilledPolysList().TotalVertices();
|
|
||||||
else
|
|
||||||
return ref->GetNetCode() < tst->GetNetCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Test_Connection_To_Copper_Areas
|
|
||||||
* init .m_ZoneSubnet parameter in tracks and pads according to the connections to areas found
|
|
||||||
* @param aNetcode = netcode to analyse. if -1, analyse all nets
|
|
||||||
*/
|
|
||||||
void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
|
|
||||||
{
|
|
||||||
// list of pads and tracks candidates on this layer and on this net.
|
|
||||||
// It is static to avoid multiple memory realloc.
|
|
||||||
static std::vector <BOARD_CONNECTED_ITEM*> candidates;
|
|
||||||
|
|
||||||
// clear .m_ZoneSubnet parameter for pads
|
|
||||||
for( MODULE* module = m_Modules; module; module = module->Next() )
|
|
||||||
{
|
|
||||||
for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
|
|
||||||
if( aNetcode < 0 || aNetcode == pad->GetNetCode() )
|
|
||||||
pad->SetZoneSubNet( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear .m_ZoneSubnet parameter for tracks and vias
|
|
||||||
for( TRACK* track = m_Track; track; track = track->Next() )
|
|
||||||
{
|
|
||||||
if( aNetcode < 0 || aNetcode == track->GetNetCode() )
|
|
||||||
track->SetZoneSubNet( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// examine all zones, net by net:
|
|
||||||
int subnet = 0;
|
|
||||||
|
|
||||||
// Build zones candidates list
|
|
||||||
std::vector<ZONE_CONTAINER*> zones_candidates;
|
|
||||||
|
|
||||||
zones_candidates.reserve( GetAreaCount() );
|
|
||||||
|
|
||||||
for( int index = 0; index < GetAreaCount(); index++ )
|
|
||||||
{
|
|
||||||
ZONE_CONTAINER* zone = GetArea( index );
|
|
||||||
|
|
||||||
if( !zone->IsOnCopperLayer() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( aNetcode >= 0 && aNetcode != zone->GetNetCode() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( zone->GetFilledPolysList().IsEmpty() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
zones_candidates.push_back( zone );
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort them by netcode then vertices count.
|
|
||||||
// For a given net, examine the smaller zones first slightly speed up calculation
|
|
||||||
// (25% faster)
|
|
||||||
// this is only noticeable with very large boards and depends on board zones topology
|
|
||||||
// This is due to the fact some items are connected by small zones ares,
|
|
||||||
// before examining large zones areas and these items are not tested after a connection is found
|
|
||||||
sort( zones_candidates.begin(), zones_candidates.end(), sort_areas );
|
|
||||||
|
|
||||||
int oldnetcode = -1;
|
|
||||||
for( unsigned idx = 0; idx < zones_candidates.size(); idx++ )
|
|
||||||
{
|
|
||||||
ZONE_CONTAINER* zone = zones_candidates[idx];
|
|
||||||
|
|
||||||
int netcode = zone->GetNetCode();
|
|
||||||
|
|
||||||
// Build a list of candidates connected to the net:
|
|
||||||
// At this point, layers are not considered, because areas on different layers can
|
|
||||||
// be connected by a via or a pad.
|
|
||||||
// (because zones are sorted by netcode, there is made only once per net)
|
|
||||||
NETINFO_ITEM* net = FindNet( netcode );
|
|
||||||
|
|
||||||
wxASSERT( net );
|
|
||||||
if( net == NULL )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( oldnetcode != netcode )
|
|
||||||
{
|
|
||||||
oldnetcode = netcode;
|
|
||||||
candidates.clear();
|
|
||||||
|
|
||||||
// Build the list of pads candidates connected to the net:
|
|
||||||
candidates.reserve( net->m_PadInNetList.size() );
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ )
|
|
||||||
candidates.push_back( net->m_PadInNetList[ii] );
|
|
||||||
|
|
||||||
// If we have any tracks...
|
|
||||||
if( m_Track.GetCount() > 0 )
|
|
||||||
{
|
|
||||||
// Build the list of track candidates connected to the net:
|
|
||||||
TRACK* track = m_Track.GetFirst()->GetStartNetCode( netcode );
|
|
||||||
|
|
||||||
for( ; track; track = track->Next() )
|
|
||||||
{
|
|
||||||
if( track->GetNetCode() != netcode )
|
|
||||||
break;
|
|
||||||
|
|
||||||
candidates.push_back( track );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// test if a candidate is inside a filled area of this zone
|
|
||||||
const SHAPE_POLY_SET& polysList = zone->GetFilledPolysList();
|
|
||||||
|
|
||||||
for( int outline = 0; outline < polysList.OutlineCount(); outline++ )
|
|
||||||
{
|
|
||||||
subnet++;
|
|
||||||
|
|
||||||
for( unsigned ic = 0; ic < candidates.size(); ic++ )
|
|
||||||
{
|
|
||||||
// test if this area is connected to a board item:
|
|
||||||
BOARD_CONNECTED_ITEM* item = candidates[ic];
|
|
||||||
|
|
||||||
if( item->GetZoneSubNet() == subnet ) // Already merged
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( !item->IsOnLayer( zone->GetLayer() ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
wxPoint pos1, pos2;
|
|
||||||
|
|
||||||
if( item->Type() == PCB_PAD_T )
|
|
||||||
{
|
|
||||||
// For pads we use the shape position instead of
|
|
||||||
// the pad position, because the zones are connected
|
|
||||||
// to the center of the shape, not the pad position
|
|
||||||
// (this is important for pads with thermal relief)
|
|
||||||
pos1 = pos2 = ( (D_PAD*) item )->ShapePos();
|
|
||||||
}
|
|
||||||
else if( item->Type() == PCB_VIA_T )
|
|
||||||
{
|
|
||||||
const VIA *via = static_cast<const VIA*>( item );
|
|
||||||
pos1 = via->GetStart();
|
|
||||||
pos2 = pos1;
|
|
||||||
}
|
|
||||||
else if( item->Type() == PCB_TRACE_T )
|
|
||||||
{
|
|
||||||
const TRACK *trk = static_cast<const TRACK*>( item );
|
|
||||||
pos1 = trk->GetStart();
|
|
||||||
pos2 = trk->GetEnd();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool connected = false;
|
|
||||||
|
|
||||||
if( polysList.Contains( VECTOR2I( pos1.x, pos1.y ), outline ) )
|
|
||||||
connected = true;
|
|
||||||
|
|
||||||
if( !connected && ( pos1 != pos2 ) )
|
|
||||||
{
|
|
||||||
if( polysList.Contains( VECTOR2I( pos2.x, pos2.y ), outline ) )
|
|
||||||
connected = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( connected )
|
|
||||||
{
|
|
||||||
// Set ZoneSubnet to the current subnet value.
|
|
||||||
// If the previous subnet is not 0, merge all items with old subnet
|
|
||||||
// to the new one
|
|
||||||
int old_subnet = item->GetZoneSubNet();
|
|
||||||
item->SetZoneSubNet( subnet );
|
|
||||||
|
|
||||||
// Merge previous subnet with the current
|
|
||||||
if( (old_subnet > 0) && (old_subnet != subnet) )
|
|
||||||
{
|
|
||||||
for( unsigned jj = 0; jj < candidates.size(); jj++ )
|
|
||||||
{
|
|
||||||
BOARD_CONNECTED_ITEM* item_to_merge = candidates[jj];
|
|
||||||
|
|
||||||
if( old_subnet == item_to_merge->GetZoneSubNet() )
|
|
||||||
{
|
|
||||||
item_to_merge->SetZoneSubNet( subnet );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // End if ( old_subnet > 0 )
|
|
||||||
} // End if( connected )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // End read all zones candidates
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb)
|
|
||||||
* Calls Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ) for each
|
|
||||||
* netcode found in zone list
|
|
||||||
* @param aPcb = the current board
|
|
||||||
*/
|
|
||||||
void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb )
|
|
||||||
{
|
|
||||||
for( int index = 0; index < aPcb->GetAreaCount(); index++ )
|
|
||||||
{
|
|
||||||
ZONE_CONTAINER* zone = aPcb->GetArea( index );
|
|
||||||
|
|
||||||
if ( ! zone->IsOnCopperLayer() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( zone->GetNetCode() <= 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Merge_SubNets_Connected_By_CopperAreas( aPcb, zone->GetNetCode() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb, int aNetcode)
|
|
||||||
* Used after connections by tracks calculations
|
|
||||||
* Merge subnets, in tracks ans pads when they are connected by a filled copper area
|
|
||||||
* for pads, this is the .m_physical_connexion member which is tested and modified
|
|
||||||
* for tracks, this is the .m_Subnet member which is tested and modified
|
|
||||||
* these members are block numbers (or cluster numbers) for a given net,
|
|
||||||
* calculated by Build_Pads_Info_Connections_By_Tracks()
|
|
||||||
* The result is merging 2 blocks (or subnets)
|
|
||||||
* @param aPcb = the current board
|
|
||||||
* @param aNetcode = netcode to consider
|
|
||||||
*/
|
|
||||||
void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode )
|
|
||||||
{
|
|
||||||
// Ensure a zone with the given netcode exists: examine all zones:
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for( int index = 0; index < aPcb->GetAreaCount(); index++ )
|
|
||||||
{
|
|
||||||
ZONE_CONTAINER* zone = aPcb->GetArea( index );
|
|
||||||
|
|
||||||
if( aNetcode == zone->GetNetCode() )
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !found ) // No zone with this netcode, therefore no connection by zone
|
|
||||||
return;
|
|
||||||
|
|
||||||
// list of pads and tracks candidates to test:
|
|
||||||
// It is static to avoid multiple memory realloc.
|
|
||||||
static std::vector <BOARD_CONNECTED_ITEM*> Candidates;
|
|
||||||
Candidates.clear();
|
|
||||||
|
|
||||||
// Build the list of pads candidates connected to the net:
|
|
||||||
NETINFO_ITEM* net = aPcb->FindNet( aNetcode );
|
|
||||||
wxASSERT( net );
|
|
||||||
Candidates.reserve( net->m_PadInNetList.size() );
|
|
||||||
for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ )
|
|
||||||
Candidates.push_back( net->m_PadInNetList[ii] );
|
|
||||||
|
|
||||||
// Build the list of track candidates connected to the net:
|
|
||||||
TRACK* track;
|
|
||||||
|
|
||||||
if( aPcb->m_Track.GetCount() > 0 )
|
|
||||||
{
|
|
||||||
track = aPcb->m_Track.GetFirst()->GetStartNetCode( aNetcode );
|
|
||||||
|
|
||||||
for( ; track; track = track->Next() )
|
|
||||||
{
|
|
||||||
if( track->GetNetCode() != aNetcode )
|
|
||||||
break;
|
|
||||||
|
|
||||||
Candidates.push_back( track );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Candidates.size() == 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
int next_subnet_free_number = 0;
|
|
||||||
for( unsigned ii = 0; ii < Candidates.size(); ii++ )
|
|
||||||
{
|
|
||||||
int subnet = Candidates[ii]->GetSubNet();
|
|
||||||
next_subnet_free_number = std::max( next_subnet_free_number, subnet );
|
|
||||||
}
|
|
||||||
|
|
||||||
next_subnet_free_number++; // This is a subnet we can use with not connected items
|
|
||||||
// by tracks, but connected by zone.
|
|
||||||
|
|
||||||
// Sort by zone_subnet:
|
|
||||||
sort( Candidates.begin(), Candidates.end(), CmpZoneSubnetValue );
|
|
||||||
|
|
||||||
// Some items can be not connected, but they can be connected to a filled area:
|
|
||||||
// give them a subnet common to these items connected only by the area,
|
|
||||||
// and not already used.
|
|
||||||
// a value like next_subnet_free_number+zone_subnet is right
|
|
||||||
for( unsigned jj = 0; jj < Candidates.size(); jj++ )
|
|
||||||
{
|
|
||||||
BOARD_CONNECTED_ITEM* item = Candidates[jj];
|
|
||||||
if ( item->GetSubNet() == 0 && (item->GetZoneSubNet() > 0) )
|
|
||||||
{
|
|
||||||
item->SetSubNet( next_subnet_free_number + item->GetZoneSubNet() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now, for each zone subnet, we search for 2 items with different subnets.
|
|
||||||
// if found, the 2 subnet are merged in the whole candidate list.
|
|
||||||
int old_subnet = 0;
|
|
||||||
int old_zone_subnet = 0;
|
|
||||||
for( unsigned ii = 0; ii < Candidates.size(); ii++ )
|
|
||||||
{
|
|
||||||
BOARD_CONNECTED_ITEM* item = Candidates[ii];
|
|
||||||
int zone_subnet = item->GetZoneSubNet();
|
|
||||||
|
|
||||||
if( zone_subnet == 0 ) // Not connected by a filled area, skip it
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int subnet = item->GetSubNet();
|
|
||||||
|
|
||||||
if( zone_subnet != old_zone_subnet ) // a new zone subnet is found
|
|
||||||
{
|
|
||||||
old_subnet = subnet;
|
|
||||||
old_zone_subnet = zone_subnet;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2 successive items already from the same cluster: nothing to do
|
|
||||||
if( subnet == old_subnet )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Here we have 2 items connected by the same area have 2 differents subnets: merge subnets
|
|
||||||
if( (subnet > old_subnet) || ( subnet <= 0) )
|
|
||||||
std::swap( subnet, old_subnet );
|
|
||||||
|
|
||||||
for( unsigned jj = 0; jj < Candidates.size(); jj++ )
|
|
||||||
{
|
|
||||||
BOARD_CONNECTED_ITEM * item_to_merge = Candidates[jj];
|
|
||||||
|
|
||||||
if( item_to_merge->GetSubNet() == old_subnet )
|
|
||||||
item_to_merge->SetSubNet( subnet );
|
|
||||||
}
|
|
||||||
|
|
||||||
old_subnet = subnet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Compare function used for sorting candidates by increasing zone subnet
|
|
||||||
*/
|
|
||||||
static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b )
|
|
||||||
{
|
|
||||||
int asubnet, bsubnet;
|
|
||||||
|
|
||||||
asubnet = a->GetZoneSubNet();
|
|
||||||
bsubnet = b->GetZoneSubNet();
|
|
||||||
|
|
||||||
return asubnet < bsubnet;
|
|
||||||
}
|
|
Loading…
Reference in New Issue