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 <colors_selection.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 80 of file auto_place_footprints.cpp.

Referenced by TstModuleOnBoard(), and TstRectangle().

#define GAIN   16

Definition at line 55 of file auto_place_footprints.cpp.

Referenced by genModuleOnRoutingMatrix(), and TstModuleOnBoard().

#define KEEP_OUT_MARGIN   500

Definition at line 56 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 79 of file auto_place_footprints.cpp.

Referenced by TstRectangle().

#define OUT_OF_BOARD   -2

Definition at line 78 of file auto_place_footprints.cpp.

Referenced by TstRectangle().

Function Documentation

unsigned int CalculateKeepOutArea ( const EDA_RECT aRect,
int  side 
)

Definition at line 818 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().

819 {
820  wxPoint start = aRect.GetOrigin();
821  wxPoint end = aRect.GetEnd();
822 
823  start -= RoutingMatrix.m_BrdBox.GetOrigin();
825 
826  int row_min = start.y / RoutingMatrix.m_GridRouting;
827  int row_max = end.y / RoutingMatrix.m_GridRouting;
828  int col_min = start.x / RoutingMatrix.m_GridRouting;
829  int col_max = end.x / RoutingMatrix.m_GridRouting;
830 
831  if( start.y > row_min * RoutingMatrix.m_GridRouting )
832  row_min++;
833 
834  if( start.x > col_min * RoutingMatrix.m_GridRouting )
835  col_min++;
836 
837  if( row_min < 0 )
838  row_min = 0;
839 
840  if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
841  row_max = RoutingMatrix.m_Nrows - 1;
842 
843  if( col_min < 0 )
844  col_min = 0;
845 
846  if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
847  col_max = RoutingMatrix.m_Ncols - 1;
848 
849  unsigned int keepOutCost = 0;
850 
851  for( int row = row_min; row <= row_max; row++ )
852  {
853  for( int col = col_min; col <= col_max; col++ )
854  {
855  // RoutingMatrix.GetDist returns the "cost" of the cell
856  // at position (row, col)
857  // in autoplace this is the cost of the cell, if it is
858  // inside aRect
859  keepOutCost += RoutingMatrix.GetDist( row, col, side );
860  }
861  }
862 
863  return keepOutCost;
864 }
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 904 of file auto_place_footprints.cpp.

References abs, EDA_RECT::Contains(), g_Offset_Module, D_PAD::GetParent(), MODULE::GetPosition(), D_PAD::GetPosition(), LOCAL_RATSNEST_ITEM, MATRIX_ROUTING_HEAD::m_BrdBox, BOARD::m_LocalRatsnest, RATSNEST_ITEM::m_PadEnd, RATSNEST_ITEM::m_PadStart, RATSNEST_ITEM::m_Status, BOARD::m_Status_Pcb, RATSNEST_ITEM_LOCAL_OK, RoutingMatrix, wxPoint::x, and wxPoint::y.

Referenced by getOptimalModulePlacement().

905 {
906  double curr_cost;
907  wxPoint start; // start point of a ratsnest
908  wxPoint end; // end point of a ratsnest
909  int dx, dy;
910 
911  if( ( aBrd->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK ) == 0 )
912  return -1;
913 
914  curr_cost = 0;
915 
916  for( unsigned ii = 0; ii < aBrd->m_LocalRatsnest.size(); ii++ )
917  {
918  RATSNEST_ITEM* pt_local_rats_nest = &aBrd->m_LocalRatsnest[ii];
919 
920  if( ( pt_local_rats_nest->m_Status & LOCAL_RATSNEST_ITEM ) )
921  continue; // Skip ratsnest between 2 pads of the current module
922 
923  // Skip modules not inside the board area
924  MODULE* module = pt_local_rats_nest->m_PadEnd->GetParent();
925 
926  if( !RoutingMatrix.m_BrdBox.Contains( module->GetPosition() ) )
927  continue;
928 
929  start = pt_local_rats_nest->m_PadStart->GetPosition() - g_Offset_Module;
930  end = pt_local_rats_nest->m_PadEnd->GetPosition();
931 
932  // Cost of the ratsnest.
933  dx = end.x - start.x;
934  dy = end.y - start.y;
935 
936  dx = abs( dx );
937  dy = abs( dy );
938 
939  // ttry to have always dx >= dy to calculate the cost of the rastsnet
940  if( dx < dy )
941  std::swap( dx, dy );
942 
943  // Cost of the connection = length + penalty due to the slope
944  // dx is the biggest length relative to the X or Y axis
945  // the penalty is max for 45 degrees ratsnests,
946  // and 0 for horizontal or vertical ratsnests.
947  // For Horizontal and Vertical ratsnests, dy = 0;
948  double conn_cost = hypot( dx, dy * 2.0 );
949  curr_cost += conn_cost; // Total cost = sum of costs of each connection
950  }
951 
952  return curr_cost;
953 }
std::vector< RATSNEST_ITEM > m_LocalRatsnest
Ratsnest list relative to a given footprint (used while moving a footprint).
Definition: class_board.h:251
wxPoint g_Offset_Module
Definition: pcbnew.cpp:83
bool Contains(const wxPoint &aPoint) const
Function Contains.
const wxPoint & GetPosition() const override
Definition: class_module.h:143
MODULE * GetParent() const
Definition: class_pad.h:108
#define abs(a)
Definition: auxiliary.h:84
D_PAD * m_PadEnd
Definition: class_netinfo.h:76
#define LOCAL_RATSNEST_ITEM
Definition: class_netinfo.h:61
const wxPoint & GetPosition() const override
Definition: class_pad.h:170
D_PAD * m_PadStart
Definition: class_netinfo.h:75
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
Class RATSNEST_ITEM describes a ratsnest line: a straight line connecting 2 pads. ...
Definition: class_netinfo.h:68
EDA_RECT m_BrdBox
Definition: autorout.h:115
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:240
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 966 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().

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

References GRRect().

Referenced by getOptimalModulePlacement().

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

Definition at line 412 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().

413 {
414  int ii, jj;
415  COLOR4D color;
416  int ox, oy;
417  MATRIX_CELL top_state, bottom_state;
418 
419  GRSetDrawMode( DC, GR_COPY );
420 
421  for( ii = 0; ii < RoutingMatrix.m_Nrows; ii++ )
422  {
424 
425  for( jj = 0; jj < RoutingMatrix.m_Ncols; jj++ )
426  {
428  color = COLOR4D::BLACK;
429 
430  top_state = RoutingMatrix.GetCell( ii, jj, TOP );
431  bottom_state = RoutingMatrix.GetCell( ii, jj, BOTTOM );
432 
433  if( top_state & CELL_is_ZONE )
434  color = COLOR4D( BLUE );
435 
436  // obstacles
437  if( ( top_state & CELL_is_EDGE ) || ( bottom_state & CELL_is_EDGE ) )
438  color = COLOR4D::WHITE;
439  else if( top_state & ( HOLE | CELL_is_MODULE ) )
440  color = COLOR4D( LIGHTRED );
441  else if( bottom_state & (HOLE | CELL_is_MODULE) )
442  color = COLOR4D( LIGHTGREEN );
443  else // Display the filling and keep out regions.
444  {
445  if( RoutingMatrix.GetDist( ii, jj, TOP )
446  || RoutingMatrix.GetDist( ii, jj, BOTTOM ) )
447  color = DARKGRAY;
448  }
449 
450  GRPutPixel( NULL, DC, ox, oy, color );
451  }
452  }
453 }
Definition: colors.h:57
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:290
#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:339
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 549 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().

550 {
551  int ox, oy, fx, fy;
552  LSET layerMask;
553  D_PAD* Pad;
554 
555  EDA_RECT fpBBox = Module->GetBoundingBox();
556 
557  fpBBox.Inflate( RoutingMatrix.m_GridRouting / 2 );
558  ox = fpBBox.GetX();
559  fx = fpBBox.GetRight();
560  oy = fpBBox.GetY();
561  fy = fpBBox.GetBottom();
562 
563  if( ox < RoutingMatrix.m_BrdBox.GetX() )
564  ox = RoutingMatrix.m_BrdBox.GetX();
565 
566  if( ox > RoutingMatrix.m_BrdBox.GetRight() )
568 
569  if( fx < RoutingMatrix.m_BrdBox.GetX() )
570  fx = RoutingMatrix.m_BrdBox.GetX();
571 
572  if( fx > RoutingMatrix.m_BrdBox.GetRight() )
574 
575  if( oy < RoutingMatrix.m_BrdBox.GetY() )
576  oy = RoutingMatrix.m_BrdBox.GetY();
577 
578  if( oy > RoutingMatrix.m_BrdBox.GetBottom() )
580 
581  if( fy < RoutingMatrix.m_BrdBox.GetY() )
582  fy = RoutingMatrix.m_BrdBox.GetY();
583 
584  if( fy > RoutingMatrix.m_BrdBox.GetBottom() )
586 
587  if( Module->GetLayer() == F_Cu )
588  layerMask.set( F_Cu );
589 
590  if( Module->GetLayer() == B_Cu )
591  layerMask.set( B_Cu );
592 
593  TraceFilledRectangle( ox, oy, fx, fy, layerMask,
595 
596  // Trace pads + clearance areas.
597  for( Pad = Module->Pads(); Pad != NULL; Pad = Pad->Next() )
598  {
599  int margin = (RoutingMatrix.m_GridRouting / 2) + Pad->GetClearance();
600  ::PlacePad( Pad, CELL_is_MODULE, margin, WRITE_OR_CELL );
601  }
602 
603  // Trace clearance.
604  int margin = ( RoutingMatrix.m_GridRouting * Module->GetPadCount() ) / GAIN;
605  CreateKeepOutRectangle( ox, oy, fx, fy, margin, KEEP_OUT_MARGIN, layerMask );
606 }
void TraceFilledRectangle(int ux0, int uy0, int ux1, int uy1, LSET side, int color, int op_logic)
Definition: graphpcb.cpp:478
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:106
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
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
#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:455
int GetY() const
void PlacePad(D_PAD *pt_pad, int type, int marge, int op_logic)
Definition: graphpcb.cpp:87
DLIST< D_PAD > & Pads()
Definition: class_module.h:133
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 456 of file auto_place_footprints.cpp.

References B_Cu, BOTTOM, CELL_is_EDGE, CELL_is_ZONE, MATRIX_ROUTING_HEAD::ComputeMatrixSize(), CYAN, DisplayError(), 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, BOARD::m_Drawings, 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, EDA_ITEM::Next(), 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(), EDA_ITEM::Type(), UNDEFINED_LAYER, MATRIX_ROUTING_HEAD::UnInitRoutingMatrix(), WRITE_CELL, and YELLOW.

Referenced by PCB_EDIT_FRAME::AutoPlaceModule().

457 {
458  wxString msg;
459 
461 
462  EDA_RECT bbox = aBrd->GetBoardEdgesBoundingBox();
463 
464  if( bbox.GetWidth() == 0 || bbox.GetHeight() == 0 )
465  {
466  DisplayError( NULL, _( "No PCB edge found, unknown board size!" ) );
467  return 0;
468  }
469 
470  RoutingMatrix.ComputeMatrixSize( aBrd, true );
471  int nbCells = RoutingMatrix.m_Ncols * RoutingMatrix.m_Nrows;
472 
473  messagePanel->EraseMsgBox();
474  msg.Printf( wxT( "%d" ), RoutingMatrix.m_Ncols );
475  messagePanel->SetMessage( 1, _( "Cols" ), msg, GREEN );
476  msg.Printf( wxT( "%d" ), RoutingMatrix.m_Nrows );
477  messagePanel->SetMessage( 7, _( "Lines" ), msg, GREEN );
478  msg.Printf( wxT( "%d" ), nbCells );
479  messagePanel->SetMessage( 14, _( "Cells." ), msg, YELLOW );
480 
481  // Choose the number of board sides.
483 
485 
486  // Display memory usage.
487  msg.Printf( wxT( "%d" ), RoutingMatrix.m_MemSize / 1024 );
488  messagePanel->SetMessage( 24, wxT( "Mem(Kb)" ), msg, CYAN );
489 
491 
494 
496 
497  // Place the edge layer segments
498  TRACK TmpSegm( NULL );
499 
500  TmpSegm.SetLayer( UNDEFINED_LAYER );
501  TmpSegm.SetNetCode( -1 );
502  TmpSegm.SetWidth( RoutingMatrix.m_GridRouting / 2 );
503 
504  EDA_ITEM* PtStruct = aBrd->m_Drawings;
505 
506  for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
507  {
508  DRAWSEGMENT* DrawSegm;
509 
510  switch( PtStruct->Type() )
511  {
512  case PCB_LINE_T:
513  DrawSegm = (DRAWSEGMENT*) PtStruct;
514 
515  if( DrawSegm->GetLayer() != Edge_Cuts )
516  break;
517 
518  TraceSegmentPcb( DrawSegm, HOLE | CELL_is_EDGE,
520  break;
521 
522  case PCB_TEXT_T:
523  default:
524  break;
525  }
526  }
527 
528  // Mark cells of the routing matrix to CELL_is_ZONE
529  // (i.e. availlable cell to place a module )
530  // Init a starting point of attachment to the area.
532  BOTTOM, CELL_is_ZONE );
533 
534  // find and mark all other availlable cells:
535  for( int ii = 1; ii != 0; )
536  ii = propagate();
537 
538  // Initialize top layer. to the same value as the bottom layer
541  nbCells * sizeof(MATRIX_CELL) );
542 
543  return 1;
544 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
PCB_LAYER_ID g_Route_Layer_TOP
Definition: pcbnew.cpp:78
PCB_LAYER_ID g_Route_Layer_BOTTOM
Definition: pcbnew.cpp:79
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...
#define CELL_is_EDGE
Definition: cell.h:42
int GetHeight() const
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
#define WRITE_CELL
Definition: autorout.h:190
EDA_ITEM * Next() const
Definition: base_struct.h:206
#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:839
MATRIX_CELL * m_BoardSide[MAX_ROUTING_LAYERS_COUNT]
Definition: autorout.h:107
Definition: colors.h:59
DLIST< BOARD_ITEM > m_Drawings
Definition: class_board.h:242
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...
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void OrCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: colors.h:58
Class EDA_RECT handles the component boundary box.
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
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:103
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:69
#define HOLE
Definition: cell.h:40
#define CELL_is_ZONE
Definition: cell.h:44
int getOptimalModulePlacement ( PCB_EDIT_FRAME aFrame,
MODULE aModule,
wxDC *  aDC 
)
static

Definition at line 618 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(), LISTE_PAD_OK, MATRIX_ROUTING_HEAD::m_BrdBox, MATRIX_ROUTING_HEAD::m_GridRouting, MATRIX_ROUTING_HEAD::m_RoutingLayersCount, DISPLAY_OPTIONS::m_Show_Module_Ratsnest, BOARD::m_Status_Pcb, MinCout, EDA_RECT::Move(), D_PAD::Next(), 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().

619 {
620  int error = 1;
621  wxPoint LastPosOK;
622  double min_cost, curr_cost, Score;
623  bool TstOtherSide;
624  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)aFrame->GetDisplayOptions();
625  BOARD* brd = aFrame->GetBoard();
626 
627  aModule->CalculateBoundingBox();
628 
629  bool showRats = displ_opts->m_Show_Module_Ratsnest;
630  displ_opts->m_Show_Module_Ratsnest = false;
631 
633  aFrame->SetMsgPanel( aModule );
634 
635  LastPosOK = RoutingMatrix.m_BrdBox.GetOrigin();
636 
637  wxPoint mod_pos = aModule->GetPosition();
638  EDA_RECT fpBBox = aModule->GetFootprintRect();
639 
640  // Move fpBBox to have the footprint position at (0,0)
641  fpBBox.Move( -mod_pos );
642  wxPoint fpBBoxOrg = fpBBox.GetOrigin();
643 
644  // Calculate the limit of the footprint position, relative
645  // to the routing matrix area
646  wxPoint xylimit = RoutingMatrix.m_BrdBox.GetEnd() - fpBBox.GetEnd();
647 
648  wxPoint initialPos = RoutingMatrix.m_BrdBox.GetOrigin() - fpBBoxOrg;
649 
650  // Stay on grid.
651  initialPos.x -= initialPos.x % RoutingMatrix.m_GridRouting;
652  initialPos.y -= initialPos.y % RoutingMatrix.m_GridRouting;
653 
654  CurrPosition = initialPos;
655 
656  // Undraw the current footprint
657  aModule->DrawOutlinesWhenMoving( aFrame->GetCanvas(), aDC, wxPoint( 0, 0 ) );
658 
659  g_Offset_Module = mod_pos - CurrPosition;
660 
661  /* Examine pads, and set TstOtherSide to true if a footprint
662  * has at least 1 pad through.
663  */
664  TstOtherSide = false;
665 
667  {
668  LSET other( aModule->GetLayer() == B_Cu ? F_Cu : B_Cu );
669 
670  for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
671  {
672  if( !( pad->GetLayerSet() & other ).any() )
673  continue;
674 
675  TstOtherSide = true;
676  break;
677  }
678  }
679 
680  // Draw the initial bounding box position
681  COLOR4D color = COLOR4D( BROWN );
682  fpBBox.SetOrigin( fpBBoxOrg + CurrPosition );
683  draw_FootprintRect(aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color);
684 
685  min_cost = -1.0;
686  aFrame->SetStatusText( wxT( "Score ??, pos ??" ) );
687 
688  for( ; CurrPosition.x < xylimit.x; CurrPosition.x += RoutingMatrix.m_GridRouting )
689  {
690  wxYield();
691 
692  if( aFrame->GetCanvas()->GetAbortRequest() )
693  {
694  if( IsOK( aFrame, _( "OK to abort?" ) ) )
695  {
696  displ_opts->m_Show_Module_Ratsnest = showRats;
697  return ESC;
698  }
699  else
700  aFrame->GetCanvas()->SetAbortRequest( false );
701  }
702 
703  CurrPosition.y = initialPos.y;
704 
705  for( ; CurrPosition.y < xylimit.y; CurrPosition.y += RoutingMatrix.m_GridRouting )
706  {
707  // Erase traces.
708  draw_FootprintRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color );
709 
710  fpBBox.SetOrigin( fpBBoxOrg + CurrPosition );
711  g_Offset_Module = mod_pos - CurrPosition;
712  int keepOutCost = TstModuleOnBoard( brd, aModule, TstOtherSide );
713 
714  // Draw at new place
715  color = keepOutCost >= 0 ? BROWN : RED;
716  draw_FootprintRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color );
717 
718  if( keepOutCost >= 0 ) // i.e. if the module can be put here
719  {
720  error = 0;
721  aFrame->build_ratsnest_module( aModule );
722  curr_cost = compute_Ratsnest_PlaceModule( brd );
723  Score = curr_cost + keepOutCost;
724 
725  if( (min_cost >= Score ) || (min_cost < 0 ) )
726  {
727  LastPosOK = CurrPosition;
728  min_cost = Score;
729  wxString msg;
730  msg.Printf( wxT( "Score %g, pos %s, %s" ),
731  min_cost,
732  GetChars( ::CoordinateToString( LastPosOK.x ) ),
733  GetChars( ::CoordinateToString( LastPosOK.y ) ) );
734  aFrame->SetStatusText( msg );
735  }
736  }
737  }
738  }
739 
740  // erasing the last traces
741  GRRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, 0, BROWN );
742 
743  displ_opts->m_Show_Module_Ratsnest = showRats;
744 
745  // Regeneration of the modified variable.
746  CurrPosition = LastPosOK;
747 
749 
750  MinCout = min_cost;
751  return error;
752 }
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:117
static wxPoint CurrPosition
wxPoint g_Offset_Module
Definition: pcbnew.cpp:83
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
static int TstModuleOnBoard(BOARD *Pcb, MODULE *Module, bool TstOtherSide)
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:299
double MinCout
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
const wxPoint & GetPosition() const override
Definition: class_module.h:143
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...
const wxPoint & GetOrigin() const
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1077
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:754
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text...
void build_ratsnest_module(MODULE *aModule)
Function build_ratsnest_module Build a ratsnest relative to one footprint.
Definition: ratsnest.cpp:533
D_PAD * Next() const
Definition: class_pad.h:106
EDA_RECT * GetClipBox()
Definition: colors.h:60
void SetAbortRequest(bool aAbortRequest)
const wxPoint GetEnd() const
Class DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
Definition: pcbstruct.h:62
MATRIX_ROUTING_HEAD RoutingMatrix
Definition: autorout.cpp:51
bool GetAbortRequest() const
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
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:166
void draw_FootprintRect(EDA_RECT *aClipBox, wxDC *aDC, EDA_RECT &fpBBox, COLOR4D aColor)
Class EDA_RECT handles the component boundary box.
DLIST< D_PAD > & Pads()
Definition: class_module.h:133
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: modules.cpp:492
bool m_Show_Module_Ratsnest
Definition: pcbstruct.h:87
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:111
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:240
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 1098 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_LocalRatsnest, 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().

1099 {
1100  MODULE* Module;
1101  std::vector <MODULE*> moduleList;
1102 
1103  // Build sorted footprints list (sort by decreasing size )
1104  Module = pcbframe->GetBoard()->m_Modules;
1105 
1106  for( ; Module != NULL; Module = Module->Next() )
1107  {
1108  Module->CalculateBoundingBox();
1109  moduleList.push_back( Module );
1110  }
1111 
1112  sort( moduleList.begin(), moduleList.end(), Tri_PlaceModules );
1113 
1114  for( unsigned kk = 0; kk < moduleList.size(); kk++ )
1115  {
1116  Module = moduleList[kk];
1117  Module->SetFlag( 0 );
1118 
1119  if( !Module->NeedsPlaced() )
1120  continue;
1121 
1122  pcbframe->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
1123  pcbframe->SetMsgPanel( Module );
1124  pcbframe->build_ratsnest_module( Module );
1125 
1126  // Calculate external ratsnest.
1127  for( unsigned ii = 0; ii < pcbframe->GetBoard()->m_LocalRatsnest.size(); ii++ )
1128  {
1129  if( ( pcbframe->GetBoard()->m_LocalRatsnest[ii].m_Status &
1130  LOCAL_RATSNEST_ITEM ) == 0 )
1131  Module->IncrementFlag();
1132  }
1133  }
1134 
1135  pcbframe->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
1136 
1137  sort( moduleList.begin(), moduleList.end(), sortFootprintsByRatsnestSize );
1138 
1139  // Search for "best" module.
1140  MODULE* bestModule = NULL;
1141  MODULE* altModule = NULL;
1142 
1143  for( unsigned ii = 0; ii < moduleList.size(); ii++ )
1144  {
1145  Module = moduleList[ii];
1146 
1147  if( !Module->NeedsPlaced() )
1148  continue;
1149 
1150  altModule = Module;
1151 
1152  if( Module->GetFlag() == 0 )
1153  continue;
1154 
1155  bestModule = Module;
1156  break;
1157  }
1158 
1159  if( bestModule )
1160  return bestModule;
1161  else
1162  return altModule;
1163 }
std::vector< RATSNEST_ITEM > m_LocalRatsnest
Ratsnest list relative to a given footprint (used while moving a footprint).
Definition: class_board.h:251
int GetFlag() const
Definition: class_module.h:189
void IncrementFlag()
Definition: class_module.h:188
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:99
BOARD * GetBoard() const
bool NeedsPlaced() const
Definition: class_module.h:250
#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:754
void build_ratsnest_module(MODULE *aModule)
Function build_ratsnest_module Build a ratsnest relative to one footprint.
Definition: ratsnest.cpp:533
static bool Tri_PlaceModules(MODULE *ref, MODULE *compare)
DLIST< MODULE > m_Modules
Definition: class_board.h:243
void SetFlag(int aFlag)
Definition: class_module.h:187
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:240
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 1190 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().

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

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

Referenced by PickModule().

1082 {
1083  double ff1, ff2;
1084 
1085  ff1 = ref->GetArea() * ref->GetFlag();
1086  ff2 = compare->GetArea() * compare->GetFlag();
1087  return ff2 < ff1;
1088 }
int GetFlag() const
Definition: class_module.h:189
double GetArea() const
Definition: class_module.h:515
static bool Tri_PlaceModules ( MODULE ref,
MODULE compare 
)
static

Definition at line 1070 of file auto_place_footprints.cpp.

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

Referenced by PickModule().

1071 {
1072  double ff1, ff2;
1073 
1074  ff1 = ref->GetArea() * ref->GetPadCount();
1075  ff2 = compare->GetArea() * compare->GetPadCount();
1076 
1077  return ff2 < ff1;
1078 }
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:515
int TstModuleOnBoard ( BOARD Pcb,
MODULE Module,
bool  TstOtherSide 
)
static

Definition at line 871 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().

872 {
873  int side = TOP;
874  int otherside = BOTTOM;
875 
876  if( aModule->GetLayer() == B_Cu )
877  {
878  side = BOTTOM; otherside = TOP;
879  }
880 
881  EDA_RECT fpBBox = aModule->GetFootprintRect();
882  fpBBox.Move( -g_Offset_Module );
883 
884  int diag = TstRectangle( Pcb, fpBBox, side );
885 
886  if( diag != FREE_CELL )
887  return diag;
888 
889  if( TstOtherSide )
890  {
891  diag = TstRectangle( Pcb, fpBBox, otherside );
892 
893  if( diag != FREE_CELL )
894  return diag;
895  }
896 
897  int marge = ( RoutingMatrix.m_GridRouting * aModule->GetPadCount() ) / GAIN;
898 
899  fpBBox.Inflate( marge );
900  return CalculateKeepOutArea( fpBBox, side );
901 }
wxPoint g_Offset_Module
Definition: pcbnew.cpp:83
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 761 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().

762 {
763  EDA_RECT rect = aRect;
764 
765  rect.Inflate( RoutingMatrix.m_GridRouting / 2 );
766 
767  wxPoint start = rect.GetOrigin();
768  wxPoint end = rect.GetEnd();
769 
770  start -= RoutingMatrix.m_BrdBox.GetOrigin();
772 
773  int row_min = start.y / RoutingMatrix.m_GridRouting;
774  int row_max = end.y / RoutingMatrix.m_GridRouting;
775  int col_min = start.x / RoutingMatrix.m_GridRouting;
776  int col_max = end.x / RoutingMatrix.m_GridRouting;
777 
778  if( start.y > row_min * RoutingMatrix.m_GridRouting )
779  row_min++;
780 
781  if( start.x > col_min * RoutingMatrix.m_GridRouting )
782  col_min++;
783 
784  if( row_min < 0 )
785  row_min = 0;
786 
787  if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
788  row_max = RoutingMatrix.m_Nrows - 1;
789 
790  if( col_min < 0 )
791  col_min = 0;
792 
793  if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
794  col_max = RoutingMatrix.m_Ncols - 1;
795 
796  for( int row = row_min; row <= row_max; row++ )
797  {
798  for( int col = col_min; col <= col_max; col++ )
799  {
800  unsigned int data = RoutingMatrix.GetCell( row, col, side );
801 
802  if( ( data & CELL_is_ZONE ) == 0 )
803  return OUT_OF_BOARD;
804 
805  if( (data & CELL_is_MODULE) )
806  return OCCUPED_By_MODULE;
807  }
808  }
809 
810  return FREE_CELL;
811 }
MATRIX_CELL GetCell(int aRow, int aCol, int aSide)
#define OCCUPED_By_MODULE
const wxPoint & GetOrigin() const
#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 62 of file auto_place_footprints.cpp.

Referenced by PCB_EDIT_FRAME::AutoPlaceModule().