KiCad PCB EDA Suite
connect.cpp File Reference

Functions to handle existing tracks in ratsnest calculations. More...

#include <fctsys.h>
#include <common.h>
#include <macros.h>
#include <wxBasePcbFrame.h>
#include <view/view.h>
#include <pcbnew.h>
#include <connect.h>

Go to the source code of this file.

Macros

#define USE_EXTENDED_SEARCH
 

Functions

void Merge_SubNets_Connected_By_CopperAreas (BOARD *aPcb)
 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. More...
 
void Merge_SubNets_Connected_By_CopperAreas (BOARD *aPcb, int aNetcode)
 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) More...
 
static void RebuildTrackChain (BOARD *pcb)
 Helper function RebuildTrackChain rebuilds the track segment linked list in order to have a chain sorted by increasing netcodes. More...
 
static bool sortConnectedPointByXthenYCoordinates (const CONNECTED_POINT &aRef, const CONNECTED_POINT &aTst)
 
static bool SortTracksByNetCode (const TRACK *const &ref, const TRACK *const &compare)
 

Detailed Description

Functions to handle existing tracks in ratsnest calculations.

Definition in file connect.cpp.

Macro Definition Documentation

#define USE_EXTENDED_SEARCH

Function Documentation

void Merge_SubNets_Connected_By_CopperAreas ( BOARD aPcb)

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.

Parameters
aPcb= the current board

Definition at line 252 of file zones_polygons_test_connections.cpp.

References BOARD::GetArea(), BOARD::GetAreaCount(), BOARD_CONNECTED_ITEM::GetNetCode(), ZONE_CONTAINER::IsOnCopperLayer(), and Merge_SubNets_Connected_By_CopperAreas().

Referenced by PCB_BASE_FRAME::TestConnections(), and PCB_BASE_FRAME::TestNetConnection().

253 {
254  for( int index = 0; index < aPcb->GetAreaCount(); index++ )
255  {
256  ZONE_CONTAINER* zone = aPcb->GetArea( index );
257 
258  if ( ! zone->IsOnCopperLayer() )
259  continue;
260 
261  if ( zone->GetNetCode() <= 0 )
262  continue;
263 
265  }
266 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
void Merge_SubNets_Connected_By_CopperAreas(BOARD *aPcb, int aNetcode)
Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb, int aNetcode) Used after connections by ...
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1051
int GetNetCode() const
Function GetNetCode.
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.h:179
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:1022
void Merge_SubNets_Connected_By_CopperAreas ( BOARD aPcb,
int  aNetcode 
)

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)

Parameters
aPcb= the current board
aNetcode= netcode to consider

Definition at line 281 of file zones_polygons_test_connections.cpp.

References CmpZoneSubnetValue(), BOARD::FindNet(), BOARD::GetArea(), BOARD::GetAreaCount(), DHEAD::GetCount(), DLIST< T >::GetFirst(), BOARD_CONNECTED_ITEM::GetNetCode(), TRACK::GetStartNetCode(), BOARD_CONNECTED_ITEM::GetSubNet(), BOARD_CONNECTED_ITEM::GetZoneSubNet(), NETINFO_ITEM::m_PadInNetList, BOARD::m_Track, max, TRACK::Next(), and BOARD_CONNECTED_ITEM::SetSubNet().

Referenced by Merge_SubNets_Connected_By_CopperAreas().

282 {
283  // Ensure a zone with the given netcode exists: examine all zones:
284  bool found = false;
285 
286  for( int index = 0; index < aPcb->GetAreaCount(); index++ )
287  {
288  ZONE_CONTAINER* zone = aPcb->GetArea( index );
289 
290  if( aNetcode == zone->GetNetCode() )
291  {
292  found = true;
293  break;
294  }
295  }
296 
297  if( !found ) // No zone with this netcode, therefore no connection by zone
298  return;
299 
300  // list of pads and tracks candidates to test:
301  // It is static to avoid multiple memory realloc.
302  static std::vector <BOARD_CONNECTED_ITEM*> Candidates;
303  Candidates.clear();
304 
305  // Build the list of pads candidates connected to the net:
306  NETINFO_ITEM* net = aPcb->FindNet( aNetcode );
307  wxASSERT( net );
308  Candidates.reserve( net->m_PadInNetList.size() );
309  for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ )
310  Candidates.push_back( net->m_PadInNetList[ii] );
311 
312  // Build the list of track candidates connected to the net:
313  TRACK* track;
314 
315  if( aPcb->m_Track.GetCount() > 0 )
316  {
317  track = aPcb->m_Track.GetFirst()->GetStartNetCode( aNetcode );
318 
319  for( ; track; track = track->Next() )
320  {
321  if( track->GetNetCode() != aNetcode )
322  break;
323 
324  Candidates.push_back( track );
325  }
326  }
327 
328  if( Candidates.size() == 0 )
329  return;
330 
331  int next_subnet_free_number = 0;
332  for( unsigned ii = 0; ii < Candidates.size(); ii++ )
333  {
334  int subnet = Candidates[ii]->GetSubNet();
335  next_subnet_free_number = std::max( next_subnet_free_number, subnet );
336  }
337 
338  next_subnet_free_number++; // This is a subnet we can use with not connected items
339  // by tracks, but connected by zone.
340 
341  // Sort by zone_subnet:
342  sort( Candidates.begin(), Candidates.end(), CmpZoneSubnetValue );
343 
344  // Some items can be not connected, but they can be connected to a filled area:
345  // give them a subnet common to these items connected only by the area,
346  // and not already used.
347  // a value like next_subnet_free_number+zone_subnet is right
348  for( unsigned jj = 0; jj < Candidates.size(); jj++ )
349  {
350  BOARD_CONNECTED_ITEM* item = Candidates[jj];
351  if ( item->GetSubNet() == 0 && (item->GetZoneSubNet() > 0) )
352  {
353  item->SetSubNet( next_subnet_free_number + item->GetZoneSubNet() );
354  }
355  }
356 
357  // Now, for each zone subnet, we search for 2 items with different subnets.
358  // if found, the 2 subnet are merged in the whole candidate list.
359  int old_subnet = 0;
360  int old_zone_subnet = 0;
361  for( unsigned ii = 0; ii < Candidates.size(); ii++ )
362  {
363  BOARD_CONNECTED_ITEM* item = Candidates[ii];
364  int zone_subnet = item->GetZoneSubNet();
365 
366  if( zone_subnet == 0 ) // Not connected by a filled area, skip it
367  continue;
368 
369  int subnet = item->GetSubNet();
370 
371  if( zone_subnet != old_zone_subnet ) // a new zone subnet is found
372  {
373  old_subnet = subnet;
374  old_zone_subnet = zone_subnet;
375  continue;
376  }
377 
378  // 2 successive items already from the same cluster: nothing to do
379  if( subnet == old_subnet )
380  continue;
381 
382  // Here we have 2 items connected by the same area have 2 differents subnets: merge subnets
383  if( (subnet > old_subnet) || ( subnet <= 0) )
384  std::swap( subnet, old_subnet );
385 
386  for( unsigned jj = 0; jj < Candidates.size(); jj++ )
387  {
388  BOARD_CONNECTED_ITEM * item_to_merge = Candidates[jj];
389 
390  if( item_to_merge->GetSubNet() == old_subnet )
391  item_to_merge->SetSubNet( subnet );
392  }
393 
394  old_subnet = subnet;
395  }
396 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
D_PADS m_PadInNetList
List of pads connected to this net.
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
static bool CmpZoneSubnetValue(const BOARD_CONNECTED_ITEM *a, const BOARD_CONNECTED_ITEM *b)
int GetZoneSubNet() const
Function GetZoneSubNet.
T * GetFirst() const
Function GetFirst returns the first T* in the list without removing it, or NULL if the list is empty...
Definition: dlist.h:163
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1051
void SetSubNet(int aSubNetCode)
int GetNetCode() const
Function GetNetCode.
Class NETINFO_ITEM handles the data for a net.
TRACK * Next() const
Definition: class_track.h:98
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:1022
TRACK * GetStartNetCode(int NetCode)
#define max(a, b)
Definition: auxiliary.h:86
int GetSubNet() const
Function GetSubNet.
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
DLIST< TRACK > m_Track
Definition: class_board.h:244
static void RebuildTrackChain ( BOARD pcb)
static

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

Parameters
pcb= board to rebuild

Definition at line 981 of file connect.cpp.

References DHEAD::GetCount(), TRACK::m_Param, BOARD::m_Track, DLIST< T >::PopFront(), DLIST< T >::PushBack(), and SortTracksByNetCode().

Referenced by PCB_BASE_FRAME::RecalculateAllTracksNetcode().

982 {
983  if( pcb->m_Track == NULL )
984  return;
985 
986  int item_count = pcb->m_Track.GetCount();
987 
988  std::vector<TRACK*> trackList;
989  trackList.reserve( item_count );
990 
991  // Put track list in a temporary list to sort tracks by netcode
992  // We try to keep the initial order of track segments in list, when possible
993  // so we use m_Param (a member variable used for temporary storage)
994  // to temporary keep trace of the order of segments
995  // The sort function uses this variable to sort items that
996  // have the same net code.
997  // Without this, during sorting, the initial order is sometimes lost
998  // by the sort algorithm
999  for( int ii = 0; ii < item_count; ++ii )
1000  {
1001  pcb->m_Track->m_Param = ii;
1002  trackList.push_back( pcb->m_Track.PopFront() );
1003  }
1004 
1005  // the list is empty now
1006  wxASSERT( pcb->m_Track == NULL && pcb->m_Track.GetCount()==0 );
1007 
1008  sort( trackList.begin(), trackList.end(), SortTracksByNetCode );
1009 
1010  // add them back to the list
1011  for( int i = 0; i < item_count; ++i )
1012  pcb->m_Track.PushBack( trackList[i] );
1013 }
double m_Param
Definition: class_track.h:92
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
static bool SortTracksByNetCode(const TRACK *const &ref, const TRACK *const &compare)
Definition: connect.cpp:965
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
DLIST< TRACK > m_Track
Definition: class_board.h:244
T * PopFront()
Definition: dlist.h:221
static bool sortConnectedPointByXthenYCoordinates ( const CONNECTED_POINT aRef,
const CONNECTED_POINT aTst 
)
static

Definition at line 244 of file connect.cpp.

References CONNECTED_POINT::GetPoint(), wxPoint::x, and wxPoint::y.

Referenced by CONNECTIONS::BuildTracksCandidatesList().

246 {
247  if( aRef.GetPoint().x == aTst.GetPoint().x )
248  return aRef.GetPoint().y < aTst.GetPoint().y;
249  return aRef.GetPoint().x < aTst.GetPoint().x;
250 }
const wxPoint & GetPoint() const
Definition: connect.h:87
static bool SortTracksByNetCode ( const TRACK *const &  ref,
const TRACK *const &  compare 
)
static

Definition at line 965 of file connect.cpp.

References BOARD_CONNECTED_ITEM::GetNetCode(), and TRACK::m_Param.

Referenced by RebuildTrackChain().

966 {
967  // For items having the same Net, keep the order in list
968  if( ref->GetNetCode() == compare->GetNetCode())
969  return ref->m_Param < compare->m_Param;
970 
971  return ref->GetNetCode() < compare->GetNetCode();
972 }
double m_Param
Definition: class_track.h:92
int GetNetCode() const
Function GetNetCode.