Rationalize footprint bounding boxes and cache all of them.

Fixes https://gitlab.com/kicad/code/kicad/issues/7720
This commit is contained in:
Jeff Young 2021-02-26 13:49:40 +00:00
parent da005bd2a6
commit 86aaa2e9cb
30 changed files with 224 additions and 284 deletions

View File

@ -251,7 +251,6 @@ ADVANCED_CFG::ADVANCED_CFG()
m_DebugZoneFiller = false; m_DebugZoneFiller = false;
m_DebugPDFWriter = false; m_DebugPDFWriter = false;
m_SkipBoundingBoxOnFpLoad = false;
m_SmallDrillMarkSize = 0.35; m_SmallDrillMarkSize = 0.35;
m_HotkeysDumper = false; m_HotkeysDumper = false;
m_DrawBoundingBoxes = false; m_DrawBoundingBoxes = false;
@ -336,9 +335,6 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::DebugPDFWriter, configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::DebugPDFWriter,
&m_DebugPDFWriter, false ) ); &m_DebugPDFWriter, false ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::SkipBoundingBoxFpLoad,
&m_SkipBoundingBoxOnFpLoad, false ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::SmallDrillMarkSize, configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::SmallDrillMarkSize,
&m_SmallDrillMarkSize, 0.35, 0.0, 3.0 ) ); &m_SmallDrillMarkSize, 0.35, 0.0, 3.0 ) );

View File

@ -144,11 +144,6 @@ public:
*/ */
bool m_DebugPDFWriter; bool m_DebugPDFWriter;
/**
* Skip bounding box calculation when loading footprints
*/
bool m_SkipBoundingBoxOnFpLoad;
/** /**
* The diameter of the drill marks on print and plot outputs (in mm), * The diameter of the drill marks on print and plot outputs (in mm),
* when the "Drill marks" option is set to "Small mark" * when the "Drill marks" option is set to "Small mark"

View File

@ -557,7 +557,7 @@ int AR_AUTOPLACER::testFootprintOnBoard( FOOTPRINT* aFootprint, bool TstOtherSid
side = AR_SIDE_BOTTOM; otherside = AR_SIDE_TOP; side = AR_SIDE_BOTTOM; otherside = AR_SIDE_TOP;
} }
EDA_RECT fpBBox = aFootprint->GetFootprintRect(); EDA_RECT fpBBox = aFootprint->GetBoundingBox( false, false );
fpBBox.Move( -aOffset ); fpBBox.Move( -aOffset );
buildFpAreas( aFootprint, 0 ); buildFpAreas( aFootprint, 0 );
@ -591,12 +591,10 @@ int AR_AUTOPLACER::getOptimalFPPlacement( FOOTPRINT* aFootprint )
double min_cost, curr_cost, Score; double min_cost, curr_cost, Score;
bool testOtherSide; bool testOtherSide;
aFootprint->CalculateBoundingBox();
lastPosOK = m_matrix.m_BrdBox.GetOrigin(); lastPosOK = m_matrix.m_BrdBox.GetOrigin();
wxPoint fpPos = aFootprint->GetPosition(); wxPoint fpPos = aFootprint->GetPosition();
EDA_RECT fpBBox = aFootprint->GetFootprintRect(); EDA_RECT fpBBox = aFootprint->GetBoundingBox( false, false );
// Move fpBBox to have the footprint position at (0,0) // Move fpBBox to have the footprint position at (0,0)
fpBBox.Move( -fpPos ); fpBBox.Move( -fpPos );
@ -785,10 +783,7 @@ FOOTPRINT* AR_AUTOPLACER::pickFootprint( )
for( FOOTPRINT* footprint : m_board->Footprints() ) for( FOOTPRINT* footprint : m_board->Footprints() )
{
footprint->CalculateBoundingBox();
fpList.push_back( footprint ); fpList.push_back( footprint );
}
sort( fpList.begin(), fpList.end(), sortFootprintsByComplexity ); sort( fpList.begin(), fpList.end(), sortFootprintsByComplexity );
@ -1049,7 +1044,6 @@ end_of_tst:
// Place footprint. // Place footprint.
placeFootprint( footprint, true, m_curPosition ); placeFootprint( footprint, true, m_curPosition );
footprint->CalculateBoundingBox();
genModuleOnRoutingMatrix( footprint ); genModuleOnRoutingMatrix( footprint );
footprint->SetIsPlaced( true ); footprint->SetIsPlaced( true );
footprint->SetNeedsPlaced( false ); footprint->SetNeedsPlaced( false );
@ -1075,8 +1069,5 @@ end_of_tst:
m_matrix.UnInitRoutingMatrix(); m_matrix.UnInitRoutingMatrix();
for( FOOTPRINT* fp : m_board->Footprints() )
fp->CalculateBoundingBox();
return cancelled ? AR_CANCELLED : AR_COMPLETED; return cancelled ? AR_CANCELLED : AR_COMPLETED;
} }

View File

@ -69,7 +69,7 @@ void fillRectList( CSubRectArray& vecSubRects, std::vector <FOOTPRINT*>& aFootpr
for( unsigned ii = 0; ii < aFootprintList.size(); ii++ ) for( unsigned ii = 0; ii < aFootprintList.size(); ii++ )
{ {
EDA_RECT fpBox = aFootprintList[ii]->GetFootprintRect(); EDA_RECT fpBox = aFootprintList[ii]->GetBoundingBox( false, false );
TSubRect fpRect( ( fpBox.GetWidth() + PADDING ) / scale, TSubRect fpRect( ( fpBox.GetWidth() + PADDING ) / scale,
( fpBox.GetHeight() + PADDING ) / scale, ii ); ( fpBox.GetHeight() + PADDING ) / scale, ii );
vecSubRects.push_back( fpRect ); vecSubRects.push_back( fpRect );
@ -167,7 +167,7 @@ void moveFootprintsInArea( CRectPlacement& aPlacementArea, std::vector <FOOTPRIN
FOOTPRINT* footprint = aFootprintList[vecSubRects[it].n]; FOOTPRINT* footprint = aFootprintList[vecSubRects[it].n];
EDA_RECT fpBBox = footprint->GetFootprintRect(); EDA_RECT fpBBox = footprint->GetBoundingBox( false, false );
wxPoint mod_pos = pos + ( footprint->GetPosition() - fpBBox.GetOrigin() ) wxPoint mod_pos = pos + ( footprint->GetPosition() - fpBBox.GetOrigin() )
+ aFreeArea.GetOrigin(); + aFreeArea.GetOrigin();
@ -197,7 +197,6 @@ void SpreadFootprints( std::vector<FOOTPRINT*>* aFootprints, wxPoint aSpreadArea
if( footprint->IsLocked() ) if( footprint->IsLocked() )
continue; continue;
footprint->CalculateBoundingBox();
footprintList.push_back( footprint ); footprintList.push_back( footprint );
} }
@ -240,7 +239,7 @@ void SpreadFootprints( std::vector<FOOTPRINT*>* aFootprints, wxPoint aSpreadArea
subsurface += footprint->GetArea( PADDING ); subsurface += footprint->GetArea( PADDING );
// Calculate min size of placement area: // Calculate min size of placement area:
EDA_RECT bbox = footprint->GetFootprintRect(); EDA_RECT bbox = footprint->GetBoundingBox( false, false );
fp_max_width = std::max( fp_max_width, bbox.GetWidth() ); fp_max_width = std::max( fp_max_width, bbox.GetWidth() );
fp_max_height = std::max( fp_max_height, bbox.GetHeight() ); fp_max_height = std::max( fp_max_height, bbox.GetHeight() );

View File

@ -59,6 +59,7 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 );
BOARD::BOARD() : BOARD::BOARD() :
BOARD_ITEM_CONTAINER( (BOARD_ITEM*) NULL, PCB_T ), BOARD_ITEM_CONTAINER( (BOARD_ITEM*) NULL, PCB_T ),
m_boardUse( BOARD_USE::NORMAL ), m_boardUse( BOARD_USE::NORMAL ),
m_timeStamp( 1 ),
m_paper( PAGE_INFO::A4 ), m_paper( PAGE_INFO::A4 ),
m_project( nullptr ), m_project( nullptr ),
m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ), m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ),
@ -1061,7 +1062,7 @@ EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
} }
else else
{ {
area.Merge( footprint->GetBoundingBox( showInvisibleText ) ); area.Merge( footprint->GetBoundingBox( true, showInvisibleText ) );
} }
} }
@ -1725,7 +1726,7 @@ FOOTPRINT* BOARD::GetFootprint( const wxPoint& aPosition, PCB_LAYER_ID aActiveLa
// Filter non visible footprints if requested // Filter non visible footprints if requested
if( !aVisibleOnly || IsFootprintLayerVisible( layer ) ) if( !aVisibleOnly || IsFootprintLayerVisible( layer ) )
{ {
EDA_RECT bb = candidate->GetFootprintRect(); EDA_RECT bb = candidate->GetBoundingBox( false, false );
int offx = bb.GetX() + bb.GetWidth() / 2; int offx = bb.GetX() + bb.GetWidth() / 2;
int offy = bb.GetY() + bb.GetHeight() / 2; int offy = bb.GetY() + bb.GetHeight() / 2;

View File

@ -193,6 +193,7 @@ class BOARD : public BOARD_ITEM_CONTAINER
private: private:
/// What is this board being used for /// What is this board being used for
BOARD_USE m_boardUse; BOARD_USE m_boardUse;
int m_timeStamp; // actually a modification counter
wxString m_fileName; wxString m_fileName;
MARKERS m_markers; MARKERS m_markers;
@ -213,9 +214,9 @@ private:
std::shared_ptr<CONNECTIVITY_DATA> m_connectivity; std::shared_ptr<CONNECTIVITY_DATA> m_connectivity;
PAGE_INFO m_paper; PAGE_INFO m_paper;
TITLE_BLOCK m_titles; // text in lower right of screen and plots TITLE_BLOCK m_titles; // text in lower right of screen and plots
PCB_PLOT_PARAMS m_plotOptions; PCB_PLOT_PARAMS m_plotOptions;
PROJECT* m_project; // project this board is a part of PROJECT* m_project; // project this board is a part of
/** /**
* All of the board design settings are stored as a JSON object inside the project file. The * All of the board design settings are stored as a JSON object inside the project file. The
@ -266,6 +267,9 @@ public:
*/ */
BOARD_USE GetBoardUse() const { return m_boardUse; } BOARD_USE GetBoardUse() const { return m_boardUse; }
void IncrementTimeStamp() { m_timeStamp++; }
int GetTimeStamp() { return m_timeStamp; }
/** /**
* Find out if the board is being used to hold a single footprint for editing/viewing. * Find out if the board is being used to hold a single footprint for editing/viewing.
* *

View File

@ -214,7 +214,7 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
if( footprint ) if( footprint )
{ {
bbox = footprint->GetBoundingBox( false ); // No invisible text in bbox calc bbox = footprint->GetBoundingBox( true, false ); // No invisible text in bbox calc
if( pad ) if( pad )
m_toolManager->RunAction( PCB_ACTIONS::highlightItem, true, (void*) pad ); m_toolManager->RunAction( PCB_ACTIONS::highlightItem, true, (void*) pad );

View File

@ -718,8 +718,6 @@ bool DIALOG_FOOTPRINT_FP_EDITOR::TransferDataFromWindow()
draw3D->clear(); draw3D->clear();
draw3D->insert( draw3D->end(), m_shapes3D_list.begin(), m_shapes3D_list.end() ); draw3D->insert( draw3D->end(), m_shapes3D_list.begin(), m_shapes3D_list.end() );
m_footprint->CalculateBoundingBox();
commit.Push( _( "Modify footprint properties" ) ); commit.Push( _( "Modify footprint properties" ) );
return true; return true;

View File

@ -558,7 +558,6 @@ void PCB_EDIT_FRAME::ExchangeFootprint( FOOTPRINT* aExisting, FOOTPRINT* aNew,
const_cast<KIID&>( aNew->m_Uuid ) = aExisting->m_Uuid; const_cast<KIID&>( aNew->m_Uuid ) = aExisting->m_Uuid;
aNew->SetProperties( aExisting->GetProperties() ); aNew->SetProperties( aExisting->GetProperties() );
aNew->SetPath( aExisting->GetPath() ); aNew->SetPath( aExisting->GetPath() );
aNew->CalculateBoundingBox();
aCommit.Remove( aExisting ); aCommit.Remove( aExisting );
aCommit.Add( aNew ); aCommit.Add( aNew );

View File

@ -780,8 +780,6 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataFromWindow()
draw3D->clear(); draw3D->clear();
draw3D->insert( draw3D->end(), m_shapes3D_list.begin(), m_shapes3D_list.end() ); draw3D->insert( draw3D->end(), m_shapes3D_list.begin(), m_shapes3D_list.end() );
m_footprint->CalculateBoundingBox();
// This is a simple edit, we must create an undo entry // This is a simple edit, we must create an undo entry
if( m_footprint->GetEditFlags() == 0 ) // i.e. not edited, or moved if( m_footprint->GetEditFlags() == 0 ) // i.e. not edited, or moved
commit.Push( _( "Modify footprint properties" ) ); commit.Push( _( "Modify footprint properties" ) );

View File

@ -1632,9 +1632,6 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
footprint->GetOrientation() ); footprint->GetOrientation() );
} }
if( footprint )
footprint->CalculateBoundingBox();
m_parent->SetMsgPanel( m_currentPad ); m_parent->SetMsgPanel( m_currentPad );
// redraw the area where the pad was // redraw the area where the pad was

View File

@ -45,13 +45,16 @@
FOOTPRINT::FOOTPRINT( BOARD* parent ) : FOOTPRINT::FOOTPRINT( BOARD* parent ) :
BOARD_ITEM_CONTAINER((BOARD_ITEM*) parent, PCB_FOOTPRINT_T ), BOARD_ITEM_CONTAINER((BOARD_ITEM*) parent, PCB_FOOTPRINT_T ),
m_boundingBoxCacheTimeStamp( 0 ),
m_visibleBBoxCacheTimeStamp( 0 ),
m_textExcludedBBoxCacheTimeStamp( 0 ),
m_hullCacheTimeStamp( 0 ),
m_initial_comments( 0 ) m_initial_comments( 0 )
{ {
m_attributes = 0; m_attributes = 0;
m_layer = F_Cu; m_layer = F_Cu;
m_orient = 0; m_orient = 0;
m_fpStatus = FP_PADS_are_LOCKED; m_fpStatus = FP_PADS_are_LOCKED;
m_hullDirty = true;
m_arflag = 0; m_arflag = 0;
m_rot90Cost = m_rot180Cost = 0; m_rot90Cost = m_rot180Cost = 0;
m_link = 0; m_link = 0;
@ -69,8 +72,6 @@ FOOTPRINT::FOOTPRINT( BOARD* parent ) :
m_value = new FP_TEXT( this, FP_TEXT::TEXT_is_VALUE ); m_value = new FP_TEXT( this, FP_TEXT::TEXT_is_VALUE );
m_3D_Drawings.clear(); m_3D_Drawings.clear();
UpdateBoundingHull();
} }
@ -82,22 +83,28 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
m_attributes = aFootprint.m_attributes; m_attributes = aFootprint.m_attributes;
m_fpStatus = aFootprint.m_fpStatus; m_fpStatus = aFootprint.m_fpStatus;
m_orient = aFootprint.m_orient; m_orient = aFootprint.m_orient;
m_boundingBox = aFootprint.m_boundingBox;
m_hullDirty = aFootprint.m_hullDirty;
m_hull = aFootprint.m_hull;
m_rot90Cost = aFootprint.m_rot90Cost; m_rot90Cost = aFootprint.m_rot90Cost;
m_rot180Cost = aFootprint.m_rot180Cost; m_rot180Cost = aFootprint.m_rot180Cost;
m_lastEditTime = aFootprint.m_lastEditTime; m_lastEditTime = aFootprint.m_lastEditTime;
m_link = aFootprint.m_link; m_link = aFootprint.m_link;
m_path = aFootprint.m_path; m_path = aFootprint.m_path;
m_localClearance = aFootprint.m_localClearance; m_cachedBoundingBox = aFootprint.m_cachedBoundingBox;
m_localSolderMaskMargin = aFootprint.m_localSolderMaskMargin; m_boundingBoxCacheTimeStamp = aFootprint.m_boundingBoxCacheTimeStamp;
m_localSolderPasteMargin = aFootprint.m_localSolderPasteMargin; m_cachedVisibleBBox = aFootprint.m_cachedVisibleBBox;
m_localSolderPasteMarginRatio = aFootprint.m_localSolderPasteMarginRatio; m_visibleBBoxCacheTimeStamp = aFootprint.m_visibleBBoxCacheTimeStamp;
m_zoneConnection = aFootprint.m_zoneConnection; m_cachedTextExcludedBBox = aFootprint.m_cachedTextExcludedBBox;
m_thermalWidth = aFootprint.m_thermalWidth; m_textExcludedBBoxCacheTimeStamp = aFootprint.m_textExcludedBBoxCacheTimeStamp;
m_thermalGap = aFootprint.m_thermalGap; m_cachedHull = aFootprint.m_cachedHull;
m_hullCacheTimeStamp = aFootprint.m_hullCacheTimeStamp;
m_localClearance = aFootprint.m_localClearance;
m_localSolderMaskMargin = aFootprint.m_localSolderMaskMargin;
m_localSolderPasteMargin = aFootprint.m_localSolderPasteMargin;
m_localSolderPasteMarginRatio = aFootprint.m_localSolderPasteMarginRatio;
m_zoneConnection = aFootprint.m_zoneConnection;
m_thermalWidth = aFootprint.m_thermalWidth;
m_thermalGap = aFootprint.m_thermalGap;
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap; std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
@ -170,9 +177,6 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
m_initial_comments = aFootprint.m_initial_comments ? m_initial_comments = aFootprint.m_initial_comments ?
new wxArrayString( *aFootprint.m_initial_comments ) : nullptr; new wxArrayString( *aFootprint.m_initial_comments ) : nullptr;
if( m_hullDirty )
UpdateBoundingHull();
} }
@ -221,22 +225,28 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
m_attributes = aOther.m_attributes; m_attributes = aOther.m_attributes;
m_fpStatus = aOther.m_fpStatus; m_fpStatus = aOther.m_fpStatus;
m_orient = aOther.m_orient; m_orient = aOther.m_orient;
m_boundingBox = aOther.m_boundingBox;
m_hull = aOther.m_hull;
m_hullDirty = aOther.m_hullDirty;
m_rot90Cost = aOther.m_rot90Cost; m_rot90Cost = aOther.m_rot90Cost;
m_rot180Cost = aOther.m_rot180Cost; m_rot180Cost = aOther.m_rot180Cost;
m_lastEditTime = aOther.m_lastEditTime; m_lastEditTime = aOther.m_lastEditTime;
m_link = aOther.m_link; m_link = aOther.m_link;
m_path = aOther.m_path; m_path = aOther.m_path;
m_localClearance = aOther.m_localClearance; m_cachedBoundingBox = aOther.m_cachedBoundingBox;
m_localSolderMaskMargin = aOther.m_localSolderMaskMargin; m_boundingBoxCacheTimeStamp = aOther.m_boundingBoxCacheTimeStamp;
m_localSolderPasteMargin = aOther.m_localSolderPasteMargin; m_cachedVisibleBBox = aOther.m_cachedVisibleBBox;
m_localSolderPasteMarginRatio = aOther.m_localSolderPasteMarginRatio; m_visibleBBoxCacheTimeStamp = aOther.m_visibleBBoxCacheTimeStamp;
m_zoneConnection = aOther.m_zoneConnection; m_cachedTextExcludedBBox = aOther.m_cachedTextExcludedBBox;
m_thermalWidth = aOther.m_thermalWidth; m_textExcludedBBoxCacheTimeStamp = aOther.m_textExcludedBBoxCacheTimeStamp;
m_thermalGap = aOther.m_thermalGap; m_cachedHull = aOther.m_cachedHull;
m_hullCacheTimeStamp = aOther.m_hullCacheTimeStamp;
m_localClearance = aOther.m_localClearance;
m_localSolderMaskMargin = aOther.m_localSolderMaskMargin;
m_localSolderPasteMargin = aOther.m_localSolderPasteMargin;
m_localSolderPasteMarginRatio = aOther.m_localSolderPasteMarginRatio;
m_zoneConnection = aOther.m_zoneConnection;
m_thermalWidth = aOther.m_thermalWidth;
m_thermalGap = aOther.m_thermalGap;
// Move reference and value // Move reference and value
m_reference = aOther.m_reference; m_reference = aOther.m_reference;
@ -292,10 +302,6 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
m_keywords = aOther.m_keywords; m_keywords = aOther.m_keywords;
m_properties = aOther.m_properties; m_properties = aOther.m_properties;
// Ensure auxiliary data is up to date
CalculateBoundingBox();
UpdateBoundingHull();
m_initial_comments = aOther.m_initial_comments; m_initial_comments = aOther.m_initial_comments;
// Clear the other item's containers since this is a move // Clear the other item's containers since this is a move
@ -319,22 +325,28 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
m_attributes = aOther.m_attributes; m_attributes = aOther.m_attributes;
m_fpStatus = aOther.m_fpStatus; m_fpStatus = aOther.m_fpStatus;
m_orient = aOther.m_orient; m_orient = aOther.m_orient;
m_boundingBox = aOther.m_boundingBox;
m_hull = aOther.m_hull;
m_hullDirty = aOther.m_hullDirty;
m_rot90Cost = aOther.m_rot90Cost; m_rot90Cost = aOther.m_rot90Cost;
m_rot180Cost = aOther.m_rot180Cost; m_rot180Cost = aOther.m_rot180Cost;
m_lastEditTime = aOther.m_lastEditTime; m_lastEditTime = aOther.m_lastEditTime;
m_link = aOther.m_link; m_link = aOther.m_link;
m_path = aOther.m_path; m_path = aOther.m_path;
m_localClearance = aOther.m_localClearance; m_cachedBoundingBox = aOther.m_cachedBoundingBox;
m_localSolderMaskMargin = aOther.m_localSolderMaskMargin; m_boundingBoxCacheTimeStamp = aOther.m_boundingBoxCacheTimeStamp;
m_localSolderPasteMargin = aOther.m_localSolderPasteMargin; m_cachedVisibleBBox = aOther.m_cachedVisibleBBox;
m_localSolderPasteMarginRatio = aOther.m_localSolderPasteMarginRatio; m_visibleBBoxCacheTimeStamp = aOther.m_visibleBBoxCacheTimeStamp;
m_zoneConnection = aOther.m_zoneConnection; m_cachedTextExcludedBBox = aOther.m_cachedTextExcludedBBox;
m_thermalWidth = aOther.m_thermalWidth; m_textExcludedBBoxCacheTimeStamp = aOther.m_textExcludedBBoxCacheTimeStamp;
m_thermalGap = aOther.m_thermalGap; m_cachedHull = aOther.m_cachedHull;
m_hullCacheTimeStamp = aOther.m_hullCacheTimeStamp;
m_localClearance = aOther.m_localClearance;
m_localSolderMaskMargin = aOther.m_localSolderMaskMargin;
m_localSolderPasteMargin = aOther.m_localSolderPasteMargin;
m_localSolderPasteMarginRatio = aOther.m_localSolderPasteMarginRatio;
m_zoneConnection = aOther.m_zoneConnection;
m_thermalWidth = aOther.m_thermalWidth;
m_thermalGap = aOther.m_thermalGap;
// Copy reference and value // Copy reference and value
*m_reference = *aOther.m_reference; *m_reference = *aOther.m_reference;
@ -401,10 +413,6 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
m_keywords = aOther.m_keywords; m_keywords = aOther.m_keywords;
m_properties = aOther.m_properties; m_properties = aOther.m_properties;
// Ensure auxiliary data is up to date
CalculateBoundingBox();
UpdateBoundingHull();
m_initial_comments = aOther.m_initial_comments ? m_initial_comments = aOther.m_initial_comments ?
new wxArrayString( *aOther.m_initial_comments ) : nullptr; new wxArrayString( *aOther.m_initial_comments ) : nullptr;
@ -504,9 +512,6 @@ void FOOTPRINT::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
} }
} }
if( aBoardItem->Type() != PCB_FP_TEXT_T )
m_hullDirty = true;
aBoardItem->ClearEditFlags(); aBoardItem->ClearEditFlags();
aBoardItem->SetParent( this ); aBoardItem->SetParent( this );
} }
@ -586,52 +591,19 @@ void FOOTPRINT::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aMode )
if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) ) if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
parentGroup->RemoveItem( aBoardItem ); parentGroup->RemoveItem( aBoardItem );
if( aBoardItem->Type() != PCB_FP_TEXT_T )
m_hullDirty = true;
}
void FOOTPRINT::CalculateBoundingBox()
{
m_boundingBox = GetFootprintRect();
} }
double FOOTPRINT::GetArea( int aPadding ) const double FOOTPRINT::GetArea( int aPadding ) const
{ {
double w = std::abs( static_cast<double>( m_boundingBox.GetWidth() ) ) + aPadding; EDA_RECT bbox = GetBoundingBox( false, false );
double h = std::abs( static_cast<double>( m_boundingBox.GetHeight() ) ) + aPadding;
double w = std::abs( static_cast<double>( bbox.GetWidth() ) ) + aPadding;
double h = std::abs( static_cast<double>( bbox.GetHeight() ) ) + aPadding;
return w * h; return w * h;
} }
EDA_RECT FOOTPRINT::GetFootprintRect() const
{
EDA_RECT area;
area.SetOrigin( m_pos );
area.SetEnd( m_pos );
area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
for( BOARD_ITEM* item : m_drawings )
{
if( item->Type() == PCB_FP_SHAPE_T )
area.Merge( item->GetBoundingBox() );
}
for( PAD* pad : m_pads )
area.Merge( pad->GetBoundingBox() );
for( FP_ZONE* zone : m_fp_zones )
area.Merge( zone->GetBoundingBox() );
// Groups do not contribute to the rect, only their members
return area;
}
EDA_RECT FOOTPRINT::GetFpPadsLocalBbox() const EDA_RECT FOOTPRINT::GetFpPadsLocalBbox() const
{ {
EDA_RECT area; EDA_RECT area;
@ -657,61 +629,122 @@ EDA_RECT FOOTPRINT::GetFpPadsLocalBbox() const
const EDA_RECT FOOTPRINT::GetBoundingBox() const const EDA_RECT FOOTPRINT::GetBoundingBox() const
{ {
return GetBoundingBox( true ); return GetBoundingBox( true, true );
} }
const EDA_RECT FOOTPRINT::GetBoundingBox( bool aIncludeInvisibleText ) const const EDA_RECT FOOTPRINT::GetBoundingBox( bool aIncludeText, bool aIncludeInvisibleText ) const
{ {
EDA_RECT area = GetFootprintRect(); BOARD* board = GetBoard();
// Add in items not collected by GetFootprintRect():
for( BOARD_ITEM* item : m_drawings )
{
if( item->Type() != PCB_FP_SHAPE_T )
area.Merge( item->GetBoundingBox() );
}
// This can be further optimized when aIncludeInvisibleText is true, but currently
// leaving this as is until it's determined there is a noticeable speed hit.
bool valueLayerIsVisible = true;
bool refLayerIsVisible = true;
BOARD* board = GetBoard();
if( board ) if( board )
{ {
// The first "&&" conditional handles the user turning layers off as well as layers if( aIncludeText && aIncludeInvisibleText )
// not being present in the current PCB stackup. Values, references, and all {
// footprint text can also be turned off via the GAL meta-layers, so the 2nd and if( m_boundingBoxCacheTimeStamp >= board->GetTimeStamp() )
// 3rd "&&" conditionals handle that. return m_cachedBoundingBox;
valueLayerIsVisible = board->IsLayerVisible( m_value->GetLayer() ) }
&& board->IsElementVisible( LAYER_MOD_VALUES ) else if( aIncludeText )
&& board->IsElementVisible( LAYER_MOD_TEXT_FR ); {
if( m_visibleBBoxCacheTimeStamp >= board->GetTimeStamp() )
refLayerIsVisible = board->IsLayerVisible( m_reference->GetLayer() ) return m_cachedVisibleBBox;
&& board->IsElementVisible( LAYER_MOD_REFERENCES ) }
&& board->IsElementVisible( LAYER_MOD_TEXT_FR ); else
{
if( m_textExcludedBBoxCacheTimeStamp >= board->GetTimeStamp() )
return m_cachedTextExcludedBBox;
}
} }
EDA_RECT area;
if(( m_value->IsVisible() && valueLayerIsVisible ) || aIncludeInvisibleText ) area.SetOrigin( m_pos );
area.Merge( m_value->GetBoundingBox() ); area.SetEnd( m_pos );
area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
if(( m_reference->IsVisible() && refLayerIsVisible ) || aIncludeInvisibleText ) for( BOARD_ITEM* item : m_drawings )
area.Merge( m_reference->GetBoundingBox() ); {
if( item->Type() == PCB_FP_SHAPE_T )
area.Merge( item->GetBoundingBox() );
}
for( PAD* pad : m_pads )
area.Merge( pad->GetBoundingBox() );
for( FP_ZONE* zone : m_fp_zones )
area.Merge( zone->GetBoundingBox() );
// Groups do not contribute to the rect, only their members
if( aIncludeText )
{
for( BOARD_ITEM* item : m_drawings )
{
if( item->Type() == PCB_FP_TEXT_T )
area.Merge( item->GetBoundingBox() );
}
// This can be further optimized when aIncludeInvisibleText is true, but currently
// leaving this as is until it's determined there is a noticeable speed hit.
bool valueLayerIsVisible = true;
bool refLayerIsVisible = true;
if( board )
{
// The first "&&" conditional handles the user turning layers off as well as layers
// not being present in the current PCB stackup. Values, references, and all
// footprint text can also be turned off via the GAL meta-layers, so the 2nd and
// 3rd "&&" conditionals handle that.
valueLayerIsVisible = board->IsLayerVisible( m_value->GetLayer() )
&& board->IsElementVisible( LAYER_MOD_VALUES )
&& board->IsElementVisible( LAYER_MOD_TEXT_FR );
refLayerIsVisible = board->IsLayerVisible( m_reference->GetLayer() )
&& board->IsElementVisible( LAYER_MOD_REFERENCES )
&& board->IsElementVisible( LAYER_MOD_TEXT_FR );
}
if( ( m_value->IsVisible() && valueLayerIsVisible ) || aIncludeInvisibleText )
area.Merge( m_value->GetBoundingBox() );
if( ( m_reference->IsVisible() && refLayerIsVisible ) || aIncludeInvisibleText )
area.Merge( m_reference->GetBoundingBox() );
}
if( board )
{
if( aIncludeText && aIncludeInvisibleText )
{
m_boundingBoxCacheTimeStamp = board->GetTimeStamp();
m_cachedBoundingBox = area;
}
else if( aIncludeText )
{
m_visibleBBoxCacheTimeStamp = board->GetTimeStamp();
m_cachedVisibleBBox = area;
}
else
{
m_textExcludedBBoxCacheTimeStamp = board->GetTimeStamp();
m_cachedTextExcludedBBox = area;
}
}
return area; return area;
} }
void FOOTPRINT::UpdateBoundingHull() SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
{ {
m_hull = CalculateBoundingHull(); BOARD* board = GetBoard();
m_hullDirty = false;
} if( board )
{
if( m_hullCacheTimeStamp >= board->GetTimeStamp() )
return m_cachedHull;
}
SHAPE_POLY_SET FOOTPRINT::CalculateBoundingHull() const
{
SHAPE_POLY_SET rawPolys; SHAPE_POLY_SET rawPolys;
SHAPE_POLY_SET hull; SHAPE_POLY_SET hull;
@ -765,34 +798,16 @@ SHAPE_POLY_SET FOOTPRINT::CalculateBoundingHull() const
std::vector<wxPoint> convex_hull; std::vector<wxPoint> convex_hull;
BuildConvexHull( convex_hull, rawPolys ); BuildConvexHull( convex_hull, rawPolys );
SHAPE_POLY_SET hullPoly; m_cachedHull.RemoveAllContours();
hullPoly.NewOutline(); m_cachedHull.NewOutline();
for( const wxPoint& pt : convex_hull ) for( const wxPoint& pt : convex_hull )
hullPoly.Append( pt ); m_cachedHull.Append( pt );
return hullPoly; if( board )
} m_hullCacheTimeStamp = board->GetTimeStamp();
return m_cachedHull;
SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
{
if( m_hullDirty )
return CalculateBoundingHull();
return m_hull;
}
SHAPE_POLY_SET FOOTPRINT::GetBoundingHull()
{
if( m_hullDirty )
{
m_hull = CalculateBoundingHull();
m_hullDirty = false;
}
return m_hull;
} }
@ -887,7 +902,7 @@ bool FOOTPRINT::IsOnLayer( PCB_LAYER_ID aLayer ) const
bool FOOTPRINT::HitTest( const wxPoint& aPosition, int aAccuracy ) const bool FOOTPRINT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{ {
EDA_RECT rect = m_boundingBox;//.GetBoundingBoxRotated( GetPosition(), m_Orient ); EDA_RECT rect = GetBoundingBox( false, false );
return rect.Inflate( aAccuracy ).Contains( aPosition ); return rect.Inflate( aAccuracy ).Contains( aPosition );
} }
@ -904,11 +919,11 @@ bool FOOTPRINT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy )
arect.Inflate( aAccuracy ); arect.Inflate( aAccuracy );
if( aContained ) if( aContained )
return arect.Contains( m_boundingBox ); return arect.Contains( false, false );
else else
{ {
// If the rect does not intersect the bounding box, skip any tests // If the rect does not intersect the bounding box, skip any tests
if( !aRect.Intersects( GetBoundingBox() ) ) if( !aRect.Intersects( GetBoundingBox( false, false ) ) )
return false; return false;
// Determine if any elements in the FOOTPRINT intersect the rect // Determine if any elements in the FOOTPRINT intersect the rect
@ -926,7 +941,7 @@ bool FOOTPRINT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy )
for( BOARD_ITEM* item : m_drawings ) for( BOARD_ITEM* item : m_drawings )
{ {
if( item->HitTest( arect, false, 0 ) ) if( item->Type() != PCB_FP_TEXT_T && item->HitTest( arect, false, 0 ) )
return true; return true;
} }
@ -1274,11 +1289,7 @@ double FOOTPRINT::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
const BOX2I FOOTPRINT::ViewBBox() const const BOX2I FOOTPRINT::ViewBBox() const
{ {
EDA_RECT area = GetFootprintRect(); EDA_RECT area = GetBoundingBox( true, true );
// Calculate extended area including text fields
area.Merge( m_reference->GetBoundingBox() );
area.Merge( m_value->GetBoundingBox() );
// Add the Clearance shape size: (shape around the pads when the clearance is shown. Not // Add the Clearance shape size: (shape around the pads when the clearance is shown. Not
// optimized, but the draw cost is small (perhaps smaller than optimization). // optimized, but the draw cost is small (perhaps smaller than optimization).
@ -1344,6 +1355,11 @@ void FOOTPRINT::Rotate( const wxPoint& aRotCentre, double aAngle )
if( item->Type() == PCB_FP_TEXT_T ) if( item->Type() == PCB_FP_TEXT_T )
static_cast<FP_TEXT*>( item )->KeepUpright( orientation, newOrientation ); static_cast<FP_TEXT*>( item )->KeepUpright( orientation, newOrientation );
} }
m_boundingBoxCacheTimeStamp = 0;
m_visibleBBoxCacheTimeStamp = 0;
m_textExcludedBBoxCacheTimeStamp = 0;
m_hullCacheTimeStamp = 0;
} }
@ -1408,12 +1424,11 @@ void FOOTPRINT::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
if( aFlipLeftRight ) if( aFlipLeftRight )
Rotate( aCentre, 1800.0 ); Rotate( aCentre, 1800.0 );
CalculateBoundingBox(); m_boundingBoxCacheTimeStamp = 0;
m_visibleBBoxCacheTimeStamp = 0;
m_textExcludedBBoxCacheTimeStamp = 0;
if( m_hullDirty ) m_cachedHull.Mirror( aFlipLeftRight, !aFlipLeftRight, m_pos );
UpdateBoundingHull();
else
m_hull.Mirror( aFlipLeftRight, !aFlipLeftRight, m_pos );
std::swap( m_poly_courtyard_front, m_poly_courtyard_back ); std::swap( m_poly_courtyard_front, m_poly_courtyard_back );
} }
@ -1458,12 +1473,10 @@ void FOOTPRINT::SetPosition( const wxPoint& aPos )
} }
} }
m_boundingBox.Move( delta ); m_cachedBoundingBox.Move( delta );
m_cachedVisibleBBox.Move( delta );
if( m_hullDirty ) m_cachedTextExcludedBBox.Move( delta );
UpdateBoundingHull(); m_cachedHull.Move( delta );
else
m_hull.Move( delta );
} }
@ -1520,8 +1533,10 @@ void FOOTPRINT::MoveAnchorPosition( const wxPoint& aMoveVector )
} }
} }
CalculateBoundingBox(); m_cachedBoundingBox.Move( moveVector );
m_hull.Move( moveVector ); m_cachedVisibleBBox.Move( moveVector );
m_cachedTextExcludedBBox.Move( moveVector );
m_cachedHull.Move( moveVector );
} }
@ -1561,8 +1576,11 @@ void FOOTPRINT::SetOrientation( double aNewAngle )
} }
} }
CalculateBoundingBox(); m_boundingBoxCacheTimeStamp = 0;
m_hull.Rotate( -DECIDEG2RAD( angleChange ), GetPosition() ); m_visibleBBoxCacheTimeStamp = 0;
m_textExcludedBBoxCacheTimeStamp = 0;
m_cachedHull.Rotate( -DECIDEG2RAD( angleChange ), GetPosition() );
} }

View File

@ -139,26 +139,6 @@ public:
*/ */
void ClearAllNets(); void ClearAllNets();
/**
* Calculate the bounding box in board coordinates.
*/
void CalculateBoundingBox();
/**
* Build and returns the boundary box of the footprint excluding any text.
*
* @return The rectangle containing the footprint.
*/
EDA_RECT GetFootprintRect() const;
/**
* Return the last calculated bounding box of the footprint (does not recalculate it).
* (call CalculateBoundingBox() to recalculate it).
*
* @return The rectangle containing the footprint.
*/
EDA_RECT GetBoundingBoxBase() const { return m_boundingBox; }
/** /**
* Return the bounding box containing pads when the footprint is on the front side, * Return the bounding box containing pads when the footprint is on the front side,
* orientation 0, position 0,0. * orientation 0, position 0,0.
@ -175,19 +155,11 @@ public:
* *
* This operation is slower but more accurate than calculating a bounding box. * This operation is slower but more accurate than calculating a bounding box.
*/ */
SHAPE_POLY_SET GetBoundingHull();
SHAPE_POLY_SET GetBoundingHull() const; SHAPE_POLY_SET GetBoundingHull() const;
/**
* Update the cached bounding Hull with current data
*/
SHAPE_POLY_SET CalculateBoundingHull() const;
void UpdateBoundingHull();
// Virtual function // Virtual function
const EDA_RECT GetBoundingBox() const override; const EDA_RECT GetBoundingBox() const override;
const EDA_RECT GetBoundingBox( bool aIncludeInvisibleText ) const; const EDA_RECT GetBoundingBox( bool aIncludeText, bool aIncludeInvisibleText ) const;
PADS& Pads() { return m_pads; } PADS& Pads() { return m_pads; }
const PADS& Pads() const { return m_pads; } const PADS& Pads() const { return m_pads; }
@ -716,11 +688,15 @@ private:
LIB_ID m_fpid; // The #LIB_ID of the FOOTPRINT. LIB_ID m_fpid; // The #LIB_ID of the FOOTPRINT.
int m_attributes; // Flag bits ( see FOOTPRINT_ATTR_T ) int m_attributes; // Flag bits ( see FOOTPRINT_ATTR_T )
int m_fpStatus; // For autoplace: flags (LOCKED, FIELDS_AUTOPLACED) int m_fpStatus; // For autoplace: flags (LOCKED, FIELDS_AUTOPLACED)
EDA_RECT m_boundingBox; // Bounding box : coordinates on board, real orientation.
mutable EDA_RECT m_cachedBoundingBox;
mutable bool m_hullDirty; // If the hull needs to be re-calculated mutable int m_boundingBoxCacheTimeStamp;
SHAPE_POLY_SET m_hull; // Convex wrapping hull of the footprint mutable EDA_RECT m_cachedVisibleBBox;
mutable int m_visibleBBoxCacheTimeStamp;
mutable EDA_RECT m_cachedTextExcludedBBox;
mutable int m_textExcludedBBoxCacheTimeStamp;
mutable SHAPE_POLY_SET m_cachedHull;
mutable int m_hullCacheTimeStamp;
ZONE_CONNECTION m_zoneConnection; ZONE_CONNECTION m_zoneConnection;
int m_thermalWidth; int m_thermalWidth;

View File

@ -581,7 +581,7 @@ const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible )
if( hasGraphicalItem ) if( hasGraphicalItem )
{ {
return footprint->GetFootprintRect(); return footprint->GetBoundingBox( false, false );
} }
else else
{ {

View File

@ -175,7 +175,6 @@ FOOTPRINT* MICROWAVE_TOOL::createFootprint( MICROWAVE_FOOTPRINT_SHAPE aFootprint
} }
// Update the footprint and board // Update the footprint and board
footprint->CalculateBoundingBox();
editFrame.OnModify(); editFrame.OnModify();
return footprint; return footprint;

View File

@ -388,7 +388,9 @@ FOOTPRINT* MICROWAVE_TOOL::createMicrowaveInductor( MICROWAVE_INDUCTOR_PATTERN&
// Calculate the elements. // Calculate the elements.
std::vector <wxPoint> buffer; std::vector <wxPoint> buffer;
const INDUCTOR_S_SHAPE_RESULT res = BuildCornersList_S_Shape( buffer, aInductorPattern.m_Start, const INDUCTOR_S_SHAPE_RESULT res = BuildCornersList_S_Shape( buffer, aInductorPattern.m_Start,
aInductorPattern.m_End, aInductorPattern.m_Length, aInductorPattern.m_Width ); aInductorPattern.m_End,
aInductorPattern.m_Length,
aInductorPattern.m_Width );
switch( res ) switch( res )
{ {
@ -471,6 +473,5 @@ FOOTPRINT* MICROWAVE_TOOL::createMicrowaveInductor( MICROWAVE_INDUCTOR_PATTERN&
valPos.y += footprint->Value().GetTextSize().y; valPos.y += footprint->Value().GetTextSize().y;
footprint->Value().SetPosition( valPos ); footprint->Value().SetPosition( valPos );
footprint->CalculateBoundingBox();
return footprint; return footprint;
} }

View File

@ -349,7 +349,6 @@ FOOTPRINT* MICROWAVE_TOOL::createPolygonShape()
shape->SetWidth( 0 ); shape->SetWidth( 0 );
PolyEdges.clear(); PolyEdges.clear();
footprint->CalculateBoundingBox();
editFrame.OnModify(); editFrame.OnModify();
return footprint; return footprint;
} }

View File

@ -691,6 +691,8 @@ void PCB_BASE_FRAME::OnModify()
GetScreen()->SetModify(); GetScreen()->SetModify();
GetScreen()->SetSave(); GetScreen()->SetSave();
GetBoard()->IncrementTimeStamp();
UpdateStatusBar(); UpdateStatusBar();
UpdateMsgPanel(); UpdateMsgPanel();
} }

View File

@ -1448,7 +1448,7 @@ void PCB_PAINTER::draw( const FOOTPRINT* aFootprint, int aLayer )
#if 0 // For debug purpose only: draw the footing bounding box #if 0 // For debug purpose only: draw the footing bounding box
double bboxThickness = 1.0 / m_gal->GetWorldScale(); double bboxThickness = 1.0 / m_gal->GetWorldScale();
m_gal->SetLineWidth( bboxThickness ); m_gal->SetLineWidth( bboxThickness );
EDA_RECT rect = aFootprint->GetBoundingBoxBase(); EDA_RECT rect = aFootprint->GetBoundingBox();
m_gal->DrawRectangle( VECTOR2D( rect.GetOrigin() ), VECTOR2D( rect.GetEnd() ) ); m_gal->DrawRectangle( VECTOR2D( rect.GetOrigin() ), VECTOR2D( rect.GetEnd() ) );
double bboxThickness = 3.0 / m_gal->GetWorldScale(); double bboxThickness = 3.0 / m_gal->GetWorldScale();

View File

@ -471,13 +471,6 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader,
m_board->GetDesignSettings().m_AuxOrigin += movementVector; m_board->GetDesignSettings().m_AuxOrigin += movementVector;
m_board->GetDesignSettings().m_GridOrigin += movementVector; m_board->GetDesignSettings().m_GridOrigin += movementVector;
// Finish Board by recalculating footprint boundingboxes
for( FOOTPRINT* footprint : m_board->Footprints() )
{
footprint->CalculateBoundingBox();
footprint->UpdateBoundingHull();
}
// Otherwise we cannot save the imported board
m_board->SetModified(); m_board->SetModified();
} }

View File

@ -1237,10 +1237,6 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
footprint->Reference().SetLocalCoord(); footprint->Reference().SetLocalCoord();
footprint->Value().SetLocalCoord(); footprint->Value().SetLocalCoord();
// Calculate the bounding boxes
footprint->CalculateBoundingBox();
footprint->UpdateBoundingHull();
// Get next element // Get next element
element = element->GetNext(); element = element->GetNext();
} }

View File

@ -24,7 +24,7 @@
/** /**
* @file pcad_plugin.cpp * @file pcad_plugin.cpp
* @brief Pcbnew PLUGIN for FABMASTER ASCII *.txt/*.fab format. * @brief Pcbnew PLUGIN for FABMASTER ASCII *.txt / *.fab format.
*/ */
#include "fabmaster_plugin.h" #include "fabmaster_plugin.h"

View File

@ -2248,9 +2248,6 @@ bool FABMASTER::loadFootprints( BOARD* aBoard )
fp->Flip( fp->GetPosition(), true ); fp->Flip( fp->GetPosition(), true );
} }
fp->CalculateBoundingBox();
fp->UpdateBoundingHull();
aBoard->Add( fp, ADD_MODE::APPEND ); aBoard->Add( fp, ADD_MODE::APPEND );
} }
} }

View File

@ -687,9 +687,6 @@ FOOTPRINT* GPCB_FPL_CACHE::parseFOOTPRINT( LINE_READER* aLineReader )
} }
} }
// Recalculate the bounding box
footprint->CalculateBoundingBox();
footprint->UpdateBoundingHull();
return footprint.release(); return footprint.release();
} }

View File

@ -3212,17 +3212,6 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
footprint->SetFPID( fpid ); footprint->SetFPID( fpid );
footprint->SetProperties( properties ); footprint->SetProperties( properties );
// We want to calculate the bounding box in most cases except if the advanced config is set
// and its a general footprint load. This improves debugging greatly under MSVC where full
// STL iterator debugging is present and loading a massive amount of footprints can lead to
// 2 minute load times.
if( !ADVANCED_CFG::GetCfg().m_SkipBoundingBoxOnFpLoad || m_board != nullptr
|| reader->GetSource().Contains( "clipboard" ) )
{
footprint->CalculateBoundingBox();
footprint->UpdateBoundingHull();
}
return footprint.release(); return footprint.release();
} }

View File

@ -1370,9 +1370,6 @@ void LEGACY_PLUGIN::loadFOOTPRINT( FOOTPRINT* aFootprint )
else if( TESTLINE( "$EndMODULE" ) ) else if( TESTLINE( "$EndMODULE" ) )
{ {
aFootprint->CalculateBoundingBox();
aFootprint->UpdateBoundingHull();
return; // preferred exit return; // preferred exit
} }
} }

View File

@ -611,9 +611,6 @@ void PCB_FOOTPRINT::AddToBoard()
if( m_FootprintItems[i]->m_objType == wxT( 'V' ) ) if( m_FootprintItems[i]->m_objType == wxT( 'V' ) )
((PCB_VIA*) m_FootprintItems[ i ] )->AddToFootprint( footprint, m_rotation, false ); ((PCB_VIA*) m_FootprintItems[ i ] )->AddToFootprint( footprint, m_rotation, false );
} }
footprint->CalculateBoundingBox();
footprint->UpdateBoundingHull();
} }

View File

@ -490,11 +490,11 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
addAnchor( position, ORIGIN | SNAPPABLE, footprint ); addAnchor( position, ORIGIN | SNAPPABLE, footprint );
// Add the footprint center point if it is markedly different from the origin // Add the footprint center point if it is markedly different from the origin
VECTOR2I center = footprint->GetFootprintRect().Centre(); VECTOR2I center = footprint->GetBoundingBox( false, false ).Centre();
VECTOR2I grid( GetGrid() ); VECTOR2I grid( GetGrid() );
if( ( center - position ).SquaredEuclideanNorm() > grid.SquaredEuclideanNorm() ) if( ( center - position ).SquaredEuclideanNorm() > grid.SquaredEuclideanNorm() )
addAnchor( footprint->GetFootprintRect().Centre(), ORIGIN | SNAPPABLE, footprint ); addAnchor( center, ORIGIN | SNAPPABLE, footprint );
break; break;
} }

View File

@ -2282,7 +2282,7 @@ int PCB_SELECTION_TOOL::hitTestDistance( const wxPoint& aWhere, BOARD_ITEM* aIte
case PCB_FOOTPRINT_T: case PCB_FOOTPRINT_T:
{ {
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aItem ); FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aItem );
EDA_RECT bbox = footprint->GetFootprintRect(); EDA_RECT bbox = footprint->GetBoundingBox( false, false );
footprint->GetBoundingHull().Collide( loc, aMaxDistance, &distance ); footprint->GetBoundingHull().Collide( loc, aMaxDistance, &distance );

View File

@ -95,7 +95,8 @@ ALIGNMENT_RECTS GetBoundingBoxes( const T& aItems )
if( item->Type() == PCB_FOOTPRINT_T ) if( item->Type() == PCB_FOOTPRINT_T )
{ {
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item ); FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
rects.emplace_back( std::make_pair( boardItem, footprint->GetFootprintRect() ) ); rects.emplace_back( std::make_pair( boardItem,
footprint->GetBoundingBox( false, false ) ) );
} }
else else
{ {