KiCad PCB EDA Suite
AR_AUTOPLACER Class Reference

#include <ar_autoplacer.h>

Public Member Functions

 AR_AUTOPLACER (BOARD *aBoard)
 
AR_RESULT AutoplaceModules (std::vector< MODULE * > aModules, BOARD_COMMIT *aCommit, bool aPlaceOffboardModules=false)
 
const std::vector< MODULE * > QueryOffboardModules ()
 
void SetPlacementGrid (int aGrid)
 
void SetOverlay (std::shared_ptr< KIGFX::VIEW_OVERLAY > aOverlay)
 
void SetRefreshCallback (std::function< int()> aCallback)
 
void SetProgressReporter (PROGRESS_REPORTER *aReporter)
 

Private Member Functions

void drawPlacementRoutingMatrix ()
 
void rotateModule (MODULE *module, double angle, bool incremental)
 
int genPlacementRoutingMatrix ()
 
void genModuleOnRoutingMatrix (MODULE *Module)
 
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...
 
int testRectangle (const EDA_RECT &aRect, int side)
 
unsigned int calculateKeepOutArea (const EDA_RECT &aRect, int side)
 
int testModuleOnBoard (MODULE *aModule, bool TstOtherSide, const wxPoint &aOffset)
 
int getOptimalModulePlacement (MODULE *aModule)
 
double computePlacementRatsnestCost (MODULE *aModule, const wxPoint &aOffset)
 
MODULEpickModule ()
 Function Module find the "best" module place The criteria are: More...
 
void placeModule (MODULE *aModule, bool aDoNotRecreateRatsnest, const wxPoint &aPos)
 
const D_PADnearestPad (MODULE *aRefModule, D_PAD *aRefPad, const wxPoint &aOffset)
 

Private Attributes

AR_MATRIX m_matrix
 
BOARDm_board
 
wxPoint m_curPosition
 
wxPoint m_moduleOffset
 
double m_minCost
 
int m_gridSize
 
std::shared_ptr< KIGFX::VIEW_OVERLAYm_overlay
 
std::unique_ptr< CONNECTIVITY_DATAm_connectivity
 
std::function< int()> m_refreshCallback
 
PROGRESS_REPORTERm_progressReporter
 

Detailed Description

Definition at line 58 of file ar_autoplacer.h.

Constructor & Destructor Documentation

AR_AUTOPLACER::AR_AUTOPLACER ( BOARD aBoard)

Definition at line 77 of file ar_autoplacer.cpp.

References m_board, m_connectivity, m_gridSize, m_progressReporter, m_refreshCallback, mod, and BOARD::Modules().

78 {
79  m_board = aBoard;
80  m_connectivity.reset( new CONNECTIVITY_DATA );
81 
82  for( auto mod : m_board->Modules() )
83  m_connectivity->Add( mod );
84 
85  m_gridSize = Millimeter2iu( 0.5 );
86  m_progressReporter = nullptr;
87  m_refreshCallback = nullptr;
88 }
PROGRESS_REPORTER * m_progressReporter
DLIST_ITERATOR_WRAPPER< MODULE > Modules()
Definition: class_board.h:254
std::function< int()> m_refreshCallback
#define mod(a, n)
Definition: greymap.cpp:24
std::unique_ptr< CONNECTIVITY_DATA > m_connectivity

Member Function Documentation

AR_RESULT AR_AUTOPLACER::AutoplaceModules ( std::vector< MODULE * >  aModules,
BOARD_COMMIT aCommit,
bool  aPlaceOffboardModules = false 
)

Definition at line 869 of file ar_autoplacer.cpp.

References PROGRESS_REPORTER::AdvanceProgress(), AR_ABORT_PLACEMENT, AR_CANCELLED, AR_COMPLETED, AR_FAILURE, MODULE::CalculateBoundingBox(), EDA_RECT::Contains(), drawPlacementRoutingMatrix(), genModuleOnRoutingMatrix(), genPlacementRoutingMatrix(), getOptimalModulePlacement(), MODULE::GetOrientation(), MODULE::GetPlacementCost180(), MODULE::GetPlacementCost90(), PROGRESS_REPORTER::KeepRefreshing(), m_board, AR_MATRIX::m_BrdBox, m_curPosition, AR_MATRIX::m_GridRouting, m_gridSize, m_matrix, m_minCost, m_progressReporter, COMMIT::Modify(), BOARD::Modules(), OrientationPenalty, pickModule(), placeModule(), PROGRESS_REPORTER::Report(), rotateModule(), MODULE::SetIsPlaced(), PROGRESS_REPORTER::SetMaxProgress(), MODULE::SetNeedsPlaced(), and AR_MATRIX::UnInitRoutingMatrix().

Referenced by AUTOPLACE_TOOL::autoplace().

870 {
871  wxPoint PosOK;
872  wxPoint memopos;
873  int error;
874  MODULE* module = nullptr;
875  bool cancelled = false;
876 
877  memopos = m_curPosition;
878 
879  //printf("set grid: %d\n", m_gridSize);
880 
881  m_matrix.m_GridRouting = m_gridSize; //(int) m_frame->GetScreen()->GetGridSize().x;
882 
883  // Ensure Board.m_GridRouting has a reasonable value:
884  if( m_matrix.m_GridRouting < Millimeter2iu( 0.25 ) )
885  m_matrix.m_GridRouting = Millimeter2iu( 0.25 );
886 
887  // Compute module parameters used in auto place
888  if( genPlacementRoutingMatrix( ) == 0 )
889  return AR_FAILURE;
890 
891  int moduleCount = 0;
892 
893  for ( auto m : m_board->Modules() )
894  {
895  m->SetNeedsPlaced( false );
896  }
897 
898  std::vector<MODULE *> offboardMods;
899 
900  if( aPlaceOffboardModules )
901  {
902  for ( auto m : m_board->Modules() )
903  {
904  if( !m_matrix.m_BrdBox.Contains( m->GetPosition() ) )
905  {
906  offboardMods.push_back( m );
907  }
908  }
909  }
910 
911  for ( auto m : aModules )
912  {
913  m->SetNeedsPlaced( true );
914  aCommit->Modify(m);
915  }
916 
917  for ( auto m : offboardMods )
918  {
919  m->SetNeedsPlaced( true );
920  aCommit->Modify(m);
921  }
922 
923  for ( auto m : m_board->Modules() )
924  {
925  if( m->NeedsPlaced() ) // Erase from screen
926  {
927  moduleCount++;
928  }
929  else
930  {
932  }
933  }
934 
936 
937  int cnt = 0;
938  wxString msg;
939 
940  if( m_progressReporter )
941  {
942  m_progressReporter->Report( _( "Autoplacing components..." ) );
943  m_progressReporter->SetMaxProgress( moduleCount );
944  }
945 
946  while( ( module = pickModule( ) ) != nullptr )
947  {
948  // Display some info about activity, module placement can take a while:
949  //printf( _( "Place footprint %d of %d [%s]\n" ), cnt, moduleCount, (const char *)module->GetReference().c_str() );
950  //m_frame->SetStatusText( msg );
951 
952  double initialOrient = module->GetOrientation();
953  // Display fill area of interest, barriers, penalties.
954  //drawPlacementRoutingMatrix( );
955 
956  error = getOptimalModulePlacement( module );
957  double bestScore = m_minCost;
958  double bestRotation = 0.0;
959  int rotAllowed;
960  PosOK = m_curPosition;
961 
962  if( error == AR_ABORT_PLACEMENT )
963  goto end_of_tst;
964 
965  // Try orientations 90, 180, 270 degrees from initial orientation
966  rotAllowed = module->GetPlacementCost180();
967 
968  //printf("rotAllowed %d\n", rotAllowed);
969 
970  if( rotAllowed != 0 )
971  {
972  rotateModule( module, 1800.0, true );
973  error = getOptimalModulePlacement( module );
974  m_minCost *= OrientationPenalty[rotAllowed];
975 
976  if( bestScore > m_minCost ) // This orientation is better.
977  {
978  PosOK = m_curPosition;
979  bestScore = m_minCost;
980  bestRotation = 1800.0;
981  }
982  else
983  {
984  rotateModule( module, initialOrient, false );
985  }
986 
987  if( error == AR_ABORT_PLACEMENT )
988  goto end_of_tst;
989  }
990 
991  // Determine if the best orientation of a module is 90.
992  rotAllowed = module->GetPlacementCost90();
993  if( rotAllowed != 0 )
994  {
995  rotateModule( module, 900.0, true );
996  error = getOptimalModulePlacement( module );
997  m_minCost *= OrientationPenalty[rotAllowed];
998 
999  if( bestScore > m_minCost ) // This orientation is better.
1000  {
1001  PosOK = m_curPosition;
1002  bestScore = m_minCost;
1003  bestRotation = 900.0;
1004  }
1005  else
1006  {
1007  rotateModule( module, initialOrient, false );
1008  }
1009 
1010  if( error == AR_ABORT_PLACEMENT )
1011  goto end_of_tst;
1012  }
1013 
1014  // Determine if the best orientation of a module is -90.
1015  if( rotAllowed != 0 )
1016  {
1017  rotateModule( module, 2700.0, true );
1018  error = getOptimalModulePlacement( module );
1019  m_minCost *= OrientationPenalty[rotAllowed];
1020 
1021  if( bestScore > m_minCost ) // This orientation is better.
1022  {
1023  PosOK = m_curPosition;
1024  bestScore = m_minCost;
1025  bestRotation = 2700.0;
1026  }
1027  else
1028  {
1029  rotateModule( module, initialOrient, false );
1030  }
1031 
1032  if( error == AR_ABORT_PLACEMENT )
1033  goto end_of_tst;
1034  }
1035 
1036 end_of_tst:
1037 
1038  if( error == AR_ABORT_PLACEMENT )
1039  break;
1040 
1041 
1042  bestRotation += initialOrient;
1043 
1044  if( bestRotation != module->GetOrientation() )
1045  {
1046  //printf("best rotation %d\n", bestRotation );
1047  rotateModule( module, bestRotation, false );
1048  }
1049 
1050  // Place module.
1051  placeModule( module, true, m_curPosition );
1052 
1053  module->CalculateBoundingBox();
1054  genModuleOnRoutingMatrix( module );
1055  module->SetIsPlaced( true );
1056  module->SetNeedsPlaced( false );
1057 
1058 
1059  if( m_progressReporter )
1060  {
1062  if ( !m_progressReporter->KeepRefreshing( false ) )
1063  {
1064  cancelled = true;
1065  break;
1066  }
1067  }
1068  cnt++;
1069  }
1070 
1071  m_curPosition = memopos;
1072 
1074 
1075  for ( auto m : m_board->Modules() )
1076  {
1077  m->CalculateBoundingBox();
1078  }
1079 
1080  return cancelled ? AR_CANCELLED : AR_COMPLETED;
1081 }
void rotateModule(MODULE *module, double angle, bool incremental)
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
PROGRESS_REPORTER * m_progressReporter
void placeModule(MODULE *aModule, bool aDoNotRecreateRatsnest, const wxPoint &aPos)
bool Contains(const wxPoint &aPoint) const
Function Contains.
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
int m_GridRouting
Definition: ar_matrix.h:63
EDA_RECT m_BrdBox
Definition: ar_matrix.h:64
void SetNeedsPlaced(bool needsPlaced)
Definition: class_module.h:296
void Report(const wxString &aMessage)
Display aMessage in the progress bar dialog.
int GetPlacementCost90() const
Definition: class_module.h:583
void genModuleOnRoutingMatrix(MODULE *Module)
AR_MATRIX m_matrix
void drawPlacementRoutingMatrix()
DLIST_ITERATOR_WRAPPER< MODULE > Modules()
Definition: class_board.h:254
int getOptimalModulePlacement(MODULE *aModule)
double GetOrientation() const
Definition: class_module.h:189
int genPlacementRoutingMatrix()
#define AR_ABORT_PLACEMENT
MODULE * pickModule()
Function Module find the "best" module place The criteria are:
void SetIsPlaced(bool isPlaced)
Definition: class_module.h:287
void UnInitRoutingMatrix()
Definition: ar_matrix.cpp:140
bool KeepRefreshing(bool aWait=false)
Update the UI dialog.
static const double OrientationPenalty[11]
wxPoint m_curPosition
void SetMaxProgress(int aMaxProgress)
Fix the value thar gives the 100 precent progress bar length (inside the current virtual zone) ...
void AdvanceProgress()
Increment the progress bar length (inside the current virtual zone)
int GetPlacementCost180() const
Definition: class_module.h:580
unsigned int AR_AUTOPLACER::calculateKeepOutArea ( const EDA_RECT aRect,
int  side 
)
private

Definition at line 452 of file ar_autoplacer.cpp.

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

Referenced by SetProgressReporter(), and testModuleOnBoard().

453 {
454  wxPoint start = aRect.GetOrigin();
455  wxPoint end = aRect.GetEnd();
456 
457  start -= m_matrix.m_BrdBox.GetOrigin();
458  end -= m_matrix.m_BrdBox.GetOrigin();
459 
460  int row_min = start.y / m_matrix.m_GridRouting;
461  int row_max = end.y / m_matrix.m_GridRouting;
462  int col_min = start.x / m_matrix.m_GridRouting;
463  int col_max = end.x / m_matrix.m_GridRouting;
464 
465  if( start.y > row_min * m_matrix.m_GridRouting )
466  row_min++;
467 
468  if( start.x > col_min * m_matrix.m_GridRouting )
469  col_min++;
470 
471  if( row_min < 0 )
472  row_min = 0;
473 
474  if( row_max >= ( m_matrix.m_Nrows - 1 ) )
475  row_max = m_matrix.m_Nrows - 1;
476 
477  if( col_min < 0 )
478  col_min = 0;
479 
480  if( col_max >= ( m_matrix.m_Ncols - 1 ) )
481  col_max = m_matrix.m_Ncols - 1;
482 
483  unsigned int keepOutCost = 0;
484 
485  for( int row = row_min; row <= row_max; row++ )
486  {
487  for( int col = col_min; col <= col_max; col++ )
488  {
489  // m_matrix.GetDist returns the "cost" of the cell
490  // at position (row, col)
491  // in autoplace this is the cost of the cell, if it is
492  // inside aRect
493  keepOutCost += m_matrix.GetDist( row, col, side );
494  }
495  }
496 
497  return keepOutCost;
498 }
const wxPoint GetOrigin() const
Definition: eda_rect.h:112
int m_Ncols
Definition: ar_matrix.h:65
int m_GridRouting
Definition: ar_matrix.h:63
EDA_RECT m_BrdBox
Definition: ar_matrix.h:64
AR_MATRIX m_matrix
int m_Nrows
Definition: ar_matrix.h:65
const wxPoint GetEnd() const
Definition: eda_rect.h:114
DIST_CELL GetDist(int aRow, int aCol, int aSide)
Definition: ar_matrix.cpp:259
double AR_AUTOPLACER::computePlacementRatsnestCost ( MODULE aModule,
const wxPoint aOffset 
)
private

Definition at line 675 of file ar_autoplacer.cpp.

References abs, nearestPad(), MODULE::Pads(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by getOptimalModulePlacement(), and SetProgressReporter().

676 {
677  double curr_cost;
678  VECTOR2I start; // start point of a ratsnest
679  VECTOR2I end; // end point of a ratsnest
680  int dx, dy;
681 
682  curr_cost = 0;
683 
684  for ( auto pad : aModule->Pads() )
685  {
686  auto nearest = nearestPad( aModule, pad, aOffset );
687 
688  if( !nearest )
689  continue;
690 
691  //printf("pad %s nearest %s\n", (const char *)aModule->GetReference().c_str(), (const char *)nearest->GetParent()->GetReference().c_str());
692 
693  start = VECTOR2I( pad->GetPosition() ) - VECTOR2I(aOffset);
694  end = VECTOR2I( nearest->GetPosition() );
695 
696  //m_overlay->SetIsStroke( true );
697  //m_overlay->SetStrokeColor( COLOR4D(0.0, 1.0, 0.0, 1.0) );
698  //m_overlay->Line( start, end );
699 
700  // Cost of the ratsnest.
701  dx = end.x - start.x;
702  dy = end.y - start.y;
703 
704  dx = abs( dx );
705  dy = abs( dy );
706 
707  // ttry to have always dx >= dy to calculate the cost of the rastsnet
708  if( dx < dy )
709  std::swap( dx, dy );
710 
711  // Cost of the connection = length + penalty due to the slope
712  // dx is the biggest length relative to the X or Y axis
713  // the penalty is max for 45 degrees ratsnests,
714  // and 0 for horizontal or vertical ratsnests.
715  // For Horizontal and Vertical ratsnests, dy = 0;
716  double conn_cost = hypot( dx, dy * 2.0 );
717  curr_cost += conn_cost; // Total cost = sum of costs of each connection
718  }
719 
720  return curr_cost;
721 }
DLIST_ITERATOR_WRAPPER< D_PAD > Pads()
Definition: class_module.h:169
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
#define abs(a)
Definition: auxiliary.h:84
const D_PAD * nearestPad(MODULE *aRefModule, D_PAD *aRefPad, const wxPoint &aOffset)
void AR_AUTOPLACER::drawPlacementRoutingMatrix ( )
private

Definition at line 818 of file ar_autoplacer.cpp.

References AR_SIDE_BOTTOM, AR_SIDE_TOP, BLACK, BLUE, CELL_IS_EDGE, CELL_IS_HOLE, CELL_IS_MODULE, CELL_IS_ZONE, color, DARKGRAY, AR_MATRIX::GetCell(), AR_MATRIX::GetDist(), EDA_RECT::GetX(), EDA_RECT::GetY(), LIGHTGREEN, LIGHTRED, AR_MATRIX::m_BrdBox, AR_MATRIX::m_GridRouting, m_matrix, AR_MATRIX::m_Ncols, AR_MATRIX::m_Nrows, m_overlay, and WHITE.

Referenced by AutoplaceModules(), and SetProgressReporter().

819 {
820  int ii, jj;
821  COLOR4D color;
822  int ox, oy;
823  AR_MATRIX::MATRIX_CELL top_state, bottom_state;
824 
825 
826  for( ii = 0; ii < m_matrix.m_Nrows; ii++ )
827  {
828  oy = m_matrix.m_BrdBox.GetY() + ( ii * m_matrix.m_GridRouting );
829 
830  for( jj = 0; jj < m_matrix.m_Ncols; jj++ )
831  {
832  ox = m_matrix.m_BrdBox.GetX() + (jj * m_matrix.m_GridRouting);
833  color = COLOR4D::BLACK;
834 
835  top_state = m_matrix.GetCell( ii, jj, AR_SIDE_TOP );
836  bottom_state = m_matrix.GetCell( ii, jj, AR_SIDE_BOTTOM );
837 
838  if(top_state || bottom_state)
839  {
840  // printf("[%d, %d] [%d, %d] TS %x BS %x\n",ii,jj, ox, oy, top_state, bottom_state );
841  }
842 
843  if( top_state & CELL_IS_ZONE )
844  color = COLOR4D( BLUE );
845 
846  // obstacles
847  if( ( top_state & CELL_IS_EDGE ) || ( bottom_state & CELL_IS_EDGE ) )
848  color = COLOR4D::WHITE;
849  else if( top_state & ( CELL_IS_HOLE | CELL_IS_MODULE ) )
850  color = COLOR4D( LIGHTRED );
851  else if( bottom_state & ( CELL_IS_HOLE | CELL_IS_MODULE) )
852  color = COLOR4D( LIGHTGREEN );
853  else // Display the filling and keep out regions.
854  {
855  if( m_matrix.GetDist( ii, jj, AR_SIDE_TOP )
856  || m_matrix.GetDist( ii, jj, AR_SIDE_BOTTOM ) )
857  color = DARKGRAY;
858  }
859 
860  m_overlay->SetIsFill(true);
861  m_overlay->SetFillColor( color );
862 
863  VECTOR2D p(ox, oy);
864  m_overlay->Circle(p, m_matrix.m_GridRouting/4 );
865  }
866  }
867 }
Definition: colors.h:57
#define AR_SIDE_BOTTOM
Definition: ar_matrix.h:43
#define AR_SIDE_TOP
Definition: ar_matrix.h:42
int m_Ncols
Definition: ar_matrix.h:65
#define CELL_IS_MODULE
Definition: ar_cell.h:37
int m_GridRouting
Definition: ar_matrix.h:63
int color
Definition: DXF_plotter.cpp:62
#define CELL_IS_ZONE
Definition: ar_cell.h:40
EDA_RECT m_BrdBox
Definition: ar_matrix.h:64
AR_MATRIX m_matrix
MATRIX_CELL GetCell(int aRow, int aCol, int aSide)
Definition: ar_matrix.cpp:194
#define CELL_IS_HOLE
Definition: ar_cell.h:36
int m_Nrows
Definition: ar_matrix.h:65
#define CELL_IS_EDGE
Definition: ar_cell.h:38
int GetX() const
Definition: eda_rect.h:109
Definition: colors.h:49
int GetY() const
Definition: eda_rect.h:110
unsigned char MATRIX_CELL
Definition: ar_matrix.h:52
Definition: colors.h:45
DIST_CELL GetDist(int aRow, int aCol, int aSide)
Definition: ar_matrix.cpp:259
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_overlay
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
void AR_AUTOPLACER::genModuleOnRoutingMatrix ( MODULE Module)
private

Definition at line 331 of file ar_autoplacer.cpp.

References AR_GAIN, AR_KEEPOUT_MARGIN, B_Cu, CELL_IS_MODULE, AR_MATRIX::CreateKeepOutRectangle(), F_Cu, EDA_RECT::GetBottom(), MODULE::GetBoundingBox(), BOARD_ITEM::GetLayer(), MODULE::GetPadCount(), EDA_RECT::GetRight(), EDA_RECT::GetX(), EDA_RECT::GetY(), EDA_RECT::Inflate(), AR_MATRIX::m_BrdBox, AR_MATRIX::m_GridRouting, m_matrix, MODULE::Pads(), AR_MATRIX::PlacePad(), AR_MATRIX::TraceFilledRectangle(), and AR_MATRIX::WRITE_OR_CELL.

Referenced by AutoplaceModules(), and SetProgressReporter().

332 {
333  int ox, oy, fx, fy;
334  LSET layerMask;
335  EDA_RECT fpBBox = Module->GetBoundingBox();
336 
337  fpBBox.Inflate( m_matrix.m_GridRouting / 2 );
338  ox = fpBBox.GetX();
339  fx = fpBBox.GetRight();
340  oy = fpBBox.GetY();
341  fy = fpBBox.GetBottom();
342 
343  if( ox < m_matrix.m_BrdBox.GetX() )
344  ox = m_matrix.m_BrdBox.GetX();
345 
346  if( ox > m_matrix.m_BrdBox.GetRight() )
347  ox = m_matrix.m_BrdBox.GetRight();
348 
349  if( fx < m_matrix.m_BrdBox.GetX() )
350  fx = m_matrix.m_BrdBox.GetX();
351 
352  if( fx > m_matrix.m_BrdBox.GetRight() )
353  fx = m_matrix.m_BrdBox.GetRight();
354 
355  if( oy < m_matrix.m_BrdBox.GetY() )
356  oy = m_matrix.m_BrdBox.GetY();
357 
358  if( oy > m_matrix.m_BrdBox.GetBottom() )
359  oy = m_matrix.m_BrdBox.GetBottom();
360 
361  if( fy < m_matrix.m_BrdBox.GetY() )
362  fy = m_matrix.m_BrdBox.GetY();
363 
364  if( fy > m_matrix.m_BrdBox.GetBottom() )
365  fy = m_matrix.m_BrdBox.GetBottom();
366 
367  if( Module->GetLayer() == F_Cu )
368  layerMask.set( F_Cu );
369 
370  if( Module->GetLayer() == B_Cu )
371  layerMask.set( B_Cu );
372 
373  m_matrix.TraceFilledRectangle( ox, oy, fx, fy, layerMask,
375 
376  // Trace pads + clearance areas.
377  for( auto pad : Module->Pads() )
378  {
379  int margin = (m_matrix.m_GridRouting / 2) + pad->GetClearance();
381  }
382 
383  // Trace clearance.
384  int margin = ( m_matrix.m_GridRouting * Module->GetPadCount() ) / AR_GAIN;
385  m_matrix.CreateKeepOutRectangle( ox, oy, fx, fy, margin, AR_KEEPOUT_MARGIN , layerMask );
386 }
#define CELL_IS_MODULE
Definition: ar_cell.h:37
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int m_GridRouting
Definition: ar_matrix.h:63
void TraceFilledRectangle(int ux0, int uy0, int ux1, int uy1, double angle, LSET aLayerMask, int color, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:794
EDA_RECT m_BrdBox
Definition: ar_matrix.h:64
DLIST_ITERATOR_WRAPPER< D_PAD > Pads()
Definition: class_module.h:169
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...
Definition: ar_matrix.cpp:1175
void PlacePad(D_PAD *aPad, int color, int marge, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:1280
#define AR_GAIN
#define AR_KEEPOUT_MARGIN
AR_MATRIX m_matrix
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.
int GetBottom() const
Definition: eda_rect.h:122
int GetRight() const
Definition: eda_rect.h:119
unsigned GetPadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
GetPadCount returns the number of pads.
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
int GetX() const
Definition: eda_rect.h:109
int GetY() const
Definition: eda_rect.h:110
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
int AR_AUTOPLACER::genPlacementRoutingMatrix ( )
private

Definition at line 101 of file ar_autoplacer.cpp.

References AR_SIDE_BOTTOM, AR_SIDE_TOP, B_Cu, CELL_IS_EDGE, CELL_IS_HOLE, CELL_IS_ZONE, AR_MATRIX::ComputeMatrixSize(), BOARD::Drawings(), Edge_Cuts, F_Cu, BOARD::GetBoardEdgesBoundingBox(), EDA_RECT::GetHeight(), BOARD_ITEM::GetLayer(), EDA_RECT::GetWidth(), AR_MATRIX::InitRoutingMatrix(), m_board, AR_MATRIX::m_BoardSide, AR_MATRIX::m_GridRouting, m_matrix, AR_MATRIX::m_Ncols, AR_MATRIX::m_Nrows, AR_MATRIX::m_routeLayerBottom, AR_MATRIX::m_routeLayerTop, AR_MATRIX::m_RoutingLayersCount, AR_MATRIX::OrCell(), PCB_LINE_T, PCB_TEXT_T, propagate(), BOARD_ITEM::SetLayer(), BOARD_CONNECTED_ITEM::SetNetCode(), TRACK::SetWidth(), AR_MATRIX::TraceSegmentPcb(), UNDEFINED_LAYER, AR_MATRIX::UnInitRoutingMatrix(), and AR_MATRIX::WRITE_CELL.

Referenced by AutoplaceModules(), and SetProgressReporter().

102 {
104 
106 
107  if( bbox.GetWidth() == 0 || bbox.GetHeight() == 0 )
108  {
109  //DisplayError( NULL, _( "No PCB edge found, unknown board size!" ) );
110  // fixme: no wx here
111  return 0;
112  }
113 
114  m_matrix.ComputeMatrixSize( bbox );
115  int nbCells = m_matrix.m_Ncols * m_matrix.m_Nrows;
116 
117  // Choose the number of board sides.
120 
122 
125 
127 
128  // Place the edge layer segments
129  TRACK tmp( NULL );
130 
131  tmp.SetLayer( UNDEFINED_LAYER );
132  tmp.SetNetCode( -1 );
133  tmp.SetWidth( m_matrix.m_GridRouting / 2 );
134 
135  for( auto drawing : m_board->Drawings() )
136  {
137  DRAWSEGMENT* DrawSegm;
138 
139  switch( drawing->Type() )
140  {
141  case PCB_LINE_T:
142  DrawSegm = (DRAWSEGMENT*) drawing;
143 
144  if( DrawSegm->GetLayer() != Edge_Cuts )
145  break;
146 
147 
148  //printf("addSeg %p grid %d\n", DrawSegm, m_matrix.m_GridRouting );
151  break;
152 
153  case PCB_TEXT_T:
154  default:
155  break;
156  }
157  }
158 
159  // Mark cells of the routing matrix to CELL_IS_ZONE
160  // (i.e. availlable cell to place a module )
161  // Init a starting point of attachment to the area.
164 
165  // find and mark all other availlable cells:
166  for( int ii = 1; ii != 0; )
167  ii = propagate();
168 
169  // Initialize top layer. to the same value as the bottom layer
172  nbCells * sizeof(AR_MATRIX::MATRIX_CELL) );
173 
174  return 1;
175 }
#define AR_SIDE_BOTTOM
Definition: ar_matrix.h:43
int InitRoutingMatrix()
Function InitBoard initializes the data structures.
Definition: ar_matrix.cpp:92
#define AR_SIDE_TOP
Definition: ar_matrix.h:42
int m_Ncols
Definition: ar_matrix.h:65
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.
int m_GridRouting
Definition: ar_matrix.h:63
#define CELL_IS_ZONE
Definition: ar_cell.h:40
int GetHeight() const
Definition: eda_rect.h:118
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
void TraceSegmentPcb(DRAWSEGMENT *pt_segm, int color, int marge, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:1085
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:804
AR_MATRIX m_matrix
PCB_LAYER_ID m_routeLayerTop
Definition: ar_matrix.h:69
void OrCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.cpp:216
#define CELL_IS_HOLE
Definition: ar_cell.h:36
int m_Nrows
Definition: ar_matrix.h:65
MATRIX_CELL * m_BoardSide[AR_MAX_ROUTING_LAYERS_COUNT]
Definition: ar_matrix.h:56
void UnInitRoutingMatrix()
Definition: ar_matrix.cpp:140
int m_RoutingLayersCount
Definition: ar_matrix.h:62
#define CELL_IS_EDGE
Definition: ar_cell.h:38
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
int GetWidth() const
Definition: eda_rect.h:117
unsigned char MATRIX_CELL
Definition: ar_matrix.h:52
bool ComputeMatrixSize(const EDA_RECT &aBoundingBox)
Function ComputeMatrixSize calculates the number of rows and columns of dimensions of aPcb for routin...
Definition: ar_matrix.cpp:62
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:255
PCB_LAYER_ID m_routeLayerBottom
Definition: ar_matrix.h:70
int AR_AUTOPLACER::getOptimalModulePlacement ( MODULE aModule)
private

Definition at line 538 of file ar_autoplacer.cpp.

References AR_ABORT_PLACEMENT, B_Cu, MODULE::CalculateBoundingBox(), computePlacementRatsnestCost(), F_Cu, EDA_RECT::GetEnd(), MODULE::GetFootprintRect(), BOARD_ITEM::GetLayer(), EDA_RECT::GetOrigin(), MODULE::GetPosition(), AR_MATRIX::m_BrdBox, m_curPosition, AR_MATRIX::m_GridRouting, m_matrix, m_minCost, m_refreshCallback, AR_MATRIX::m_RoutingLayersCount, EDA_RECT::Move(), MODULE::Pads(), EDA_RECT::SetOrigin(), testModuleOnBoard(), wxPoint::x, and wxPoint::y.

Referenced by AutoplaceModules(), and SetProgressReporter().

539 {
540  int error = 1;
541  wxPoint LastPosOK;
542  double min_cost, curr_cost, Score;
543  bool TstOtherSide;
544 
545  aModule->CalculateBoundingBox();
546 
547  LastPosOK = m_matrix.m_BrdBox.GetOrigin();
548 
549  wxPoint mod_pos = aModule->GetPosition();
550  EDA_RECT fpBBox = aModule->GetFootprintRect();
551 
552  // Move fpBBox to have the footprint position at (0,0)
553  fpBBox.Move( -mod_pos );
554  wxPoint fpBBoxOrg = fpBBox.GetOrigin();
555 
556  // Calculate the limit of the footprint position, relative
557  // to the routing matrix area
558  wxPoint xylimit = m_matrix.m_BrdBox.GetEnd() - fpBBox.GetEnd();
559 
560  wxPoint initialPos = m_matrix.m_BrdBox.GetOrigin() - fpBBoxOrg;
561 
562  // Stay on grid.
563  initialPos.x -= initialPos.x % m_matrix.m_GridRouting;
564  initialPos.y -= initialPos.y % m_matrix.m_GridRouting;
565 
566  m_curPosition = initialPos;
567  auto moduleOffset = mod_pos - m_curPosition;
568 
569  /* Examine pads, and set TstOtherSide to true if a footprint
570  * has at least 1 pad through.
571  */
572  TstOtherSide = false;
573 
575  {
576  LSET other( aModule->GetLayer() == B_Cu ? F_Cu : B_Cu );
577 
578  for( auto pad : aModule->Pads() )
579  {
580  if( !( pad->GetLayerSet() & other ).any() )
581  continue;
582 
583  TstOtherSide = true;
584  break;
585  }
586  }
587 
588  fpBBox.SetOrigin( fpBBoxOrg + m_curPosition );
589 
590  min_cost = -1.0;
591 // m_frame->SetStatusText( wxT( "Score ??, pos ??" ) );
592 
593 
594  for( ; m_curPosition.x < xylimit.x; m_curPosition.x += m_matrix.m_GridRouting )
595  {
596  if ( m_refreshCallback )
597  {
599  return AR_ABORT_PLACEMENT;
600  }
601 
602  m_curPosition.y = initialPos.y;
603 
604  for( ; m_curPosition.y < xylimit.y; m_curPosition.y += m_matrix.m_GridRouting )
605  {
606 
607  fpBBox.SetOrigin( fpBBoxOrg + m_curPosition );
608  moduleOffset = mod_pos - m_curPosition;
609  int keepOutCost = testModuleOnBoard( aModule, TstOtherSide, moduleOffset );
610 
611  if( keepOutCost >= 0 ) // i.e. if the module can be put here
612  {
613  error = 0;
614  // m_frame->build_ratsnest_module( aModule ); // fixme
615  curr_cost = computePlacementRatsnestCost( aModule, moduleOffset );
616  Score = curr_cost + keepOutCost;
617 
618  if( (min_cost >= Score ) || (min_cost < 0 ) )
619  {
620  LastPosOK = m_curPosition;
621  min_cost = Score;
622  wxString msg;
623 /* msg.Printf( wxT( "Score %g, pos %s, %s" ),
624  min_cost,
625  GetChars( ::CoordinateToString( LastPosOK.x ) ),
626  GetChars( ::CoordinateToString( LastPosOK.y ) ) );
627  m_frame->SetStatusText( msg );*/
628  }
629  }
630  }
631  }
632 
633  // Regeneration of the modified variable.
634  m_curPosition = LastPosOK;
635 
636  m_minCost = min_cost;
637  return error;
638 }
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
const wxPoint GetOrigin() const
Definition: eda_rect.h:112
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.
int m_GridRouting
Definition: ar_matrix.h:63
EDA_RECT m_BrdBox
Definition: ar_matrix.h:64
DLIST_ITERATOR_WRAPPER< D_PAD > Pads()
Definition: class_module.h:169
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:124
AR_MATRIX m_matrix
Class LSET is a set of PCB_LAYER_IDs.
double computePlacementRatsnestCost(MODULE *aModule, const wxPoint &aOffset)
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text...
#define AR_ABORT_PLACEMENT
int testModuleOnBoard(MODULE *aModule, bool TstOtherSide, const wxPoint &aOffset)
const wxPoint GetEnd() const
Definition: eda_rect.h:114
std::function< int()> m_refreshCallback
int m_RoutingLayersCount
Definition: ar_matrix.h:62
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
wxPoint m_curPosition
const wxPoint GetPosition() const override
Definition: class_module.h:184
const D_PAD * AR_AUTOPLACER::nearestPad ( MODULE aRefModule,
D_PAD aRefPad,
const wxPoint aOffset 
)
private

Definition at line 641 of file ar_autoplacer.cpp.

References EDA_RECT::Contains(), dist, BOARD_CONNECTED_ITEM::GetNetCode(), D_PAD::GetPosition(), m_board, AR_MATRIX::m_BrdBox, m_matrix, mod, and BOARD::Modules().

Referenced by computePlacementRatsnestCost(), and SetProgressReporter().

642 {
643  const D_PAD* nearest = nullptr;
644  int64_t nearestDist = INT64_MAX;
645 
646  for ( auto mod : m_board->Modules() )
647  {
648  if ( mod == aRefModule )
649  continue;
650 
651  if( !m_matrix.m_BrdBox.Contains( mod->GetPosition() ) )
652  continue;
653 
654  for ( auto pad: mod->Pads() )
655  {
656  if ( pad->GetNetCode() != aRefPad->GetNetCode() || pad->GetNetCode() <= 0 )
657  continue;
658 
659  auto dist = (VECTOR2I( aRefPad->GetPosition() - aOffset ) - VECTOR2I( pad->GetPosition() ) ).EuclideanNorm();
660 
661  //printf("Dist %lld pad %p\n", dist, pad );
662 
663  if ( dist < nearestDist )
664  {
665  nearestDist = dist;
666  nearest = pad;
667  }
668  }
669  }
670 
671  return nearest;
672 }
static const int dist[10][10]
Definition: ar_matrix.cpp:320
bool Contains(const wxPoint &aPoint) const
Function Contains.
EDA_RECT m_BrdBox
Definition: ar_matrix.h:64
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
AR_MATRIX m_matrix
DLIST_ITERATOR_WRAPPER< MODULE > Modules()
Definition: class_board.h:254
int GetNetCode() const
Function GetNetCode.
const wxPoint GetPosition() const override
Definition: class_pad.h:220
#define mod(a, n)
Definition: greymap.cpp:24
MODULE * AR_AUTOPLACER::pickModule ( )
private

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

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

Definition at line 753 of file ar_autoplacer.cpp.

References MODULE::CalculateBoundingBox(), MODULE::GetFlag(), m_board, m_connectivity, BOARD::Modules(), MODULE::NeedsPlaced(), MODULE::SetFlag(), sortFootprintsByComplexity(), and sortFootprintsByRatsnestSize().

Referenced by AutoplaceModules(), and SetProgressReporter().

754 {
755  MODULE* module;
756  std::vector <MODULE*> moduleList;
757 
758 
759  for( auto m : m_board->Modules() )
760  {
762  moduleList.push_back( m );
763  }
764 
765  sort( moduleList.begin(), moduleList.end(), sortFootprintsByComplexity );
766 
767  for( unsigned kk = 0; kk < moduleList.size(); kk++ )
768  {
769  module = moduleList[kk];
770  module->SetFlag( 0 );
771 
772  if( !module->NeedsPlaced() )
773  continue;
774 
775  m_connectivity->Update( module );
776  }
777 
778  m_connectivity->RecalculateRatsnest();
779 
780  for( unsigned kk = 0; kk < moduleList.size(); kk++ )
781  {
782  module = moduleList[kk];
783 
784  auto edges = m_connectivity->GetRatsnestForComponent( module, true );
785 
786  module->SetFlag( edges.size() ) ;
787  }
788 
789  sort( moduleList.begin(), moduleList.end(), sortFootprintsByRatsnestSize );
790 
791  // Search for "best" module.
792  MODULE* bestModule = nullptr;
793  MODULE* altModule = nullptr;
794 
795  for( unsigned ii = 0; ii < moduleList.size(); ii++ )
796  {
797  module = moduleList[ii];
798 
799  if( !module->NeedsPlaced() )
800  continue;
801 
802  altModule = module;
803 
804  if( module->GetFlag() == 0 )
805  continue;
806 
807  bestModule = module;
808  break;
809  }
810 
811  if( bestModule )
812  return bestModule;
813  else
814  return altModule;
815 }
int GetFlag() const
Definition: class_module.h:231
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
bool NeedsPlaced() const
Definition: class_module.h:295
DLIST_ITERATOR_WRAPPER< MODULE > Modules()
Definition: class_board.h:254
static bool sortFootprintsByComplexity(MODULE *ref, MODULE *compare)
static bool sortFootprintsByRatsnestSize(MODULE *ref, MODULE *compare)
void SetFlag(int aFlag)
Definition: class_module.h:229
std::unique_ptr< CONNECTIVITY_DATA > m_connectivity
void AR_AUTOPLACER::placeModule ( MODULE aModule,
bool  aDoNotRecreateRatsnest,
const wxPoint aPos 
)
private

Definition at line 91 of file ar_autoplacer.cpp.

References m_connectivity, and MODULE::SetPosition().

Referenced by AutoplaceModules(), and SetProgressReporter().

92 {
93  if( !aModule )
94  return;
95 
96  aModule->SetPosition( aPos );
97  m_connectivity->Update( aModule );
98 }
void SetPosition(const wxPoint &aPos) override
std::unique_ptr< CONNECTIVITY_DATA > m_connectivity
int AR_AUTOPLACER::propagate ( )
private

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 218 of file ar_autoplacer.cpp.

References AR_SIDE_BOTTOM, CELL_IS_EDGE, CELL_IS_EMPTY, CELL_IS_HOLE, CELL_IS_ZONE, AR_MATRIX::GetCell(), m_matrix, AR_MATRIX::m_Ncols, AR_MATRIX::m_Nrows, max, and AR_MATRIX::OrCell().

Referenced by genPlacementRoutingMatrix(), and SetProgressReporter().

219 {
220  int row, col;
221  long current_cell, old_cell_H;
222  std::vector<int> pt_cell_V;
223  int nbpoints = 0;
224 
225  const uint32_t NO_CELL_ZONE = CELL_IS_HOLE | CELL_IS_EDGE | CELL_IS_ZONE;
226 
227  pt_cell_V.resize( std::max( m_matrix.m_Nrows, m_matrix.m_Ncols ), CELL_IS_EMPTY );
228 
229  // Search from left to right and top to bottom.
230  for( row = 0; row < m_matrix.m_Nrows; row++ )
231  {
232  old_cell_H = 0;
233 
234  for( col = 0; col < m_matrix.m_Ncols; col++ )
235  {
236  current_cell = m_matrix.GetCell( row, col, AR_SIDE_BOTTOM ) & NO_CELL_ZONE;
237 
238  if( current_cell == 0 ) // a free cell is found
239  {
240  if( (old_cell_H & CELL_IS_ZONE) || (pt_cell_V[col] & CELL_IS_ZONE) )
241  {
242  m_matrix.OrCell( row, col, AR_SIDE_BOTTOM, CELL_IS_ZONE );
243  current_cell = CELL_IS_ZONE;
244  nbpoints++;
245  }
246  }
247 
248  pt_cell_V[col] = old_cell_H = current_cell;
249  }
250  }
251 
252  // Search from right to left and top to bottom/
253  fill( pt_cell_V.begin(), pt_cell_V.end(), CELL_IS_EMPTY );
254 
255  for( row = 0; row < m_matrix.m_Nrows; row++ )
256  {
257  old_cell_H = 0;
258 
259  for( col = m_matrix.m_Ncols - 1; col >= 0; col-- )
260  {
261  current_cell = m_matrix.GetCell( row, col, AR_SIDE_BOTTOM ) & NO_CELL_ZONE;
262 
263  if( current_cell == 0 ) // a free cell is found
264  {
265  if( (old_cell_H & CELL_IS_ZONE) || (pt_cell_V[col] & CELL_IS_ZONE) )
266  {
267  m_matrix.OrCell( row, col, AR_SIDE_BOTTOM, CELL_IS_ZONE );
268  current_cell = CELL_IS_ZONE;
269  nbpoints++;
270  }
271  }
272 
273  pt_cell_V[col] = old_cell_H = current_cell;
274  }
275  }
276 
277  // Search from bottom to top and right to left.
278  fill( pt_cell_V.begin(), pt_cell_V.end(), CELL_IS_EMPTY );
279 
280  for( col = m_matrix.m_Ncols - 1; col >= 0; col-- )
281  {
282  old_cell_H = 0;
283 
284  for( row = m_matrix.m_Nrows - 1; row >= 0; row-- )
285  {
286  current_cell = m_matrix.GetCell( row, col, AR_SIDE_BOTTOM ) & NO_CELL_ZONE;
287 
288  if( current_cell == 0 ) // a free cell is found
289  {
290  if( (old_cell_H & CELL_IS_ZONE) || (pt_cell_V[row] & CELL_IS_ZONE) )
291  {
292  m_matrix.OrCell( row, col, AR_SIDE_BOTTOM, CELL_IS_ZONE );
293  current_cell = CELL_IS_ZONE;
294  nbpoints++;
295  }
296  }
297 
298  pt_cell_V[row] = old_cell_H = current_cell;
299  }
300  }
301 
302  // Search from bottom to top and left to right.
303  fill( pt_cell_V.begin(), pt_cell_V.end(), CELL_IS_EMPTY );
304 
305  for( col = 0; col < m_matrix.m_Ncols; col++ )
306  {
307  old_cell_H = 0;
308 
309  for( row = m_matrix.m_Nrows - 1; row >= 0; row-- )
310  {
311  current_cell = m_matrix.GetCell( row, col, AR_SIDE_BOTTOM ) & NO_CELL_ZONE;
312 
313  if( current_cell == 0 ) // a free cell is found
314  {
315  if( (old_cell_H & CELL_IS_ZONE) || (pt_cell_V[row] & CELL_IS_ZONE) )
316  {
317  m_matrix.OrCell( row, col, AR_SIDE_BOTTOM, CELL_IS_ZONE );
318  current_cell = CELL_IS_ZONE;
319  nbpoints++;
320  }
321  }
322 
323  pt_cell_V[row] = old_cell_H = current_cell;
324  }
325  }
326 
327  return nbpoints;
328 }
#define AR_SIDE_BOTTOM
Definition: ar_matrix.h:43
int m_Ncols
Definition: ar_matrix.h:65
#define CELL_IS_ZONE
Definition: ar_cell.h:40
AR_MATRIX m_matrix
#define CELL_IS_EMPTY
Definition: ar_cell.h:35
void OrCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.cpp:216
MATRIX_CELL GetCell(int aRow, int aCol, int aSide)
Definition: ar_matrix.cpp:194
#define CELL_IS_HOLE
Definition: ar_cell.h:36
int m_Nrows
Definition: ar_matrix.h:65
#define max(a, b)
Definition: auxiliary.h:86
#define CELL_IS_EDGE
Definition: ar_cell.h:38
const std::vector<MODULE*> AR_AUTOPLACER::QueryOffboardModules ( )
void AR_AUTOPLACER::rotateModule ( MODULE module,
double  angle,
bool  incremental 
)
private

Definition at line 178 of file ar_autoplacer.cpp.

References PNS::angle(), BOARD::GetConnectivity(), MODULE::GetOrientation(), m_board, and MODULE::SetOrientation().

Referenced by AutoplaceModules(), and SetProgressReporter().

179 {
180  if( module == NULL )
181  return;
182 
183  if( incremental )
184  module->SetOrientation( module->GetOrientation() + angle );
185  else
186  module->SetOrientation( angle );
187 
188 
189  m_board->GetConnectivity()->Update( module );
190 }
double GetOrientation() const
Definition: class_module.h:189
void SetOrientation(double newangle)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:296
void AR_AUTOPLACER::SetOverlay ( std::shared_ptr< KIGFX::VIEW_OVERLAY aOverlay)
inline

Definition at line 73 of file ar_autoplacer.h.

References m_overlay.

Referenced by AUTOPLACE_TOOL::autoplace().

74  {
75  m_overlay = aOverlay;
76  }
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_overlay
void AR_AUTOPLACER::SetPlacementGrid ( int  aGrid)
inline

Definition at line 68 of file ar_autoplacer.h.

References m_gridSize.

69  {
70  m_gridSize = aGrid;
71  }
void AR_AUTOPLACER::SetRefreshCallback ( std::function< int()>  aCallback)
inline

Definition at line 78 of file ar_autoplacer.h.

References m_refreshCallback.

79  {
80  m_refreshCallback = aCallback;
81  }
std::function< int()> m_refreshCallback
int AR_AUTOPLACER::testModuleOnBoard ( MODULE aModule,
bool  TstOtherSide,
const wxPoint aOffset 
)
private

Definition at line 505 of file ar_autoplacer.cpp.

References AR_FREE_CELL, AR_GAIN, AR_SIDE_BOTTOM, AR_SIDE_TOP, B_Cu, calculateKeepOutArea(), MODULE::GetFootprintRect(), BOARD_ITEM::GetLayer(), MODULE::GetPadCount(), EDA_RECT::Inflate(), AR_MATRIX::m_GridRouting, m_matrix, EDA_RECT::Move(), and testRectangle().

Referenced by getOptimalModulePlacement(), and SetProgressReporter().

506 {
507  int side = AR_SIDE_TOP;
508  int otherside = AR_SIDE_BOTTOM;
509 
510  if( aModule->GetLayer() == B_Cu )
511  {
512  side = AR_SIDE_BOTTOM; otherside = AR_SIDE_TOP;
513  }
514 
515  EDA_RECT fpBBox = aModule->GetFootprintRect();
516  fpBBox.Move( -aOffset );
517 
518  int diag = testRectangle( fpBBox, side );
519 
520  if( diag != AR_FREE_CELL )
521  return diag;
522 
523  if( TstOtherSide )
524  {
525  diag = testRectangle( fpBBox, otherside );
526 
527  if( diag != AR_FREE_CELL )
528  return diag;
529  }
530 
531  int marge = ( m_matrix.m_GridRouting * aModule->GetPadCount() ) / AR_GAIN;
532 
533  fpBBox.Inflate( marge );
534  return calculateKeepOutArea( fpBBox, side );
535 }
#define AR_SIDE_BOTTOM
Definition: ar_matrix.h:43
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
#define AR_SIDE_TOP
Definition: ar_matrix.h:42
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int m_GridRouting
Definition: ar_matrix.h:63
#define AR_GAIN
AR_MATRIX m_matrix
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text...
unsigned int calculateKeepOutArea(const EDA_RECT &aRect, int side)
unsigned GetPadCount(INCLUDE_NPTH_T aIncludeNPTH=INCLUDE_NPTH_T(INCLUDE_NPTH)) const
GetPadCount returns the number of pads.
int testRectangle(const EDA_RECT &aRect, int side)
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
int AR_AUTOPLACER::testRectangle ( const EDA_RECT aRect,
int  side 
)
private

Definition at line 395 of file ar_autoplacer.cpp.

References AR_FREE_CELL, AR_OCCUIPED_BY_MODULE, AR_OUT_OF_BOARD, CELL_IS_MODULE, CELL_IS_ZONE, AR_MATRIX::GetCell(), EDA_RECT::GetEnd(), EDA_RECT::GetOrigin(), EDA_RECT::Inflate(), AR_MATRIX::m_BrdBox, AR_MATRIX::m_GridRouting, m_matrix, AR_MATRIX::m_Ncols, AR_MATRIX::m_Nrows, wxPoint::x, and wxPoint::y.

Referenced by SetProgressReporter(), and testModuleOnBoard().

396 {
397  EDA_RECT rect = aRect;
398 
399  rect.Inflate( m_matrix.m_GridRouting / 2 );
400 
401  wxPoint start = rect.GetOrigin();
402  wxPoint end = rect.GetEnd();
403 
404  start -= m_matrix.m_BrdBox.GetOrigin();
405  end -= m_matrix.m_BrdBox.GetOrigin();
406 
407  int row_min = start.y / m_matrix.m_GridRouting;
408  int row_max = end.y / m_matrix.m_GridRouting;
409  int col_min = start.x / m_matrix.m_GridRouting;
410  int col_max = end.x / m_matrix.m_GridRouting;
411 
412  if( start.y > row_min * m_matrix.m_GridRouting )
413  row_min++;
414 
415  if( start.x > col_min * m_matrix.m_GridRouting )
416  col_min++;
417 
418  if( row_min < 0 )
419  row_min = 0;
420 
421  if( row_max >= ( m_matrix.m_Nrows - 1 ) )
422  row_max = m_matrix.m_Nrows - 1;
423 
424  if( col_min < 0 )
425  col_min = 0;
426 
427  if( col_max >= ( m_matrix.m_Ncols - 1 ) )
428  col_max = m_matrix.m_Ncols - 1;
429 
430  for( int row = row_min; row <= row_max; row++ )
431  {
432  for( int col = col_min; col <= col_max; col++ )
433  {
434  unsigned int data = m_matrix.GetCell( row, col, side );
435 
436  if( ( data & CELL_IS_ZONE ) == 0 )
437  return AR_OUT_OF_BOARD;
438 
439  if( (data & CELL_IS_MODULE) )
440  return AR_OCCUIPED_BY_MODULE;
441  }
442  }
443 
444  return AR_FREE_CELL;
445 }
const wxPoint GetOrigin() const
Definition: eda_rect.h:112
int m_Ncols
Definition: ar_matrix.h:65
#define CELL_IS_MODULE
Definition: ar_cell.h:37
int m_GridRouting
Definition: ar_matrix.h:63
#define CELL_IS_ZONE
Definition: ar_cell.h:40
EDA_RECT m_BrdBox
Definition: ar_matrix.h:64
AR_MATRIX m_matrix
MATRIX_CELL GetCell(int aRow, int aCol, int aSide)
Definition: ar_matrix.cpp:194
int m_Nrows
Definition: ar_matrix.h:65
const wxPoint GetEnd() const
Definition: eda_rect.h:114
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.

Member Data Documentation

BOARD* AR_AUTOPLACER::m_board
private
std::unique_ptr<CONNECTIVITY_DATA> AR_AUTOPLACER::m_connectivity
private

Definition at line 113 of file ar_autoplacer.h.

Referenced by AR_AUTOPLACER(), pickModule(), and placeModule().

wxPoint AR_AUTOPLACER::m_curPosition
private

Definition at line 107 of file ar_autoplacer.h.

Referenced by AutoplaceModules(), and getOptimalModulePlacement().

int AR_AUTOPLACER::m_gridSize
private

Definition at line 110 of file ar_autoplacer.h.

Referenced by AR_AUTOPLACER(), AutoplaceModules(), and SetPlacementGrid().

double AR_AUTOPLACER::m_minCost
private

Definition at line 109 of file ar_autoplacer.h.

Referenced by AutoplaceModules(), and getOptimalModulePlacement().

wxPoint AR_AUTOPLACER::m_moduleOffset
private

Definition at line 108 of file ar_autoplacer.h.

std::shared_ptr<KIGFX::VIEW_OVERLAY> AR_AUTOPLACER::m_overlay
private

Definition at line 112 of file ar_autoplacer.h.

Referenced by drawPlacementRoutingMatrix(), and SetOverlay().

PROGRESS_REPORTER* AR_AUTOPLACER::m_progressReporter
private

Definition at line 115 of file ar_autoplacer.h.

Referenced by AR_AUTOPLACER(), AutoplaceModules(), and SetProgressReporter().

std::function<int()> AR_AUTOPLACER::m_refreshCallback
private

Definition at line 114 of file ar_autoplacer.h.

Referenced by AR_AUTOPLACER(), getOptimalModulePlacement(), and SetRefreshCallback().


The documentation for this class was generated from the following files: