KiCad PCB EDA Suite
class_board.cpp File Reference

BOARD class functions. More...

#include <limits.h>
#include <algorithm>
#include <fctsys.h>
#include <common.h>
#include <kicad_string.h>
#include <wxBasePcbFrame.h>
#include <msgpanel.h>
#include <pcb_netlist.h>
#include <reporter.h>
#include <base_units.h>
#include <ratsnest_data.h>
#include <ratsnest_viewitem.h>
#include <worksheet_viewitem.h>
#include <pcbnew.h>
#include <colors_selection.h>
#include <collectors.h>
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_zone.h>
#include <class_marker_pcb.h>
#include <class_drawsegment.h>
#include <class_pcb_text.h>
#include <class_mire.h>
#include <class_dimension.h>
#include <stdio.h>

Go to the source code of this file.

Functions

static void removeTrack (TRACKS *aList, TRACK *aOneToRemove)
 Function removeTrack removes aOneToRemove from aList, which is a non-owning std::vector. More...
 
static void otherEnd (const TRACK &aTrack, const wxPoint &aNotThisEnd, wxPoint *aOtherEnd)
 
static int find_vias_and_tracks_at (TRACKS &at_next, TRACKS &in_net, LSET &lset, const wxPoint &next)
 Function find_vias_and_tracks_at collects TRACKs and VIAs at aPos and returns the track_count which excludes vias. More...
 
static void checkConnectedTo (BOARD *aBoard, TRACKS *aList, const TRACKS &aTracksInNet, const wxPoint &aGoal, const wxPoint &aStart, TRACK *aFirstTrack)
 Function checkConnectedTo returns if aTracksInNet contains a copper pathway to aGoal when starting with aFirstTrack. More...
 
static bool sortNetsByNodes (const NETINFO_ITEM *a, const NETINFO_ITEM *b)
 
static bool sortNetsByNames (const NETINFO_ITEM *a, const NETINFO_ITEM *b)
 
bool sortPadsByXthenYCoord (D_PAD *const &ref, D_PAD *const &comp)
 Function SortPadsByXCoord is used by GetSortedPadListByXCoord to Sort a pad list by x coordinate value. More...
 
bool BuildBoardPolygonOutlines (BOARD *aBoard, SHAPE_POLY_SET &aOutlines, wxString *aErrorText)
 

Detailed Description

BOARD class functions.

Definition in file class_board.cpp.

Function Documentation

bool BuildBoardPolygonOutlines ( BOARD aBoard,
SHAPE_POLY_SET aOutlines,
wxString *  aErrorText 
)

Definition at line 586 of file convert_drawsegment_list_to_polygon.cpp.

References SHAPE_POLY_SET::Append(), PCB_TYPE_COLLECTOR::Collect(), BOARD::ComputeBoundingBox(), ConvertOutlineToPolygon(), Edge_Cuts, EOT, BOARD::GetBoardEdgesBoundingBox(), COLLECTOR::GetCount(), EDA_RECT::GetEnd(), EDA_RECT::GetHeight(), GetLayer(), EDA_RECT::GetOrigin(), EDA_RECT::GetWidth(), EDA_RECT::Inflate(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::OutlineCount(), PCB_LINE_T, PCB_MODULE_EDGE_T, SHAPE_POLY_SET::RemoveAllContours(), wxPoint::x, and wxPoint::y.

Referenced by BOARD::GetBoardPolygonOutlines().

589 {
590  PCB_TYPE_COLLECTOR items;
591 
592  // Get all the DRAWSEGMENTS and module graphics into 'items',
593  // then keep only those on layer == Edge_Cuts.
594  static const KICAD_T scan_graphics[] = { PCB_LINE_T, PCB_MODULE_EDGE_T, EOT };
595  items.Collect( aBoard, scan_graphics );
596 
597  // Make a working copy of aSegList, because the list is modified during calculations
598  std::vector< DRAWSEGMENT* > segList;
599 
600  for( int ii = 0; ii < items.GetCount(); ii++ )
601  {
602  if( items[ii]->GetLayer() == Edge_Cuts )
603  segList.push_back( static_cast< DRAWSEGMENT* >( items[ii] ) );
604  }
605 
606  const int STEPS = 36; // for a segmentation of an arc of 360 degrees
607  bool success = ConvertOutlineToPolygon( segList, aOutlines, STEPS, aErrorText );
608 
609  if( !success || !aOutlines.OutlineCount() )
610  {
611  // Creates a valid polygon outline is not possible.
612  // So uses the board edge cuts bounding box to create a
613  // rectangular outline
614  // When no edge cuts items, build a contour
615  // from global bounding box
616 
617  EDA_RECT bbbox = aBoard->GetBoardEdgesBoundingBox();
618 
619  // If null area, uses the global bounding box.
620  if( ( bbbox.GetWidth() ) == 0 || ( bbbox.GetHeight() == 0 ) )
621  bbbox = aBoard->ComputeBoundingBox();
622 
623  // Ensure non null area. If happen, gives a minimal size.
624  if( ( bbbox.GetWidth() ) == 0 || ( bbbox.GetHeight() == 0 ) )
625  bbbox.Inflate( Millimeter2iu( 1.0 ) );
626 
627  aOutlines.RemoveAllContours();
628  aOutlines.NewOutline();
629 
630  wxPoint corner;
631  aOutlines.Append( bbbox.GetOrigin() );
632 
633  corner.x = bbbox.GetOrigin().x;
634  corner.y = bbbox.GetEnd().y;
635  aOutlines.Append( corner );
636 
637  aOutlines.Append( bbbox.GetEnd() );
638 
639  corner.x = bbbox.GetEnd().x;
640  corner.y = bbbox.GetOrigin().y;
641  aOutlines.Append( corner );
642  }
643 
644  return success;
645 }
int GetCount() const
Function GetCount returns the number of objects in the list.
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Function ComputeBoundingBox calculates the bounding box containing all board items (or board edge seg...
int GetHeight() const
int OutlineCount() const
Returns the number of outlines in the set
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
search types array terminator (End Of Types)
Definition: typeinfo.h:94
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:90
bool ConvertOutlineToPolygon(std::vector< DRAWSEGMENT * > &aSegList, SHAPE_POLY_SET &aPolygons, int aSegmentsByCircle, wxString *aErrorText)
Function ConvertOutlineToPolygon build a polygon (with holes) from a DRAWSEGMENT list, which is expected to be a outline, therefore a closed main outline with perhaps closed inner outlines.
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:839
const wxPoint & GetOrigin() const
int NewOutline()
Creates a new empty polygon in the set and returns its index
void Collect(BOARD_ITEM *aBoard, const KICAD_T aScanList[])
Function Collect scans a BOARD_ITEM using this class's Inspector method, which does the collection...
Definition: collectors.cpp:488
const wxPoint GetEnd() const
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
Class EDA_RECT handles the component boundary box.
int GetWidth() const
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
Class PCB_TYPE_COLLECTOR merely gathers up all BOARD_ITEMs of a given set of KICAD_T type(s)...
Definition: collectors.h:593
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline) ...
static void checkConnectedTo ( BOARD aBoard,
TRACKS *  aList,
const TRACKS &  aTracksInNet,
const wxPoint aGoal,
const wxPoint aStart,
TRACK aFirstTrack 
)
static

Function checkConnectedTo returns if aTracksInNet contains a copper pathway to aGoal when starting with aFirstTrack.

aFirstTrack should have one end situated on aStart, and the traversal testing begins from the other end of aFirstTrack.

The function throws an exception instead of returning bool so that detailed information can be provided about a possible failure in the track layout.

Exceptions
IO_ERROR- if points are not connected, with text saying why.

Definition at line 281 of file class_board.cpp.

References find_vias_and_tracks_at(), BOARD_ITEM::FormatInternalUnits(), BOARD_ITEM::GetLayer(), BOARD::GetPadFast(), next(), otherEnd(), removeTrack(), StrPrintf(), and THROW_IO_ERROR.

Referenced by BOARD::TracksInNetBetweenPoints().

283 {
284  TRACKS in_net = aTracksInNet; // copy source list so the copy can be modified
285  wxPoint next;
286 
287  otherEnd( *aFirstTrack, aStart, &next );
288 
289  aList->push_back( aFirstTrack );
290  removeTrack( &in_net, aFirstTrack );
291 
292  LSET lset( aFirstTrack->GetLayer() );
293 
294  while( in_net.size() )
295  {
296  if( next == aGoal )
297  return; // success
298 
299  // Want an exact match on the position of next, i.e. pad at next,
300  // not a forgiving HitTest() with tolerance type of match, otherwise the overall
301  // algorithm will not work. GetPadFast() is an exact match as I write this.
302  if( aBoard->GetPadFast( next, lset ) )
303  {
304  std::string m = StrPrintf(
305  "intervening pad at:(xy %s) between start:(xy %s) and goal:(xy %s)",
306  BOARD_ITEM::FormatInternalUnits( next ).c_str(),
307  BOARD_ITEM::FormatInternalUnits( aStart ).c_str(),
308  BOARD_ITEM::FormatInternalUnits( aGoal ).c_str()
309  );
310  THROW_IO_ERROR( m );
311  }
312 
313  int track_count = find_vias_and_tracks_at( *aList, in_net, lset, next );
314 
315  if( track_count != 1 )
316  {
317  std::string m = StrPrintf(
318  "found %d tracks intersecting at (xy %s), exactly 2 would be acceptable.",
319  track_count + aList->size() == 1 ? 1 : 0,
320  BOARD_ITEM::FormatInternalUnits( next ).c_str()
321  );
322  THROW_IO_ERROR( m );
323  }
324 
325  // reduce lset down to the layer that the last track at 'next' is on.
326  lset = aList->back()->GetLayerSet();
327 
328  otherEnd( *aList->back(), next, &next );
329  }
330 
331  std::string m = StrPrintf(
332  "not enough tracks connecting start:(xy %s) and goal:(xy %s).",
333  BOARD_ITEM::FormatInternalUnits( aStart ).c_str(),
334  BOARD_ITEM::FormatInternalUnits( aGoal ).c_str()
335  );
336  THROW_IO_ERROR( m );
337 }
CITER next(CITER it)
Definition: ptree.cpp:130
static void removeTrack(TRACKS *aList, TRACK *aOneToRemove)
Function removeTrack removes aOneToRemove from aList, which is a non-owning std::vector.
D_PAD * GetPadFast(const wxPoint &aPosition, LSET aLayerMask)
Function GetPadFast return pad found at aPosition on aLayerMask using the fast search method...
static void otherEnd(const TRACK &aTrack, const wxPoint &aNotThisEnd, wxPoint *aOtherEnd)
LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
static int find_vias_and_tracks_at(TRACKS &at_next, TRACKS &in_net, LSET &lset, const wxPoint &next)
Function find_vias_and_tracks_at collects TRACKs and VIAs at aPos and returns the track_count which e...
static std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from board internal units to a string appropriate for wr...
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
Class LSET is a set of LAYER_IDs.
#define THROW_IO_ERROR(x)
Definition: utf8.cpp:60
static int find_vias_and_tracks_at ( TRACKS &  at_next,
TRACKS &  in_net,
LSET lset,
const wxPoint next 
)
static

Function find_vias_and_tracks_at collects TRACKs and VIAs at aPos and returns the track_count which excludes vias.

Definition at line 229 of file class_board.cpp.

References TRACK::GetEnd(), BOARD_ITEM::GetLayerSet(), TRACK::GetStart(), next(), PCB_VIA_T, and EDA_ITEM::Type().

Referenced by checkConnectedTo().

230 {
231  // first find all vias (in this net) at 'next' location, and expand LSET with each
232  for( TRACKS::iterator it = in_net.begin(); it != in_net.end(); )
233  {
234  TRACK* t = *it;
235 
236  if( t->Type() == PCB_VIA_T && (t->GetLayerSet() & lset).any() &&
237  ( t->GetStart() == next || t->GetEnd() == next ) )
238  {
239  lset |= t->GetLayerSet();
240  at_next.push_back( t );
241  it = in_net.erase( it );
242  }
243  else
244  ++it;
245  }
246 
247  int track_count = 0;
248 
249  // with expanded lset, find all tracks with an end on any of the layers in lset
250  for( TRACKS::iterator it = in_net.begin(); it != in_net.end(); /* iterates in the loop body */ )
251  {
252  TRACK* t = *it;
253 
254  if( ( t->GetLayerSet() & lset ).any() && ( t->GetStart() == next || t->GetEnd() == next ) )
255  {
256  at_next.push_back( t );
257  it = in_net.erase( it );
258  ++track_count;
259  }
260  else
261  {
262  ++it;
263  }
264  }
265 
266  return track_count;
267 }
CITER next(CITER it)
Definition: ptree.cpp:130
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
const wxPoint & GetEnd() const
Definition: class_track.h:117
const wxPoint & GetStart() const
Definition: class_track.h:120
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
static void otherEnd ( const TRACK aTrack,
const wxPoint aNotThisEnd,
wxPoint aOtherEnd 
)
static

Definition at line 211 of file class_board.cpp.

References TRACK::GetEnd(), and TRACK::GetStart().

Referenced by checkConnectedTo().

212 {
213  if( aTrack.GetStart() == aNotThisEnd )
214  {
215  *aOtherEnd = aTrack.GetEnd();
216  }
217  else
218  {
219  wxASSERT( aTrack.GetEnd() == aNotThisEnd );
220  *aOtherEnd = aTrack.GetStart();
221  }
222 }
const wxPoint & GetEnd() const
Definition: class_track.h:117
const wxPoint & GetStart() const
Definition: class_track.h:120
static void removeTrack ( TRACKS *  aList,
TRACK aOneToRemove 
)
static

Function removeTrack removes aOneToRemove from aList, which is a non-owning std::vector.

Definition at line 205 of file class_board.cpp.

Referenced by checkConnectedTo().

206 {
207  aList->erase( std::remove( aList->begin(), aList->end(), aOneToRemove ), aList->end() );
208 }
static bool sortNetsByNames ( const NETINFO_ITEM a,
const NETINFO_ITEM b 
)
static

Definition at line 1438 of file class_board.cpp.

References NETINFO_ITEM::GetNetname().

Referenced by BOARD::SortedNetnamesList().

1439 {
1440  return a->GetNetname() < b->GetNetname();
1441 }
const wxString & GetNetname() const
Function GetNetname.
static bool sortNetsByNodes ( const NETINFO_ITEM a,
const NETINFO_ITEM b 
)
static

Definition at line 1429 of file class_board.cpp.

References NETINFO_ITEM::GetNetname(), and NETINFO_ITEM::GetNodesCount().

Referenced by BOARD::SortedNetnamesList().

1430 {
1431  if( b->GetNodesCount() == a->GetNodesCount() )
1432  return a->GetNetname() < b->GetNetname();
1433 
1434  return b->GetNodesCount() < a->GetNodesCount();
1435 }
int GetNodesCount() const
Function GetNodesCount.
const wxString & GetNetname() const
Function GetNetname.
bool sortPadsByXthenYCoord ( D_PAD *const &  ref,
D_PAD *const &  comp 
)

Function SortPadsByXCoord is used by GetSortedPadListByXCoord to Sort a pad list by x coordinate value.

This function is used to build ordered pads lists

Definition at line 1737 of file class_board.cpp.

References D_PAD::GetPosition(), wxPoint::x, and wxPoint::y.

Referenced by DRAG_LIST::BuildDragListe(), and BOARD::GetSortedPadListByXthenYCoord().

1738 {
1739  if( ref->GetPosition().x == comp->GetPosition().x )
1740  return ref->GetPosition().y < comp->GetPosition().y;
1741  return ref->GetPosition().x < comp->GetPosition().x;
1742 }
const wxPoint & GetPosition() const override
Definition: class_pad.h:170