KiCad PCB EDA Suite
auto_place_footprints.cpp File Reference

Functions to automatically place Footprints on a board. More...

#include <fctsys.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <gr_basic.h>
#include <macros.h>
#include <msgpanel.h>
#include <autorout.h>
#include <cell.h>
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_drawsegment.h>
#include <convert_to_biu.h>
#include <base_units.h>
#include <protos.h>

Go to the source code of this file.

Macros

#define GAIN   16
 
#define KEEP_OUT_MARGIN   500
 
#define OUT_OF_BOARD   -2
 
#define OCCUPED_By_MODULE   -1
 
#define FREE_CELL   0
 
#define NO_CELL_ZONE   (HOLE | CELL_is_EDGE | CELL_is_ZONE)
 

Functions

int genPlacementRoutingMatrix (BOARD *aBrd, EDA_MSG_PANEL *messagePanel)
 
static int getOptimalModulePlacement (PCB_EDIT_FRAME *aFrame, MODULE *aModule, wxDC *aDC)
 
static double compute_Ratsnest_PlaceModule (BOARD *aBrd)
 
void genModuleOnRoutingMatrix (MODULE *Module)
 
static void drawPlacementRoutingMatrix (BOARD *aBrd, wxDC *DC)
 
static int TstModuleOnBoard (BOARD *Pcb, MODULE *Module, bool TstOtherSide)
 
static void CreateKeepOutRectangle (int ux0, int uy0, int ux1, int uy1, int marge, int aKeepOut, LSET aLayerMask)
 Function CreateKeepOutRectangle builds the cost map: Cells ( in Dist map ) inside the rect x0,y0 a x1,y1 are incremented by value aKeepOut Cell outside this rectangle, but inside the rectangle x0,y0 -marge to x1,y1 + marge are incremented by a decreasing value (aKeepOut ... More...
 
static MODULEPickModule (PCB_EDIT_FRAME *pcbframe, wxDC *DC)
 Function PickModule find the "best" module place The criteria are: More...
 
static int propagate ()
 Function propagate Used only in autoplace calculations Uses the routing matrix to fill the cells within the zone Search and mark cells within the zone, and agree with DRC options. More...
 
void draw_FootprintRect (EDA_RECT *aClipBox, wxDC *aDC, EDA_RECT &fpBBox, COLOR4D aColor)
 
int TstRectangle (BOARD *Pcb, const EDA_RECT &aRect, int side)
 
unsigned int CalculateKeepOutArea (const EDA_RECT &aRect, int side)
 
static bool Tri_PlaceModules (MODULE *ref, MODULE *compare)
 
static bool sortFootprintsByRatsnestSize (MODULE *ref, MODULE *compare)
 

Variables

static const double OrientPenality [11]
 
static wxPoint CurrPosition
 
double MinCout
 

Detailed Description

Functions to automatically place Footprints on a board.

Definition in file auto_place_footprints.cpp.

Macro Definition Documentation

#define FREE_CELL   0

Definition at line 79 of file auto_place_footprints.cpp.

Referenced by TstModuleOnBoard(), and TstRectangle().

#define GAIN   16

Definition at line 54 of file auto_place_footprints.cpp.

Referenced by genModuleOnRoutingMatrix(), and TstModuleOnBoard().

#define KEEP_OUT_MARGIN   500

Definition at line 55 of file auto_place_footprints.cpp.

Referenced by genModuleOnRoutingMatrix().

#define NO_CELL_ZONE   (HOLE | CELL_is_EDGE | CELL_is_ZONE)

Referenced by propagate().

#define OCCUPED_By_MODULE   -1

Definition at line 78 of file auto_place_footprints.cpp.

Referenced by TstRectangle().

#define OUT_OF_BOARD   -2

Definition at line 77 of file auto_place_footprints.cpp.

Referenced by TstRectangle().

Function Documentation

unsigned int CalculateKeepOutArea ( const EDA_RECT aRect,
int  side 
)

Definition at line 815 of file auto_place_footprints.cpp.

References MATRIX_ROUTING_HEAD::GetDist(), EDA_RECT::GetEnd(), EDA_RECT::GetOrigin(), MATRIX_ROUTING_HEAD::m_BrdBox, MATRIX_ROUTING_HEAD::m_GridRouting, MATRIX_ROUTING_HEAD::m_Ncols, MATRIX_ROUTING_HEAD::m_Nrows, RoutingMatrix, wxPoint::x, and wxPoint::y.

Referenced by TstModuleOnBoard().

816 {
817  wxPoint start = aRect.GetOrigin();
818  wxPoint end = aRect.GetEnd();
819 
820  start -= RoutingMatrix.m_BrdBox.GetOrigin();
822 
823  int row_min = start.y / RoutingMatrix.m_GridRouting;
824  int row_max = end.y / RoutingMatrix.m_GridRouting;
825  int col_min = start.x / RoutingMatrix.m_GridRouting;
826  int col_max = end.x / RoutingMatrix.m_GridRouting;
827 
828  if( start.y > row_min * RoutingMatrix.m_GridRouting )
829  row_min++;
830 
831  if( start.x > col_min * RoutingMatrix.m_GridRouting )
832  col_min++;
833 
834  if( row_min < 0 )
835  row_min = 0;
836 
837  if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
838  row_max = RoutingMatrix.m_Nrows - 1;
839 
840  if( col_min < 0 )
841  col_min = 0;
842 
843  if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
844  col_max = RoutingMatrix.m_Ncols - 1;
845 
846  unsigned int keepOutCost = 0;
847 
848  for( int row = row_min; row <= row_max; row++ )
849  {
850  for( int col = col_min; col <= col_max; col++ )
851  {
852  // RoutingMatrix.GetDist returns the "cost" of the cell
853  // at position (row, col)
854  // in autoplace this is the cost of the cell, if it is
855  // inside aRect
856  keepOutCost += RoutingMatrix.GetDist( row, col, side );
857  }
858  }
859 
860  return keepOutCost;
861 }
const wxPoint GetOrigin() const
DIST_CELL GetDist(int aRow, int aCol, int aSide)
const wxPoint GetEnd() const
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
EDA_RECT m_BrdBox
Definition: autorout.h:115
double compute_Ratsnest_PlaceModule ( BOARD aBrd)
static

Definition at line 901 of file auto_place_footprints.cpp.

References abs, EDA_RECT::Contains(), g_Offset_Module, BOARD_ITEM::GetParent(), MODULE::GetPosition(), LOCAL_RATSNEST_ITEM, MATRIX_ROUTING_HEAD::m_BrdBox, BOARD::m_Status_Pcb, RATSNEST_ITEM_LOCAL_OK, RoutingMatrix, wxPoint::x, and wxPoint::y.

Referenced by getOptimalModulePlacement().

902 {
903  double curr_cost;
904  wxPoint start; // start point of a ratsnest
905  wxPoint end; // end point of a ratsnest
906  int dx, dy;
907 
908  if( ( aBrd->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK ) == 0 )
909  return -1;
910 
911  curr_cost = 0;
912 
913  for( unsigned ii = 0; ii < aBrd->m_LocalRatsnest.size(); ii++ )
914  {
915  RATSNEST_ITEM* pt_local_rats_nest = &aBrd->m_LocalRatsnest[ii];
916 
917  if( ( pt_local_rats_nest->m_Status & LOCAL_RATSNEST_ITEM ) )
918  continue; // Skip ratsnest between 2 pads of the current module
919 
920  // Skip modules not inside the board area
921  MODULE* module = pt_local_rats_nest->m_PadEnd->GetParent();
922 
923  if( !RoutingMatrix.m_BrdBox.Contains( module->GetPosition() ) )
924  continue;
925 
926  start = pt_local_rats_nest->m_PadStart->GetPosition() - g_Offset_Module;
927  end = pt_local_rats_nest->m_PadEnd->GetPosition();
928 
929  // Cost of the ratsnest.
930  dx = end.x - start.x;
931  dy = end.y - start.y;
932 
933  dx = abs( dx );
934  dy = abs( dy );
935 
936  // ttry to have always dx >= dy to calculate the cost of the rastsnet
937  if( dx < dy )
938  std::swap( dx, dy );
939 
940  // Cost of the connection = length + penalty due to the slope
941  // dx is the biggest length relative to the X or Y axis
942  // the penalty is max for 45 degrees ratsnests,
943  // and 0 for horizontal or vertical ratsnests.
944  // For Horizontal and Vertical ratsnests, dy = 0;
945  double conn_cost = hypot( dx, dy * 2.0 );
946  curr_cost += conn_cost; // Total cost = sum of costs of each connection
947  }
948 
949  return curr_cost;
950 }
BOARD_ITEM_CONTAINER * GetParent() const
wxPoint g_Offset_Module
Definition: pcbnew.cpp:73
bool Contains(const wxPoint &aPoint) const
Function Contains.
const wxPoint & GetPosition() const override
Definition: class_module.h:175
#define abs(a)
Definition: auxiliary.h:84
#define LOCAL_RATSNEST_ITEM
Definition: class_netinfo.h:61
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
EDA_RECT m_BrdBox
Definition: autorout.h:115
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:237
void CreateKeepOutRectangle ( int  ux0,
int  uy0,
int  ux1,
int  uy1,
int  marge,
int  aKeepOut,
LSET  aLayerMask 
)
static

Function CreateKeepOutRectangle builds the cost map: Cells ( in Dist map ) inside the rect x0,y0 a x1,y1 are incremented by value aKeepOut Cell outside this rectangle, but inside the rectangle x0,y0 -marge to x1,y1 + marge are incremented by a decreasing value (aKeepOut ...

0). The decreasing value depends on the distance to the first rectangle Therefore the cost is high in rect x0,y0 to x1,y1, and decrease outside this rectangle

Definition at line 963 of file auto_place_footprints.cpp.

References BOTTOM, g_Route_Layer_BOTTOM, g_Route_Layer_TOP, MATRIX_ROUTING_HEAD::GetDist(), EDA_RECT::GetX(), EDA_RECT::GetY(), MATRIX_ROUTING_HEAD::m_BrdBox, MATRIX_ROUTING_HEAD::m_GridRouting, MATRIX_ROUTING_HEAD::m_Ncols, MATRIX_ROUTING_HEAD::m_Nrows, MATRIX_ROUTING_HEAD::m_RoutingLayersCount, max, RoutingMatrix, MATRIX_ROUTING_HEAD::SetDist(), TOP, and trace.

Referenced by genModuleOnRoutingMatrix().

965 {
966  int row, col;
967  int row_min, row_max, col_min, col_max, pmarge;
968  int trace = 0;
969  DIST_CELL data, LocalKeepOut;
970  int lgain, cgain;
971 
972  if( aLayerMask[g_Route_Layer_BOTTOM] )
973  trace = 1; // Trace on bottom layer.
974 
976  trace |= 2; // Trace on top layer.
977 
978  if( trace == 0 )
979  return;
980 
981  ux0 -= RoutingMatrix.m_BrdBox.GetX();
982  uy0 -= RoutingMatrix.m_BrdBox.GetY();
983  ux1 -= RoutingMatrix.m_BrdBox.GetX();
984  uy1 -= RoutingMatrix.m_BrdBox.GetY();
985 
986  ux0 -= marge; ux1 += marge;
987  uy0 -= marge; uy1 += marge;
988 
989  pmarge = marge / RoutingMatrix.m_GridRouting;
990 
991  if( pmarge < 1 )
992  pmarge = 1;
993 
994  // Calculate the coordinate limits of the rectangle.
995  row_max = uy1 / RoutingMatrix.m_GridRouting;
996  col_max = ux1 / RoutingMatrix.m_GridRouting;
997  row_min = uy0 / RoutingMatrix.m_GridRouting;
998 
999  if( uy0 > row_min * RoutingMatrix.m_GridRouting )
1000  row_min++;
1001 
1002  col_min = ux0 / RoutingMatrix.m_GridRouting;
1003 
1004  if( ux0 > col_min * RoutingMatrix.m_GridRouting )
1005  col_min++;
1006 
1007  if( row_min < 0 )
1008  row_min = 0;
1009 
1010  if( row_max >= (RoutingMatrix.m_Nrows - 1) )
1011  row_max = RoutingMatrix.m_Nrows - 1;
1012 
1013  if( col_min < 0 )
1014  col_min = 0;
1015 
1016  if( col_max >= (RoutingMatrix.m_Ncols - 1) )
1017  col_max = RoutingMatrix.m_Ncols - 1;
1018 
1019  for( row = row_min; row <= row_max; row++ )
1020  {
1021  lgain = 256;
1022 
1023  if( row < pmarge )
1024  lgain = ( 256 * row ) / pmarge;
1025  else if( row > row_max - pmarge )
1026  lgain = ( 256 * ( row_max - row ) ) / pmarge;
1027 
1028  for( col = col_min; col <= col_max; col++ )
1029  {
1030  // RoutingMatrix Dist map containt the "cost" of the cell
1031  // at position (row, col)
1032  // in autoplace this is the cost of the cell, when
1033  // a footprint overlaps it, near a "master" footprint
1034  // this cost is hight near the "master" footprint
1035  // and decrease with the distance
1036  cgain = 256;
1037  LocalKeepOut = aKeepOut;
1038 
1039  if( col < pmarge )
1040  cgain = ( 256 * col ) / pmarge;
1041  else if( col > col_max - pmarge )
1042  cgain = ( 256 * ( col_max - col ) ) / pmarge;
1043 
1044  cgain = ( cgain * lgain ) / 256;
1045 
1046  if( cgain != 256 )
1047  LocalKeepOut = ( LocalKeepOut * cgain ) / 256;
1048 
1049  if( trace & 1 )
1050  {
1051  data = RoutingMatrix.GetDist( row, col, BOTTOM ) + LocalKeepOut;
1052  RoutingMatrix.SetDist( row, col, BOTTOM, data );
1053  }
1054 
1055  if( trace & 2 )
1056  {
1057  data = RoutingMatrix.GetDist( row, col, TOP );
1058  data = std::max( data, LocalKeepOut );
1059  RoutingMatrix.SetDist( row, col, TOP, data );
1060  }
1061  }
1062  }
1063 }
PCB_LAYER_ID g_Route_Layer_TOP
Definition: pcbnew.cpp:68
PCB_LAYER_ID g_Route_Layer_BOTTOM
Definition: pcbnew.cpp:69
long trace
Definition: solve.cpp:232
#define TOP
Definition: autorout.h:49
DIST_CELL GetDist(int aRow, int aCol, int aSide)
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
void SetDist(int aRow, int aCol, int aSide, DIST_CELL)
#define max(a, b)
Definition: auxiliary.h:86
int GetX() const
int GetY() const
#define BOTTOM
Definition: autorout.h:50
EDA_RECT m_BrdBox
Definition: autorout.h:115
int DIST_CELL
Definition: autorout.h:82
void draw_FootprintRect ( EDA_RECT aClipBox,
wxDC *  aDC,
EDA_RECT fpBBox,
COLOR4D  aColor 
)
inline

Definition at line 607 of file auto_place_footprints.cpp.

References GRRect().

Referenced by getOptimalModulePlacement().

608 {
609 #ifndef USE_WX_OVERLAY
610  GRRect( aClipBox, aDC, fpBBox, 0, aColor );
611 #endif
612 }
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1076
void drawPlacementRoutingMatrix ( BOARD aBrd,
wxDC *  DC 
)
static

Definition at line 411 of file auto_place_footprints.cpp.

References BLACK, BLUE, BOTTOM, CELL_is_EDGE, CELL_is_MODULE, CELL_is_ZONE, color, DARKGRAY, MATRIX_ROUTING_HEAD::GetCell(), MATRIX_ROUTING_HEAD::GetDist(), EDA_RECT::GetX(), EDA_RECT::GetY(), GR_COPY, GRPutPixel(), GRSetDrawMode(), HOLE, LIGHTGREEN, LIGHTRED, MATRIX_ROUTING_HEAD::m_BrdBox, MATRIX_ROUTING_HEAD::m_GridRouting, MATRIX_ROUTING_HEAD::m_Ncols, MATRIX_ROUTING_HEAD::m_Nrows, RoutingMatrix, TOP, and WHITE.

Referenced by PCB_EDIT_FRAME::AutoPlaceModule().

412 {
413  int ii, jj;
414  COLOR4D color;
415  int ox, oy;
416  MATRIX_CELL top_state, bottom_state;
417 
418  GRSetDrawMode( DC, GR_COPY );
419 
420  for( ii = 0; ii < RoutingMatrix.m_Nrows; ii++ )
421  {
423 
424  for( jj = 0; jj < RoutingMatrix.m_Ncols; jj++ )
425  {
427  color = COLOR4D::BLACK;
428 
429  top_state = RoutingMatrix.GetCell( ii, jj, TOP );
430  bottom_state = RoutingMatrix.GetCell( ii, jj, BOTTOM );
431 
432  if( top_state & CELL_is_ZONE )
433  color = COLOR4D( BLUE );
434 
435  // obstacles
436  if( ( top_state & CELL_is_EDGE ) || ( bottom_state & CELL_is_EDGE ) )
437  color = COLOR4D::WHITE;
438  else if( top_state & ( HOLE | CELL_is_MODULE ) )
439  color = COLOR4D( LIGHTRED );
440  else if( bottom_state & (HOLE | CELL_is_MODULE) )
441  color = COLOR4D( LIGHTGREEN );
442  else // Display the filling and keep out regions.
443  {
444  if( RoutingMatrix.GetDist( ii, jj, TOP )
445  || RoutingMatrix.GetDist( ii, jj, BOTTOM ) )
446  color = DARKGRAY;
447  }
448 
449  GRPutPixel( NULL, DC, ox, oy, color );
450  }
451  }
452 }
Definition: colors.h:57
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:296
#define CELL_is_EDGE
Definition: cell.h:42
MATRIX_CELL GetCell(int aRow, int aCol, int aSide)
#define TOP
Definition: autorout.h:49
DIST_CELL GetDist(int aRow, int aCol, int aSide)
unsigned char MATRIX_CELL
Definition: autorout.h:81
void GRPutPixel(EDA_RECT *ClipBox, wxDC *DC, int x, int y, COLOR4D Color)
Definition: gr_basic.cpp:345
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
#define CELL_is_MODULE
Definition: cell.h:41
int GetX() const
Definition: colors.h:49
int GetY() const
#define BOTTOM
Definition: autorout.h:50
Definition: colors.h:45
EDA_RECT m_BrdBox
Definition: autorout.h:115
#define HOLE
Definition: cell.h:40
#define CELL_is_ZONE
Definition: cell.h:44
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
void genModuleOnRoutingMatrix ( MODULE Module)

Definition at line 546 of file auto_place_footprints.cpp.

References B_Cu, CELL_is_MODULE, CreateKeepOutRectangle(), F_Cu, GAIN, EDA_RECT::GetBottom(), MODULE::GetBoundingBox(), D_PAD::GetClearance(), BOARD_ITEM::GetLayer(), MODULE::GetPadCount(), EDA_RECT::GetRight(), EDA_RECT::GetX(), EDA_RECT::GetY(), EDA_RECT::Inflate(), KEEP_OUT_MARGIN, MATRIX_ROUTING_HEAD::m_BrdBox, MATRIX_ROUTING_HEAD::m_GridRouting, D_PAD::Next(), MODULE::Pads(), PlacePad(), RoutingMatrix, TraceFilledRectangle(), and WRITE_OR_CELL.

Referenced by PCB_EDIT_FRAME::AutoPlaceModule().

547 {
548  int ox, oy, fx, fy;
549  LSET layerMask;
550  D_PAD* Pad;
551 
552  EDA_RECT fpBBox = Module->GetBoundingBox();
553 
554  fpBBox.Inflate( RoutingMatrix.m_GridRouting / 2 );
555  ox = fpBBox.GetX();
556  fx = fpBBox.GetRight();
557  oy = fpBBox.GetY();
558  fy = fpBBox.GetBottom();
559 
560  if( ox < RoutingMatrix.m_BrdBox.GetX() )
561  ox = RoutingMatrix.m_BrdBox.GetX();
562 
563  if( ox > RoutingMatrix.m_BrdBox.GetRight() )
565 
566  if( fx < RoutingMatrix.m_BrdBox.GetX() )
567  fx = RoutingMatrix.m_BrdBox.GetX();
568 
569  if( fx > RoutingMatrix.m_BrdBox.GetRight() )
571 
572  if( oy < RoutingMatrix.m_BrdBox.GetY() )
573  oy = RoutingMatrix.m_BrdBox.GetY();
574 
575  if( oy > RoutingMatrix.m_BrdBox.GetBottom() )
577 
578  if( fy < RoutingMatrix.m_BrdBox.GetY() )
579  fy = RoutingMatrix.m_BrdBox.GetY();
580 
581  if( fy > RoutingMatrix.m_BrdBox.GetBottom() )
583 
584  if( Module->GetLayer() == F_Cu )
585  layerMask.set( F_Cu );
586 
587  if( Module->GetLayer() == B_Cu )
588  layerMask.set( B_Cu );
589 
590  TraceFilledRectangle( ox, oy, fx, fy, layerMask,
592 
593  // Trace pads + clearance areas.
594  for( Pad = Module->Pads(); Pad != NULL; Pad = Pad->Next() )
595  {
596  int margin = (RoutingMatrix.m_GridRouting / 2) + Pad->GetClearance();
597  ::PlacePad( Pad, CELL_is_MODULE, margin, WRITE_OR_CELL );
598  }
599 
600  // Trace clearance.
601  int margin = ( RoutingMatrix.m_GridRouting * Module->GetPadCount() ) / GAIN;
602  CreateKeepOutRectangle( ox, oy, fx, fy, margin, KEEP_OUT_MARGIN, layerMask );
603 }
void TraceFilledRectangle(int ux0, int uy0, int ux1, int uy1, LSET side, int color, int op_logic)
Definition: graphpcb.cpp:478
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
DLIST_ITERATOR_WRAPPER< D_PAD > Pads()
Definition: class_module.h:160
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Class LSET is a set of PCB_LAYER_IDs.
D_PAD * Next() const
Definition: class_pad.h:160
int GetBottom() const
static void CreateKeepOutRectangle(int ux0, int uy0, int ux1, int uy1, int marge, int aKeepOut, LSET aLayerMask)
Function CreateKeepOutRectangle builds the cost map: Cells ( in Dist map ) inside the rect x0...
int GetRight() const
unsigned GetPadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
GetPadCount returns the number of pads.
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
#define GAIN
#define CELL_is_MODULE
Definition: cell.h:41
Class EDA_RECT handles the component boundary box.
int GetX() const
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:546
int GetY() const
void PlacePad(D_PAD *pt_pad, int type, int marge, int op_logic)
Definition: graphpcb.cpp:87
EDA_RECT m_BrdBox
Definition: autorout.h:115
#define KEEP_OUT_MARGIN
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
#define WRITE_OR_CELL
Definition: autorout.h:191
int genPlacementRoutingMatrix ( BOARD aBrd,
EDA_MSG_PANEL messagePanel 
)

Definition at line 455 of file auto_place_footprints.cpp.

References B_Cu, BOTTOM, CELL_is_EDGE, CELL_is_ZONE, MATRIX_ROUTING_HEAD::ComputeMatrixSize(), CYAN, DisplayError(), BOARD::Drawings(), Edge_Cuts, EDA_MSG_PANEL::EraseMsgBox(), F_Cu, g_Route_Layer_BOTTOM, g_Route_Layer_TOP, BOARD::GetBoardEdgesBoundingBox(), EDA_RECT::GetHeight(), BOARD_ITEM::GetLayer(), EDA_RECT::GetWidth(), GREEN, HOLE, MATRIX_ROUTING_HEAD::InitRoutingMatrix(), MATRIX_ROUTING_HEAD::m_BoardSide, MATRIX_ROUTING_HEAD::m_GridRouting, MATRIX_ROUTING_HEAD::m_MemSize, MATRIX_ROUTING_HEAD::m_Ncols, MATRIX_ROUTING_HEAD::m_Nrows, MATRIX_ROUTING_HEAD::m_RoutingLayersCount, MATRIX_ROUTING_HEAD::OrCell(), PCB_LINE_T, PCB_TEXT_T, propagate(), RoutingMatrix, BOARD_ITEM::SetLayer(), EDA_MSG_PANEL::SetMessage(), BOARD_CONNECTED_ITEM::SetNetCode(), TRACK::SetWidth(), TOP, TraceSegmentPcb(), UNDEFINED_LAYER, MATRIX_ROUTING_HEAD::UnInitRoutingMatrix(), WRITE_CELL, and YELLOW.

Referenced by PCB_EDIT_FRAME::AutoPlaceModule().

456 {
457  wxString msg;
458 
460 
461  EDA_RECT bbox = aBrd->GetBoardEdgesBoundingBox();
462 
463  if( bbox.GetWidth() == 0 || bbox.GetHeight() == 0 )
464  {
465  DisplayError( NULL, _( "No PCB edge found, unknown board size!" ) );
466  return 0;
467  }
468 
469  RoutingMatrix.ComputeMatrixSize( aBrd, true );
470  int nbCells = RoutingMatrix.m_Ncols * RoutingMatrix.m_Nrows;
471 
472  messagePanel->EraseMsgBox();
473  msg.Printf( wxT( "%d" ), RoutingMatrix.m_Ncols );
474  messagePanel->SetMessage( 1, _( "Cols" ), msg, GREEN );
475  msg.Printf( wxT( "%d" ), RoutingMatrix.m_Nrows );
476  messagePanel->SetMessage( 7, _( "Lines" ), msg, GREEN );
477  msg.Printf( wxT( "%d" ), nbCells );
478  messagePanel->SetMessage( 14, _( "Cells." ), msg, YELLOW );
479 
480  // Choose the number of board sides.
482 
484 
485  // Display memory usage.
486  msg.Printf( wxT( "%d" ), RoutingMatrix.m_MemSize / 1024 );
487  messagePanel->SetMessage( 24, wxT( "Mem(Kb)" ), msg, CYAN );
488 
490 
493 
495 
496  // Place the edge layer segments
497  TRACK TmpSegm( NULL );
498 
499  TmpSegm.SetLayer( UNDEFINED_LAYER );
500  TmpSegm.SetNetCode( -1 );
501  TmpSegm.SetWidth( RoutingMatrix.m_GridRouting / 2 );
502 
503  for( auto PtStruct : aBrd->Drawings() )
504  {
505  DRAWSEGMENT* DrawSegm;
506 
507  switch( PtStruct->Type() )
508  {
509  case PCB_LINE_T:
510  DrawSegm = (DRAWSEGMENT*) PtStruct;
511 
512  if( DrawSegm->GetLayer() != Edge_Cuts )
513  break;
514 
515  TraceSegmentPcb( DrawSegm, HOLE | CELL_is_EDGE,
517  break;
518 
519  case PCB_TEXT_T:
520  default:
521  break;
522  }
523  }
524 
525  // Mark cells of the routing matrix to CELL_is_ZONE
526  // (i.e. availlable cell to place a module )
527  // Init a starting point of attachment to the area.
529  BOTTOM, CELL_is_ZONE );
530 
531  // find and mark all other availlable cells:
532  for( int ii = 1; ii != 0; )
533  ii = propagate();
534 
535  // Initialize top layer. to the same value as the bottom layer
538  nbCells * sizeof(MATRIX_CELL) );
539 
540  return 1;
541 }
PCB_LAYER_ID g_Route_Layer_TOP
Definition: pcbnew.cpp:68
PCB_LAYER_ID g_Route_Layer_BOTTOM
Definition: pcbnew.cpp:69
int InitRoutingMatrix()
Function InitBoard initializes the data structures.
static int propagate()
Function propagate Used only in autoplace calculations Uses the routing matrix to fill the cells with...
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
#define CELL_is_EDGE
Definition: cell.h:42
int GetHeight() const
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
#define WRITE_CELL
Definition: autorout.h:190
#define TOP
Definition: autorout.h:49
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:797
MATRIX_CELL * m_BoardSide[MAX_ROUTING_LAYERS_COUNT]
Definition: autorout.h:107
Definition: colors.h:59
unsigned char MATRIX_CELL
Definition: autorout.h:81
void EraseMsgBox()
Definition: msgpanel.cpp:215
void SetMessage(int aXPosition, const wxString &aUpperText, const wxString &aLowerText, COLOR4D aColor)
Function SetMessage sets a message at aXPosition to aUpperText and aLowerText in the message panel...
Definition: msgpanel.cpp:145
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
bool ComputeMatrixSize(BOARD *aPcb, bool aUseBoardEdgesOnly=false)
Function ComputeMatrixSize calculates the number of rows and columns of dimensions of aPcb for routin...
void OrCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: colors.h:58
Class EDA_RECT handles the component boundary box.
int GetWidth() const
#define BOTTOM
Definition: autorout.h:50
void TraceSegmentPcb(TRACK *pt_segm, int type, int marge, int op_logic)
Definition: graphpcb.cpp:290
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
Definition: colors.h:68
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:73
#define HOLE
Definition: cell.h:40
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:251
#define CELL_is_ZONE
Definition: cell.h:44
int getOptimalModulePlacement ( PCB_EDIT_FRAME aFrame,
MODULE aModule,
wxDC *  aDC 
)
static

Definition at line 615 of file auto_place_footprints.cpp.

References B_Cu, BROWN, PCB_BASE_FRAME::build_ratsnest_module(), MODULE::CalculateBoundingBox(), color, compute_Ratsnest_PlaceModule(), CoordinateToString(), CurrPosition, draw_FootprintRect(), MODULE::DrawOutlinesWhenMoving(), ESC, F_Cu, g_Offset_Module, EDA_DRAW_PANEL::GetAbortRequest(), PCB_BASE_FRAME::GetBoard(), EDA_DRAW_FRAME::GetCanvas(), GetChars(), EDA_DRAW_PANEL::GetClipBox(), PCB_BASE_FRAME::GetDisplayOptions(), EDA_RECT::GetEnd(), MODULE::GetFootprintRect(), BOARD_ITEM::GetLayer(), EDA_RECT::GetOrigin(), MODULE::GetPosition(), GRRect(), IsOK(), MATRIX_ROUTING_HEAD::m_BrdBox, MATRIX_ROUTING_HEAD::m_GridRouting, MATRIX_ROUTING_HEAD::m_RoutingLayersCount, BOARD::m_Status_Pcb, MinCout, EDA_RECT::Move(), MODULE::Pads(), RATSNEST_ITEM_LOCAL_OK, RED, RoutingMatrix, EDA_DRAW_PANEL::SetAbortRequest(), EDA_DRAW_FRAME::SetMsgPanel(), EDA_RECT::SetOrigin(), TstModuleOnBoard(), wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::AutoPlaceModule().

616 {
617  int error = 1;
618  wxPoint LastPosOK;
619  double min_cost, curr_cost, Score;
620  bool TstOtherSide;
621  auto displ_opts = (PCB_DISPLAY_OPTIONS*)aFrame->GetDisplayOptions();
622  BOARD* brd = aFrame->GetBoard();
623 
624  aModule->CalculateBoundingBox();
625 
626  bool showRats = displ_opts->m_Show_Module_Ratsnest;
627  displ_opts->m_Show_Module_Ratsnest = false;
628 
630  aFrame->SetMsgPanel( aModule );
631 
632  LastPosOK = RoutingMatrix.m_BrdBox.GetOrigin();
633 
634  wxPoint mod_pos = aModule->GetPosition();
635  EDA_RECT fpBBox = aModule->GetFootprintRect();
636 
637  // Move fpBBox to have the footprint position at (0,0)
638  fpBBox.Move( -mod_pos );
639  wxPoint fpBBoxOrg = fpBBox.GetOrigin();
640 
641  // Calculate the limit of the footprint position, relative
642  // to the routing matrix area
643  wxPoint xylimit = RoutingMatrix.m_BrdBox.GetEnd() - fpBBox.GetEnd();
644 
645  wxPoint initialPos = RoutingMatrix.m_BrdBox.GetOrigin() - fpBBoxOrg;
646 
647  // Stay on grid.
648  initialPos.x -= initialPos.x % RoutingMatrix.m_GridRouting;
649  initialPos.y -= initialPos.y % RoutingMatrix.m_GridRouting;
650 
651  CurrPosition = initialPos;
652 
653  // Undraw the current footprint
654  aModule->DrawOutlinesWhenMoving( aFrame->GetCanvas(), aDC, wxPoint( 0, 0 ) );
655 
656  g_Offset_Module = mod_pos - CurrPosition;
657 
658  /* Examine pads, and set TstOtherSide to true if a footprint
659  * has at least 1 pad through.
660  */
661  TstOtherSide = false;
662 
664  {
665  LSET other( aModule->GetLayer() == B_Cu ? F_Cu : B_Cu );
666 
667  for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
668  {
669  if( !( pad->GetLayerSet() & other ).any() )
670  continue;
671 
672  TstOtherSide = true;
673  break;
674  }
675  }
676 
677  // Draw the initial bounding box position
678  COLOR4D color = COLOR4D( BROWN );
679  fpBBox.SetOrigin( fpBBoxOrg + CurrPosition );
680  draw_FootprintRect(aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color);
681 
682  min_cost = -1.0;
683  aFrame->SetStatusText( wxT( "Score ??, pos ??" ) );
684 
685  for( ; CurrPosition.x < xylimit.x; CurrPosition.x += RoutingMatrix.m_GridRouting )
686  {
687  wxYield();
688 
689  if( aFrame->GetCanvas()->GetAbortRequest() )
690  {
691  if( IsOK( aFrame, _( "OK to abort?" ) ) )
692  {
693  displ_opts->m_Show_Module_Ratsnest = showRats;
694  return ESC;
695  }
696  else
697  aFrame->GetCanvas()->SetAbortRequest( false );
698  }
699 
700  CurrPosition.y = initialPos.y;
701 
702  for( ; CurrPosition.y < xylimit.y; CurrPosition.y += RoutingMatrix.m_GridRouting )
703  {
704  // Erase traces.
705  draw_FootprintRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color );
706 
707  fpBBox.SetOrigin( fpBBoxOrg + CurrPosition );
708  g_Offset_Module = mod_pos - CurrPosition;
709  int keepOutCost = TstModuleOnBoard( brd, aModule, TstOtherSide );
710 
711  // Draw at new place
712  color = keepOutCost >= 0 ? BROWN : RED;
713  draw_FootprintRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color );
714 
715  if( keepOutCost >= 0 ) // i.e. if the module can be put here
716  {
717  error = 0;
718  aFrame->build_ratsnest_module( aModule );
719  curr_cost = compute_Ratsnest_PlaceModule( brd );
720  Score = curr_cost + keepOutCost;
721 
722  if( (min_cost >= Score ) || (min_cost < 0 ) )
723  {
724  LastPosOK = CurrPosition;
725  min_cost = Score;
726  wxString msg;
727  msg.Printf( wxT( "Score %g, pos %s, %s" ),
728  min_cost,
729  GetChars( ::CoordinateToString( LastPosOK.x ) ),
730  GetChars( ::CoordinateToString( LastPosOK.y ) ) );
731  aFrame->SetStatusText( msg );
732  }
733  }
734  }
735  }
736 
737  // erasing the last traces
738  GRRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, 0, BROWN );
739 
740  displ_opts->m_Show_Module_Ratsnest = showRats;
741 
742  // Regeneration of the modified variable.
743  CurrPosition = LastPosOK;
744 
745  brd->m_Status_Pcb &= ~( RATSNEST_ITEM_LOCAL_OK | LISTE_PAD_OK );
746 
747  MinCout = min_cost;
748  return error;
749 }
wxString CoordinateToString(int aValue, bool aConvertToMils)
Function CoordinateToString is a helper to convert the integer coordinate aValue to a string in inche...
Definition: base_units.cpp:118
static wxPoint CurrPosition
wxPoint g_Offset_Module
Definition: pcbnew.cpp:73
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
const wxPoint GetOrigin() const
static int TstModuleOnBoard(BOARD *Pcb, MODULE *Module, bool TstOtherSide)
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:331
double MinCout
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
const wxPoint & GetPosition() const override
Definition: class_module.h:175
void build_ratsnest_module(MODULE *aModule, wxPoint aMoveVector)
Function build_ratsnest_module Build a ratsnest relative to one footprint.
Definition: ratsnest.cpp:184
DLIST_ITERATOR_WRAPPER< D_PAD > Pads()
Definition: class_module.h:160
void SetOrigin(const wxPoint &pos)
BOARD * GetBoard() const
#define ESC
Definition: common.h:87
void * GetDisplayOptions() override
Function GetDisplayOptions returns the display options current in use Display options are relative to...
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1076
Class PCB_DISPLAY_OPTIONS handles display options like enable/disable some optional drawings...
Class LSET is a set of PCB_LAYER_IDs.
static double compute_Ratsnest_PlaceModule(BOARD *aBrd)
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:784
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text...
EDA_RECT * GetClipBox()
Definition: colors.h:60
void SetAbortRequest(bool aAbortRequest)
const wxPoint GetEnd() const
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
bool GetAbortRequest() const
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
void draw_FootprintRect(EDA_RECT *aClipBox, wxDC *aDC, EDA_RECT &fpBBox, COLOR4D aColor)
Class EDA_RECT handles the component boundary box.
void DrawOutlinesWhenMoving(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aMoveVector)
Function DrawOutlinesWhenMoving draws in XOR mode the footprint when moving it to the aDC...
Definition: ratsnest.cpp:217
EDA_RECT m_BrdBox
Definition: autorout.h:115
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:131
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:237
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
Definition: colors.h:62
static MODULE * PickModule ( PCB_EDIT_FRAME pcbframe,
wxDC *  DC 
)
static

Function PickModule find the "best" module place The criteria are:

  • Maximum ratsnest with modules already placed
  • Max size, and number of pads max

Definition at line 1095 of file auto_place_footprints.cpp.

References PCB_BASE_FRAME::build_ratsnest_module(), MODULE::CalculateBoundingBox(), PCB_BASE_FRAME::GetBoard(), MODULE::GetFlag(), MODULE::IncrementFlag(), LOCAL_RATSNEST_ITEM, BOARD::m_Modules, BOARD::m_Status_Pcb, MODULE::NeedsPlaced(), MODULE::Next(), RATSNEST_ITEM_LOCAL_OK, MODULE::SetFlag(), EDA_DRAW_FRAME::SetMsgPanel(), sortFootprintsByRatsnestSize(), and Tri_PlaceModules().

Referenced by PCB_EDIT_FRAME::AutoPlaceModule().

1096 {
1097  MODULE* Module;
1098  std::vector <MODULE*> moduleList;
1099 
1100  // Build sorted footprints list (sort by decreasing size )
1101  Module = pcbframe->GetBoard()->m_Modules;
1102 
1103  for( ; Module != NULL; Module = Module->Next() )
1104  {
1105  Module->CalculateBoundingBox();
1106  moduleList.push_back( Module );
1107  }
1108 
1109  sort( moduleList.begin(), moduleList.end(), Tri_PlaceModules );
1110 
1111  for( unsigned kk = 0; kk < moduleList.size(); kk++ )
1112  {
1113  Module = moduleList[kk];
1114  Module->SetFlag( 0 );
1115 
1116  if( !Module->NeedsPlaced() )
1117  continue;
1118 
1119  pcbframe->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
1120  pcbframe->SetMsgPanel( Module );
1121  pcbframe->build_ratsnest_module( Module );
1122 
1123  // Calculate external ratsnest.
1124  for( unsigned ii = 0; ii < pcbframe->GetBoard()->m_LocalRatsnest.size(); ii++ )
1125  {
1126  if( ( pcbframe->GetBoard()->m_LocalRatsnest[ii].m_Status &
1127  LOCAL_RATSNEST_ITEM ) == 0 )
1128  Module->IncrementFlag();
1129  }
1130  }
1131 
1132  pcbframe->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
1133 
1134  sort( moduleList.begin(), moduleList.end(), sortFootprintsByRatsnestSize );
1135 
1136  // Search for "best" module.
1137  MODULE* bestModule = NULL;
1138  MODULE* altModule = NULL;
1139 
1140  for( unsigned ii = 0; ii < moduleList.size(); ii++ )
1141  {
1142  Module = moduleList[ii];
1143 
1144  if( !Module->NeedsPlaced() )
1145  continue;
1146 
1147  altModule = Module;
1148 
1149  if( Module->GetFlag() == 0 )
1150  continue;
1151 
1152  bestModule = Module;
1153  break;
1154  }
1155 
1156  if( bestModule )
1157  return bestModule;
1158  else
1159  return altModule;
1160 }
int GetFlag() const
Definition: class_module.h:222
void IncrementFlag()
Definition: class_module.h:221
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
static bool sortFootprintsByRatsnestSize(MODULE *ref, MODULE *compare)
MODULE * Next() const
Definition: class_module.h:120
void build_ratsnest_module(MODULE *aModule, wxPoint aMoveVector)
Function build_ratsnest_module Build a ratsnest relative to one footprint.
Definition: ratsnest.cpp:184
BOARD * GetBoard() const
bool NeedsPlaced() const
Definition: class_module.h:283
#define LOCAL_RATSNEST_ITEM
Definition: class_netinfo.h:61
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:784
static bool Tri_PlaceModules(MODULE *ref, MODULE *compare)
DLIST< MODULE > m_Modules
Definition: class_board.h:245
void SetFlag(int aFlag)
Definition: class_module.h:220
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:237
int propagate ( )
static

Function propagate Used only in autoplace calculations Uses the routing matrix to fill the cells within the zone Search and mark cells within the zone, and agree with DRC options.

Requirements: Start from an initial point, to fill zone The zone must have no "copper island" Algorithm: If the current cell has a neighbor flagged as "cell in the zone", it become a cell in the zone The first point in the zone is the starting point 4 searches within the matrix are made: 1 - Left to right and top to bottom 2 - Right to left and top to bottom 3 - bottom to top and Right to left 4 - bottom to top and Left to right Given the current cell, for each search, we consider the 2 neighbor cells the previous cell on the same line and the previous cell on the same column.

This function can request some iterations Iterations are made until no cell is added to the zone.

Returns
added cells count (i.e. which the attribute CELL_is_ZONE is set)

Definition at line 1187 of file auto_place_footprints.cpp.

References BOTTOM, CELL_is_ZONE, MATRIX_ROUTING_HEAD::GetCell(), MATRIX_ROUTING_HEAD::m_Ncols, MATRIX_ROUTING_HEAD::m_Nrows, max, NO_CELL_ZONE, MATRIX_ROUTING_HEAD::OrCell(), and RoutingMatrix.

Referenced by genPlacementRoutingMatrix().

1188 {
1189  int row, col;
1190  long current_cell, old_cell_H;
1191  std::vector<long> pt_cell_V;
1192  int nbpoints = 0;
1193 
1194 #define NO_CELL_ZONE (HOLE | CELL_is_EDGE | CELL_is_ZONE)
1195 
1196  pt_cell_V.reserve( std::max( RoutingMatrix.m_Nrows, RoutingMatrix.m_Ncols ) );
1197  fill( pt_cell_V.begin(), pt_cell_V.end(), 0 );
1198 
1199  // Search from left to right and top to bottom.
1200  for( row = 0; row < RoutingMatrix.m_Nrows; row++ )
1201  {
1202  old_cell_H = 0;
1203 
1204  for( col = 0; col < RoutingMatrix.m_Ncols; col++ )
1205  {
1206  current_cell = RoutingMatrix.GetCell( row, col, BOTTOM ) & NO_CELL_ZONE;
1207 
1208  if( current_cell == 0 ) // a free cell is found
1209  {
1210  if( (old_cell_H & CELL_is_ZONE) || (pt_cell_V[col] & CELL_is_ZONE) )
1211  {
1212  RoutingMatrix.OrCell( row, col, BOTTOM, CELL_is_ZONE );
1213  current_cell = CELL_is_ZONE;
1214  nbpoints++;
1215  }
1216  }
1217 
1218  pt_cell_V[col] = old_cell_H = current_cell;
1219  }
1220  }
1221 
1222  // Search from right to left and top to bottom/
1223  fill( pt_cell_V.begin(), pt_cell_V.end(), 0 );
1224 
1225  for( row = 0; row < RoutingMatrix.m_Nrows; row++ )
1226  {
1227  old_cell_H = 0;
1228 
1229  for( col = RoutingMatrix.m_Ncols - 1; col >= 0; col-- )
1230  {
1231  current_cell = RoutingMatrix.GetCell( row, col, BOTTOM ) & NO_CELL_ZONE;
1232 
1233  if( current_cell == 0 ) // a free cell is found
1234  {
1235  if( (old_cell_H & CELL_is_ZONE) || (pt_cell_V[col] & CELL_is_ZONE) )
1236  {
1237  RoutingMatrix.OrCell( row, col, BOTTOM, CELL_is_ZONE );
1238  current_cell = CELL_is_ZONE;
1239  nbpoints++;
1240  }
1241  }
1242 
1243  pt_cell_V[col] = old_cell_H = current_cell;
1244  }
1245  }
1246 
1247  // Search from bottom to top and right to left.
1248  fill( pt_cell_V.begin(), pt_cell_V.end(), 0 );
1249 
1250  for( col = RoutingMatrix.m_Ncols - 1; col >= 0; col-- )
1251  {
1252  old_cell_H = 0;
1253 
1254  for( row = RoutingMatrix.m_Nrows - 1; row >= 0; row-- )
1255  {
1256  current_cell = RoutingMatrix.GetCell( row, col, BOTTOM ) & NO_CELL_ZONE;
1257 
1258  if( current_cell == 0 ) // a free cell is found
1259  {
1260  if( (old_cell_H & CELL_is_ZONE) || (pt_cell_V[row] & CELL_is_ZONE) )
1261  {
1262  RoutingMatrix.OrCell( row, col, BOTTOM, CELL_is_ZONE );
1263  current_cell = CELL_is_ZONE;
1264  nbpoints++;
1265  }
1266  }
1267 
1268  pt_cell_V[row] = old_cell_H = current_cell;
1269  }
1270  }
1271 
1272  // Search from bottom to top and left to right.
1273  fill( pt_cell_V.begin(), pt_cell_V.end(), 0 );
1274 
1275  for( col = 0; col < RoutingMatrix.m_Ncols; col++ )
1276  {
1277  old_cell_H = 0;
1278 
1279  for( row = RoutingMatrix.m_Nrows - 1; row >= 0; row-- )
1280  {
1281  current_cell = RoutingMatrix.GetCell( row, col, BOTTOM ) & NO_CELL_ZONE;
1282 
1283  if( current_cell == 0 ) // a free cell is found
1284  {
1285  if( (old_cell_H & CELL_is_ZONE) || (pt_cell_V[row] & CELL_is_ZONE) )
1286  {
1287  RoutingMatrix.OrCell( row, col, BOTTOM, CELL_is_ZONE );
1288  current_cell = CELL_is_ZONE;
1289  nbpoints++;
1290  }
1291  }
1292 
1293  pt_cell_V[row] = old_cell_H = current_cell;
1294  }
1295  }
1296 
1297  return nbpoints;
1298 }
MATRIX_CELL GetCell(int aRow, int aCol, int aSide)
#define NO_CELL_ZONE
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
void OrCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
#define max(a, b)
Definition: auxiliary.h:86
#define BOTTOM
Definition: autorout.h:50
#define CELL_is_ZONE
Definition: cell.h:44
static bool sortFootprintsByRatsnestSize ( MODULE ref,
MODULE compare 
)
static

Definition at line 1078 of file auto_place_footprints.cpp.

References MODULE::GetArea(), and MODULE::GetFlag().

Referenced by PickModule().

1079 {
1080  double ff1, ff2;
1081 
1082  ff1 = ref->GetArea() * ref->GetFlag();
1083  ff2 = compare->GetArea() * compare->GetFlag();
1084  return ff2 < ff1;
1085 }
int GetFlag() const
Definition: class_module.h:222
double GetArea() const
Definition: class_module.h:545
static bool Tri_PlaceModules ( MODULE ref,
MODULE compare 
)
static

Definition at line 1067 of file auto_place_footprints.cpp.

References MODULE::GetArea(), and MODULE::GetPadCount().

Referenced by PickModule().

1068 {
1069  double ff1, ff2;
1070 
1071  ff1 = ref->GetArea() * ref->GetPadCount();
1072  ff2 = compare->GetArea() * compare->GetPadCount();
1073 
1074  return ff2 < ff1;
1075 }
unsigned GetPadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
GetPadCount returns the number of pads.
double GetArea() const
Definition: class_module.h:545
int TstModuleOnBoard ( BOARD Pcb,
MODULE Module,
bool  TstOtherSide 
)
static

Definition at line 868 of file auto_place_footprints.cpp.

References B_Cu, BOTTOM, CalculateKeepOutArea(), FREE_CELL, g_Offset_Module, GAIN, MODULE::GetFootprintRect(), BOARD_ITEM::GetLayer(), MODULE::GetPadCount(), EDA_RECT::Inflate(), MATRIX_ROUTING_HEAD::m_GridRouting, EDA_RECT::Move(), RoutingMatrix, TOP, and TstRectangle().

Referenced by getOptimalModulePlacement().

869 {
870  int side = TOP;
871  int otherside = BOTTOM;
872 
873  if( aModule->GetLayer() == B_Cu )
874  {
875  side = BOTTOM; otherside = TOP;
876  }
877 
878  EDA_RECT fpBBox = aModule->GetFootprintRect();
879  fpBBox.Move( -g_Offset_Module );
880 
881  int diag = TstRectangle( Pcb, fpBBox, side );
882 
883  if( diag != FREE_CELL )
884  return diag;
885 
886  if( TstOtherSide )
887  {
888  diag = TstRectangle( Pcb, fpBBox, otherside );
889 
890  if( diag != FREE_CELL )
891  return diag;
892  }
893 
894  int marge = ( RoutingMatrix.m_GridRouting * aModule->GetPadCount() ) / GAIN;
895 
896  fpBBox.Inflate( marge );
897  return CalculateKeepOutArea( fpBBox, side );
898 }
wxPoint g_Offset_Module
Definition: pcbnew.cpp:73
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
unsigned int CalculateKeepOutArea(const EDA_RECT &aRect, int side)
#define TOP
Definition: autorout.h:49
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
int TstRectangle(BOARD *Pcb, const EDA_RECT &aRect, int side)
#define GAIN
Class EDA_RECT handles the component boundary box.
#define BOTTOM
Definition: autorout.h:50
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
#define FREE_CELL
int TstRectangle ( BOARD Pcb,
const EDA_RECT aRect,
int  side 
)

Definition at line 758 of file auto_place_footprints.cpp.

References CELL_is_MODULE, CELL_is_ZONE, FREE_CELL, MATRIX_ROUTING_HEAD::GetCell(), EDA_RECT::GetEnd(), EDA_RECT::GetOrigin(), EDA_RECT::Inflate(), MATRIX_ROUTING_HEAD::m_BrdBox, MATRIX_ROUTING_HEAD::m_GridRouting, MATRIX_ROUTING_HEAD::m_Ncols, MATRIX_ROUTING_HEAD::m_Nrows, OCCUPED_By_MODULE, OUT_OF_BOARD, RoutingMatrix, wxPoint::x, and wxPoint::y.

Referenced by TstModuleOnBoard().

759 {
760  EDA_RECT rect = aRect;
761 
762  rect.Inflate( RoutingMatrix.m_GridRouting / 2 );
763 
764  wxPoint start = rect.GetOrigin();
765  wxPoint end = rect.GetEnd();
766 
767  start -= RoutingMatrix.m_BrdBox.GetOrigin();
769 
770  int row_min = start.y / RoutingMatrix.m_GridRouting;
771  int row_max = end.y / RoutingMatrix.m_GridRouting;
772  int col_min = start.x / RoutingMatrix.m_GridRouting;
773  int col_max = end.x / RoutingMatrix.m_GridRouting;
774 
775  if( start.y > row_min * RoutingMatrix.m_GridRouting )
776  row_min++;
777 
778  if( start.x > col_min * RoutingMatrix.m_GridRouting )
779  col_min++;
780 
781  if( row_min < 0 )
782  row_min = 0;
783 
784  if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
785  row_max = RoutingMatrix.m_Nrows - 1;
786 
787  if( col_min < 0 )
788  col_min = 0;
789 
790  if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
791  col_max = RoutingMatrix.m_Ncols - 1;
792 
793  for( int row = row_min; row <= row_max; row++ )
794  {
795  for( int col = col_min; col <= col_max; col++ )
796  {
797  unsigned int data = RoutingMatrix.GetCell( row, col, side );
798 
799  if( ( data & CELL_is_ZONE ) == 0 )
800  return OUT_OF_BOARD;
801 
802  if( (data & CELL_is_MODULE) )
803  return OCCUPED_By_MODULE;
804  }
805  }
806 
807  return FREE_CELL;
808 }
const wxPoint GetOrigin() const
MATRIX_CELL GetCell(int aRow, int aCol, int aSide)
#define OCCUPED_By_MODULE
#define OUT_OF_BOARD
const wxPoint GetEnd() const
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
#define CELL_is_MODULE
Definition: cell.h:41
Class EDA_RECT handles the component boundary box.
EDA_RECT m_BrdBox
Definition: autorout.h:115
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
#define CELL_is_ZONE
Definition: cell.h:44
#define FREE_CELL

Variable Documentation

wxPoint CurrPosition
static
double MinCout
const double OrientPenality[11]
static
Initial value:
=
{
2.0,
1.9,
1.8,
1.7,
1.6,
1.5,
1.4,
1.3,
1.2,
1.1,
1.0
}

Definition at line 61 of file auto_place_footprints.cpp.

Referenced by PCB_EDIT_FRAME::AutoPlaceModule().