Pcbnew: spread and pick up new footprints when loaded.
This commit is contained in:
parent
7e2af163dd
commit
f309eaab00
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010 Jean-Pierre Charras, jp.charras@wanadoo.fr
|
||||
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -1587,12 +1587,17 @@ public:
|
|||
* Function SpreadFootprints
|
||||
* Footprints (after loaded by reading a netlist for instance) are moved
|
||||
* to be in a small free area (outside the current board) without overlapping.
|
||||
* @param aFootprintsOutsideBoardOnly: 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
|
||||
* @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).
|
||||
* @param aCheckForBoardEdges: true to try to place footprints outside of
|
||||
* board edges.
|
||||
*/
|
||||
void SpreadFootprints( bool aFootprintsOutsideBoardOnly );
|
||||
void SpreadFootprints( std::vector<MODULE*>* aFootprints,
|
||||
bool aMoveFootprintsOutsideBoardOnly,
|
||||
bool aCheckForBoardEdges );
|
||||
|
||||
/**
|
||||
* Function AutoPlaceModule
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
*
|
||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -139,8 +139,15 @@ void PCB_EDIT_FRAME::OnPlaceOrRouteFootprints( wxCommandEvent& event )
|
|||
DisplayError( this, _( "No footprint found!" ) );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
MODULE* footprint = GetBoard()->m_Modules;
|
||||
std::vector<MODULE*> footprintList;
|
||||
for( ; footprint != NULL; footprint = footprint->Next() )
|
||||
footprintList.push_back( footprint );
|
||||
|
||||
SpreadFootprints( id == ID_POPUP_PCB_SPREAD_NEW_MODULES );
|
||||
SpreadFootprints( &footprintList, id == ID_POPUP_PCB_SPREAD_NEW_MODULES, true );
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_POPUP_PCB_AUTOROUTE_ALL_MODULES:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
*
|
||||
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <convert_to_biu.h>
|
||||
|
@ -95,8 +96,8 @@ void fillRectList( CSubRectArray& vecSubRects, std::vector <EDA_RECT>& aRectList
|
|||
|
||||
// Spread a list of rectangles inside a placement area
|
||||
void spreadRectangles( CRectPlacement& aPlacementArea,
|
||||
CSubRectArray& vecSubRects,
|
||||
int areaSizeX, int areaSizeY )
|
||||
CSubRectArray& vecSubRects,
|
||||
int areaSizeX, int areaSizeY )
|
||||
{
|
||||
areaSizeX/= scale;
|
||||
areaSizeY/= scale;
|
||||
|
@ -135,8 +136,9 @@ void spreadRectangles( CRectPlacement& aPlacementArea,
|
|||
|
||||
|
||||
void moveFootprintsInArea( CRectPlacement& aPlacementArea,
|
||||
std::vector <MODULE*>& aModuleList, EDA_RECT& aFreeArea,
|
||||
bool aFindAreaOnly )
|
||||
std::vector <MODULE*>& aModuleList,
|
||||
EDA_RECT& aFreeArea,
|
||||
bool aFindAreaOnly )
|
||||
{
|
||||
CSubRectArray vecSubRects;
|
||||
|
||||
|
@ -163,83 +165,82 @@ void moveFootprintsInArea( CRectPlacement& aPlacementArea,
|
|||
}
|
||||
}
|
||||
|
||||
static bool sortModulesbySheetPath( MODULE* ref, MODULE* compare );
|
||||
static bool sortFootprintsbySheetPath( MODULE* ref, MODULE* compare );
|
||||
|
||||
/* Function to move components in a rectangular area format 4 / 3,
|
||||
* starting from the mouse cursor
|
||||
* The components with the FIXED status set are not moved
|
||||
*/
|
||||
void PCB_EDIT_FRAME::SpreadFootprints( bool aFootprintsOutsideBoardOnly )
|
||||
void PCB_EDIT_FRAME::SpreadFootprints( std::vector<MODULE*>* aFootprints,
|
||||
bool aMoveFootprintsOutsideBoardOnly,
|
||||
bool aCheckForBoardEdges )
|
||||
{
|
||||
EDA_RECT bbox = GetBoard()->ComputeBoundingBox( true );
|
||||
bool edgesExist = ( bbox.GetWidth() || bbox.GetHeight() );
|
||||
// if aFootprintsOutsideBoardOnly is true, and if board outline exists,
|
||||
// wue have to filter footprints to move:
|
||||
bool outsideBrdFilter = aMoveFootprintsOutsideBoardOnly && edgesExist;
|
||||
|
||||
// no edges exist
|
||||
if( aFootprintsOutsideBoardOnly && !edgesExist )
|
||||
if( aMoveFootprintsOutsideBoardOnly && !edgesExist )
|
||||
{
|
||||
DisplayError( this,
|
||||
_( "Could not automatically place footprints. No board outlines detected." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// if aFootprintsOutsideBoardOnly is true, and if board outline exists,
|
||||
// wue have to filter footprints to move:
|
||||
bool outsideBrdFilter = aFootprintsOutsideBoardOnly && edgesExist;
|
||||
|
||||
// Build candidate list
|
||||
// calculate also the area needed by these footprints
|
||||
MODULE* module = GetBoard()->m_Modules;
|
||||
std::vector <MODULE*> moduleList;
|
||||
std::vector <MODULE*> footprintList;
|
||||
|
||||
for( ; module != NULL; module = module->Next() )
|
||||
BOOST_FOREACH( MODULE* footprint, *aFootprints )
|
||||
{
|
||||
module->CalculateBoundingBox();
|
||||
footprint->CalculateBoundingBox();
|
||||
|
||||
if( outsideBrdFilter )
|
||||
{
|
||||
if( bbox.Contains( module->GetPosition() ) )
|
||||
if( bbox.Contains( footprint->GetPosition() ) )
|
||||
continue;
|
||||
}
|
||||
|
||||
if( module->IsLocked() )
|
||||
if( footprint->IsLocked() )
|
||||
continue;
|
||||
|
||||
moduleList.push_back(module);
|
||||
footprintList.push_back( footprint );
|
||||
}
|
||||
|
||||
if( moduleList.size() == 0 ) // Nothing to do
|
||||
if( footprintList.empty() )
|
||||
return;
|
||||
|
||||
// sort footprints by sheet path. we group them later by sheet
|
||||
sort( moduleList.begin(), moduleList.end(), sortModulesbySheetPath );
|
||||
sort( footprintList.begin(), footprintList.end(), sortFootprintsbySheetPath );
|
||||
|
||||
// Undo command: init undo list
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
undoList.m_Status = UR_CHANGED;
|
||||
ITEM_PICKER picker( NULL, UR_CHANGED );
|
||||
|
||||
for( unsigned ii = 0; ii < moduleList.size(); ii++ )
|
||||
BOOST_FOREACH( MODULE* footprint, footprintList )
|
||||
{
|
||||
module = moduleList[ii];
|
||||
|
||||
// Undo: add copy of module to undo list
|
||||
picker.SetItem( module );
|
||||
picker.SetLink( module->Clone() );
|
||||
// Undo: add copy of the footprint to undo list
|
||||
picker.SetItem( footprint );
|
||||
picker.SetLink( footprint->Clone() );
|
||||
undoList.PushItem( picker );
|
||||
}
|
||||
|
||||
// Extract and place footprints by sheet
|
||||
std::vector <MODULE*> moduleListBySheet;
|
||||
std::vector <MODULE*> footprintListBySheet;
|
||||
std::vector <EDA_RECT> placementSheetAreas;
|
||||
double subsurface;
|
||||
double placementsurface = 0.0;
|
||||
|
||||
wxPoint placementAreaPosition = GetCrossHairPosition();
|
||||
|
||||
// We do not want to move footprints inside an existing board.
|
||||
// We sometimes do not want to move footprints inside an existing board.
|
||||
// move the placement area position outside the board bounding box
|
||||
// to the left of the board
|
||||
if( edgesExist )
|
||||
if( edgesExist && aCheckForBoardEdges )
|
||||
{
|
||||
if( placementAreaPosition.x < bbox.GetEnd().x &&
|
||||
placementAreaPosition.y < bbox.GetEnd().y )
|
||||
|
@ -253,24 +254,25 @@ void PCB_EDIT_FRAME::SpreadFootprints( bool aFootprintsOutsideBoardOnly )
|
|||
// the first pass creates the rectangular areas to place footprints
|
||||
// each sheet in schematic creates one rectangular area.
|
||||
// the second pass moves footprints inside these areas
|
||||
MODULE* footprint;
|
||||
for( int pass = 0; pass < 2; pass++ )
|
||||
{
|
||||
int subareaIdx = 0;
|
||||
moduleListBySheet.clear();
|
||||
footprintListBySheet.clear();
|
||||
subsurface = 0.0;
|
||||
|
||||
for( unsigned ii = 0; ii < moduleList.size(); ii++ )
|
||||
for( unsigned ii = 0; ii < footprintList.size(); ii++ )
|
||||
{
|
||||
module = moduleList[ii];
|
||||
footprint = footprintList[ii];
|
||||
bool islastItem = false;
|
||||
|
||||
if( ii == moduleList.size() - 1 ||
|
||||
( moduleList[ii]->GetPath().BeforeLast( '/' ) !=
|
||||
moduleList[ii+1]->GetPath().BeforeLast( '/' ) ) )
|
||||
if( ii == footprintList.size() - 1 ||
|
||||
( footprintList[ii]->GetPath().BeforeLast( '/' ) !=
|
||||
footprintList[ii+1]->GetPath().BeforeLast( '/' ) ) )
|
||||
islastItem = true;
|
||||
|
||||
moduleListBySheet.push_back( module );
|
||||
subsurface += module->GetArea();
|
||||
footprintListBySheet.push_back( footprint );
|
||||
subsurface += footprint->GetArea();
|
||||
|
||||
if( islastItem )
|
||||
{
|
||||
|
@ -292,7 +294,7 @@ void PCB_EDIT_FRAME::SpreadFootprints( bool aFootprintsOutsideBoardOnly )
|
|||
}
|
||||
|
||||
bool findAreaOnly = pass == 0;
|
||||
moveFootprintsInArea( placementArea, moduleListBySheet,
|
||||
moveFootprintsInArea( placementArea, footprintListBySheet,
|
||||
freeArea, findAreaOnly );
|
||||
|
||||
if( pass == 0 )
|
||||
|
@ -312,7 +314,7 @@ void PCB_EDIT_FRAME::SpreadFootprints( bool aFootprintsOutsideBoardOnly )
|
|||
|
||||
// Prepare buffers for next sheet
|
||||
subsurface = 0.0;
|
||||
moduleListBySheet.clear();
|
||||
footprintListBySheet.clear();
|
||||
subareaIdx++;
|
||||
}
|
||||
}
|
||||
|
@ -353,7 +355,7 @@ void PCB_EDIT_FRAME::SpreadFootprints( bool aFootprintsOutsideBoardOnly )
|
|||
// Footprints are sorted by their sheet path.
|
||||
// (the full sheet path restricted to the time stamp of the sheet itself,
|
||||
// without the time stamp of the footprint ).
|
||||
static bool sortModulesbySheetPath( MODULE* ref, MODULE* compare )
|
||||
static bool sortFootprintsbySheetPath( MODULE* ref, MODULE* compare )
|
||||
{
|
||||
if( ref->GetPath().Length() == compare->GetPath().Length() )
|
||||
return ref->GetPath().BeforeLast( '/' ).Cmp( compare->GetPath().BeforeLast( '/' ) ) < 0;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
*
|
||||
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -2259,13 +2259,14 @@ bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAI
|
|||
|
||||
|
||||
void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||
REPORTER* aReporter )
|
||||
std::vector<MODULE*>* aNewFootprints, REPORTER* aReporter )
|
||||
{
|
||||
unsigned i;
|
||||
wxPoint bestPosition;
|
||||
wxString msg;
|
||||
D_PAD* pad;
|
||||
MODULE* footprint;
|
||||
std::vector<MODULE*> newFootprints;
|
||||
|
||||
if( !IsEmpty() )
|
||||
{
|
||||
|
@ -2340,6 +2341,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
|||
footprint->SetParent( this );
|
||||
footprint->SetPosition( bestPosition );
|
||||
footprint->SetTimeStamp( GetNewTimeStamp() );
|
||||
newFootprints.push_back( footprint );
|
||||
Add( footprint, ADD_APPEND );
|
||||
}
|
||||
}
|
||||
|
@ -2666,6 +2668,8 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::swap( newFootprints, *aNewFootprints );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -962,7 +962,7 @@ public:
|
|||
* the #BOARD. If NULL, no change reporting occurs.
|
||||
*/
|
||||
void ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||
REPORTER* aReporter = NULL );
|
||||
std::vector<MODULE*>* aNewFootprints, REPORTER* aReporter = NULL );
|
||||
|
||||
/**
|
||||
* Function SortedNetnamesList
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Copyright (C) 1992-2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -66,6 +66,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
|
|||
NETLIST netlist;
|
||||
KIGFX::VIEW* view = GetGalCanvas()->GetView();
|
||||
BOARD* board = GetBoard();
|
||||
std::vector<MODULE*> newFootprints;
|
||||
|
||||
netlist.SetIsDryRun( aIsDryRun );
|
||||
netlist.SetFindByTimeStamp( aSelectByTimeStamp );
|
||||
|
@ -113,12 +114,24 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
|
|||
m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||
|
||||
netlist.SortByReference();
|
||||
board->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter );
|
||||
board->ReplaceNetlist( netlist, aDeleteSinglePadNets, &newFootprints, aReporter );
|
||||
|
||||
|
||||
// If it was a dry run, nothing has changed so we're done.
|
||||
if( netlist.IsDryRun() )
|
||||
return;
|
||||
|
||||
if( IsGalCanvasActive() )
|
||||
{
|
||||
SpreadFootprints( &newFootprints, false, false );
|
||||
|
||||
BOOST_FOREACH( MODULE* footprint, newFootprints )
|
||||
{
|
||||
m_toolManager->RunAction( COMMON_ACTIONS::selectItem, true, footprint );
|
||||
}
|
||||
m_toolManager->InvokeTool( "pcbnew.InteractiveEdit" );
|
||||
}
|
||||
|
||||
OnModify();
|
||||
|
||||
SetCurItem( NULL );
|
||||
|
|
Loading…
Reference in New Issue