diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 292920a710..010f6ec159 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -1582,14 +1582,17 @@ public: * @param aFootprints: a list of footprints to be spread out. * @param aMoveFootprintsOutsideBoardOnly: true to move only * footprints outside the board outlines - * (they are outside if the position of a footprint is outside - * the board outlines bounding box). + * (they are outside if the position of a footprint anchor is outside + * the board outlines bounding box). It imply the board outlines exist * @param aCheckForBoardEdges: true to try to place footprints outside of - * board edges. + * board edges, if aSpreadAreaPosition is incorrectly chosen. + * @param aSpreadAreaPosition the position of the upper left corner of the + * area used to spread footprints */ void SpreadFootprints( std::vector* aFootprints, bool aMoveFootprintsOutsideBoardOnly, - bool aCheckForBoardEdges ); + bool aCheckForBoardEdges, + wxPoint aSpreadAreaPosition ); /** * Function AutoPlaceModule diff --git a/pcbnew/autorouter/move_and_route_event_functions.cpp b/pcbnew/autorouter/move_and_route_event_functions.cpp index c09aa5fca6..90aad416f9 100644 --- a/pcbnew/autorouter/move_and_route_event_functions.cpp +++ b/pcbnew/autorouter/move_and_route_event_functions.cpp @@ -146,7 +146,8 @@ void PCB_EDIT_FRAME::OnPlaceOrRouteFootprints( wxCommandEvent& event ) for( ; footprint != NULL; footprint = footprint->Next() ) footprintList.push_back( footprint ); - SpreadFootprints( &footprintList, id == ID_POPUP_PCB_SPREAD_NEW_MODULES, true ); + SpreadFootprints( &footprintList, id == ID_POPUP_PCB_SPREAD_NEW_MODULES, + true, GetCrossHairPosition() ); } break; diff --git a/pcbnew/autorouter/spread_footprints.cpp b/pcbnew/autorouter/spread_footprints.cpp index e67e5c0aad..94a2a01a1e 100644 --- a/pcbnew/autorouter/spread_footprints.cpp +++ b/pcbnew/autorouter/spread_footprints.cpp @@ -172,12 +172,13 @@ static bool sortFootprintsbySheetPath( MODULE* ref, MODULE* compare ); */ void PCB_EDIT_FRAME::SpreadFootprints( std::vector* aFootprints, bool aMoveFootprintsOutsideBoardOnly, - bool aCheckForBoardEdges ) + bool aCheckForBoardEdges, + wxPoint aSpreadAreaPosition ) { EDA_RECT bbox = GetBoard()->ComputeBoundingBox( true ); - bool edgesExist = ( bbox.GetWidth() || bbox.GetHeight() ); + bool edgesExist = bbox.GetWidth() || bbox.GetHeight(); // if aFootprintsOutsideBoardOnly is true, and if board outline exists, - // wue have to filter footprints to move: + // we have to filter footprints to move: bool outsideBrdFilter = aMoveFootprintsOutsideBoardOnly && edgesExist; // no edges exist @@ -234,16 +235,20 @@ void PCB_EDIT_FRAME::SpreadFootprints( std::vector* aFootprints, double subsurface; double placementsurface = 0.0; - wxPoint placementAreaPosition = GetCrossHairPosition(); + // put the placement area position on mouse cursor. + // this position will be adjusted later + wxPoint placementAreaPosition = aSpreadAreaPosition; // We sometimes do not want to move footprints inside an existing board. - // move the placement area position outside the board bounding box + // Therefore, move the placement area position outside the board bounding box // to the left of the board - if( edgesExist && aCheckForBoardEdges ) + if( aCheckForBoardEdges && edgesExist ) { if( placementAreaPosition.x < bbox.GetEnd().x && placementAreaPosition.y < bbox.GetEnd().y ) { + // the placement area could overlap the board + // move its position to a safe location placementAreaPosition.x = bbox.GetEnd().x; placementAreaPosition.y = bbox.GetOrigin().y; } diff --git a/pcbnew/dialogs/dialog_update_pcb.cpp b/pcbnew/dialogs/dialog_update_pcb.cpp index 64796eafee..7efcda67b0 100644 --- a/pcbnew/dialogs/dialog_update_pcb.cpp +++ b/pcbnew/dialogs/dialog_update_pcb.cpp @@ -109,7 +109,7 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun ) if( m_frame->IsGalCanvasActive() ) { - m_frame->SpreadFootprints( &newFootprints, false, false ); + m_frame->SpreadFootprints( &newFootprints, false, false, m_frame->GetCrossHairPosition() ); if( !newFootprints.empty() ) { diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index aff9cf95f9..c83c1994ab 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -69,6 +69,9 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, KIGFX::VIEW* view = GetGalCanvas()->GetView(); BOARD* board = GetBoard(); std::vector newFootprints; + // keep trace of the initial baord area, if we want to place new footprints + // outside the existinag board + EDA_RECT bbox = GetBoard()->ComputeBoundingBox( false ); netlist.SetIsDryRun( aIsDryRun ); netlist.SetFindByTimeStamp( aSelectByTimeStamp ); @@ -124,7 +127,8 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, if( IsGalCanvasActive() ) { - SpreadFootprints( &newFootprints, false, false ); + SpreadFootprints( &newFootprints, false, false, GetCrossHairPosition() ); + if( !newFootprints.empty() ) { for( MODULE* footprint : newFootprints ) @@ -134,6 +138,17 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, m_toolManager->InvokeTool( "pcbnew.InteractiveEdit" ); } } + else + { + wxPoint placementAreaPosition; + + // Place area to the left side of the board. + // if the board is empty, the bbox position is (0,0) + placementAreaPosition.x = bbox.GetEnd().x + Millimeter2iu( 10 ); + placementAreaPosition.y = bbox.GetOrigin().y; + + SpreadFootprints( &newFootprints, false, false, placementAreaPosition ); + } OnModify();