Fix issue with caches not being initialized when printing msg bar.

(cherry picked from commit 43df863df2)
This commit is contained in:
Jeff Young 2022-07-31 22:14:24 +01:00
parent 4ac48ad829
commit 36a0c2a9cc
15 changed files with 352 additions and 305 deletions

View File

@ -339,9 +339,9 @@ void AR_AUTOPLACER::buildFpAreas( FOOTPRINT* aFootprint, int aFpClearance )
m_fpAreaTop.RemoveAllContours();
m_fpAreaBottom.RemoveAllContours();
aFootprint->BuildPolyCourtyards();
m_fpAreaTop = aFootprint->GetPolyCourtyard( F_CrtYd );
m_fpAreaBottom = aFootprint->GetPolyCourtyard( B_CrtYd );
aFootprint->BuildCourtyardCaches();
m_fpAreaTop = aFootprint->GetCourtyard( F_CrtYd );
m_fpAreaBottom = aFootprint->GetCourtyard( B_CrtYd );
LSET layerMask;

View File

@ -119,7 +119,7 @@ void DIALOG_FOOTPRINT_CHECKER::runChecks()
m_frame->GetCanvas()->GetView()->Add( marker );
};
footprint->BuildPolyCourtyards( &errorHandler );
footprint->BuildCourtyardCaches( &errorHandler );
const std::function<void( const wxString& msg )> typeWarning =

View File

View File

@ -717,7 +717,7 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aT
copperZones.push_back( zone );
}
footprint->BuildPolyCourtyards();
footprint->BuildCourtyardCaches();
}
int zoneCount = copperZones.size();
@ -990,10 +990,10 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
{
const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( a );
if( !footprint->GetPolyCourtyard( F_CrtYd ).IsEmpty() )
if( !footprint->GetCourtyard( F_CrtYd ).IsEmpty() )
itemLayers |= LSET::FrontMask();
if( !footprint->GetPolyCourtyard( B_CrtYd ).IsEmpty() )
if( !footprint->GetCourtyard( B_CrtYd ).IsEmpty() )
itemLayers |= LSET::BackMask();
}

View File

@ -122,10 +122,10 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
};
// Re-run courtyard tests to generate DRC_ITEMs
footprint->BuildPolyCourtyards( &errorHandler );
footprint->BuildCourtyardCaches( &errorHandler );
}
else if( footprint->GetPolyCourtyard( F_CrtYd ).OutlineCount() == 0
&& footprint->GetPolyCourtyard( B_CrtYd ).OutlineCount() == 0 )
else if( footprint->GetCourtyard( F_CrtYd ).OutlineCount() == 0
&& footprint->GetCourtyard( B_CrtYd ).OutlineCount() == 0 )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_COURTYARD ) )
continue;
@ -136,8 +136,8 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
}
else
{
footprint->GetPolyCourtyard( F_CrtYd ).BuildBBoxCaches();
footprint->GetPolyCourtyard( B_CrtYd ).BuildBBoxCaches();
footprint->GetCourtyard( F_CrtYd ).BuildBBoxCaches();
footprint->GetCourtyard( B_CrtYd ).BuildBBoxCaches();
}
}
@ -167,8 +167,8 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
}
FOOTPRINT* fpA = *itA;
const SHAPE_POLY_SET& frontA = fpA->GetPolyCourtyard( F_CrtYd );
const SHAPE_POLY_SET& backA = fpA->GetPolyCourtyard( B_CrtYd );
const SHAPE_POLY_SET& frontA = fpA->GetCourtyard( F_CrtYd );
const SHAPE_POLY_SET& backA = fpA->GetCourtyard( B_CrtYd );
if( frontA.OutlineCount() == 0 && backA.OutlineCount() == 0
&& m_drcEngine->IsErrorLimitExceeded( DRCE_PTH_IN_COURTYARD )
@ -190,8 +190,8 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
{
FOOTPRINT* fpB = *itB;
EDA_RECT fpBBBox = fpB->GetBoundingBox();
const SHAPE_POLY_SET& frontB = fpB->GetPolyCourtyard( F_CrtYd );
const SHAPE_POLY_SET& backB = fpB->GetPolyCourtyard( B_CrtYd );
const SHAPE_POLY_SET& frontB = fpB->GetCourtyard( F_CrtYd );
const SHAPE_POLY_SET& backB = fpB->GetCourtyard( B_CrtYd );
DRC_CONSTRAINT constraint;
int clearance;
int actual;
@ -269,8 +269,8 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
return;
const SHAPE_SEGMENT* hole = pad->GetEffectiveHoleShape();
const SHAPE_POLY_SET& front = footprint->GetPolyCourtyard( F_CrtYd );
const SHAPE_POLY_SET& back = footprint->GetPolyCourtyard( B_CrtYd );
const SHAPE_POLY_SET& front = footprint->GetCourtyard( F_CrtYd );
const SHAPE_POLY_SET& back = footprint->GetCourtyard( B_CrtYd );
if( ( front.OutlineCount() > 0 && front.Collide( hole, 0 ) )
|| ( back.OutlineCount() > 0 && back.Collide( hole, 0 ) ) )

View File

@ -177,7 +177,7 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER
bool useFpPadsBbox = true;
bool onBack = aLayer == B_Cu;
footprint->BuildPolyCourtyards();
footprint->BuildCourtyardCaches();
int checkFlag = onBack ? MALFORMED_B_COURTYARD : MALFORMED_F_COURTYARD;
@ -186,7 +186,7 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER
gbr_metadata.SetApertureAttrib(
GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CMP_COURTYARD );
const SHAPE_POLY_SET& courtyard = footprint->GetPolyCourtyard( aLayer );
const SHAPE_POLY_SET& courtyard = footprint->GetCourtyard( aLayer );
for( int ii = 0; ii < courtyard.OutlineCount(); ii++ )
{

View File

@ -54,7 +54,8 @@ FOOTPRINT::FOOTPRINT( BOARD* parent ) :
m_visibleBBoxCacheTimeStamp( 0 ),
m_textExcludedBBoxCacheTimeStamp( 0 ),
m_hullCacheTimeStamp( 0 ),
m_initial_comments( nullptr )
m_initial_comments( nullptr ),
m_courtyard_cache_timestamp( 0 )
{
m_attributes = 0;
m_layer = F_Cu;
@ -1555,7 +1556,7 @@ void FOOTPRINT::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
m_cachedHull.Mirror( aFlipLeftRight, !aFlipLeftRight, m_pos );
std::swap( m_poly_courtyard_front, m_poly_courtyard_back );
std::swap( m_courtyard_cache_front, m_courtyard_cache_back );
}
@ -2037,12 +2038,26 @@ std::shared_ptr<SHAPE> FOOTPRINT::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHI
}
void FOOTPRINT::BuildPolyCourtyards( OUTLINE_ERROR_HANDLER* aErrorHandler )
const SHAPE_POLY_SET& FOOTPRINT::GetCourtyard( PCB_LAYER_ID aLayer ) const
{
m_poly_courtyard_front.RemoveAllContours();
m_poly_courtyard_back.RemoveAllContours();
if( GetBoard() && GetBoard()->GetTimeStamp() > m_courtyard_cache_timestamp )
const_cast<FOOTPRINT*>( this )->BuildCourtyardCaches();
if( IsBackLayer( aLayer ) )
return m_courtyard_cache_back;
else
return m_courtyard_cache_front;
}
void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
{
m_courtyard_cache_front.RemoveAllContours();
m_courtyard_cache_back.RemoveAllContours();
ClearFlags( MALFORMED_COURTYARDS );
m_courtyard_cache_timestamp = GetBoard()->GetTimeStamp();
// Build the courtyard area from graphic items on the courtyard.
// Only PCB_FP_SHAPE_T have meaning, graphic texts are ignored.
// Collect items:
@ -2064,26 +2079,26 @@ void FOOTPRINT::BuildPolyCourtyards( OUTLINE_ERROR_HANDLER* aErrorHandler )
int errorMax = Millimeter2iu( 0.02 ); // max error for polygonization
int chainingEpsilon = Millimeter2iu( 0.02 ); // max dist from one endPt to next startPt
if( ConvertOutlineToPolygon( list_front, m_poly_courtyard_front, errorMax, chainingEpsilon,
if( ConvertOutlineToPolygon( list_front, m_courtyard_cache_front, errorMax, chainingEpsilon,
aErrorHandler ) )
{
// Touching courtyards, or courtyards -at- the clearance distance are legal.
m_poly_courtyard_front.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
m_courtyard_cache_front.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
m_poly_courtyard_front.CacheTriangulation( false );
m_courtyard_cache_front.CacheTriangulation( false );
}
else
{
SetFlags( MALFORMED_F_COURTYARD );
}
if( ConvertOutlineToPolygon( list_back, m_poly_courtyard_back, errorMax, chainingEpsilon,
if( ConvertOutlineToPolygon( list_back, m_courtyard_cache_back, errorMax, chainingEpsilon,
aErrorHandler ) )
{
// Touching courtyards, or courtyards -at- the clearance distance are legal.
m_poly_courtyard_back.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
m_courtyard_cache_back.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
m_poly_courtyard_back.CacheTriangulation( false );
m_courtyard_cache_back.CacheTriangulation( false );
}
else
{

View File

@ -695,13 +695,7 @@ public:
*
* @return the courtyard polygon.
*/
const SHAPE_POLY_SET& GetPolyCourtyard( PCB_LAYER_ID aLayer ) const
{
if( IsBackLayer( aLayer ) )
return m_poly_courtyard_back;
else
return m_poly_courtyard_front;
}
const SHAPE_POLY_SET& GetCourtyard( PCB_LAYER_ID aLayer ) const;
/**
* Build complex polygons of the courtyard areas from graphic items on the courtyard layers.
@ -709,7 +703,7 @@ public:
* @note Set the #MALFORMED_F_COURTYARD and #MALFORMED_B_COURTYARD status flags if the given
* courtyard layer does not contain a (single) closed shape.
*/
void BuildPolyCourtyards( OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
void BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
@ -786,8 +780,9 @@ private:
wxArrayString* m_initial_comments; // s-expression comments in the footprint,
// lazily allocated only if needed for speed
SHAPE_POLY_SET m_poly_courtyard_front; // Note that a footprint can have both front and back
SHAPE_POLY_SET m_poly_courtyard_back; // courtyards populated.
SHAPE_POLY_SET m_courtyard_cache_front; // Note that a footprint can have both front and back
SHAPE_POLY_SET m_courtyard_cache_back; // courtyards populated.
mutable int m_courtyard_cache_timestamp;
};
#endif // FOOTPRINT_H

View File

@ -195,7 +195,7 @@ bool calcIsInsideCourtyard( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox,
{
SHAPE_POLY_SET footprintCourtyard;
footprintCourtyard = aFootprint->GetPolyCourtyard( aSide );
footprintCourtyard = aFootprint->GetCourtyard( aSide );
if( !aFootprint->GetBoundingBox().Intersects( aItemBBox ) )
return false;
@ -495,7 +495,7 @@ bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CO
if( ( aArea->GetLayerSet() & LSET::FrontMask() ).any() )
{
SHAPE_POLY_SET courtyard = footprint->GetPolyCourtyard( F_CrtYd );
const SHAPE_POLY_SET& courtyard = footprint->GetCourtyard( F_CrtYd );
if( courtyard.OutlineCount() == 0 )
{
@ -512,7 +512,7 @@ bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CO
if( ( aArea->GetLayerSet() & LSET::BackMask() ).any() )
{
SHAPE_POLY_SET courtyard = footprint->GetPolyCourtyard( B_CrtYd );
const SHAPE_POLY_SET& courtyard = footprint->GetCourtyard( B_CrtYd );
if( courtyard.OutlineCount() == 0 )
{

View File

@ -132,6 +132,24 @@ int PCB_TRACK::GetLocalClearance( wxString* aSource ) const
}
MINOPTMAX<int> PCB_TRACK::GetWidthConstraint( wxString* aSource ) const
{
DRC_CONSTRAINT constraint;
if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
{
BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings();
constraint = bds.m_DRCEngine->EvalRules( TRACK_WIDTH_CONSTRAINT, this, nullptr, m_layer );
}
if( aSource )
*aSource = constraint.GetName();
return constraint.Value();
}
int PCB_VIA::GetMinAnnulus( PCB_LAYER_ID aLayer, wxString* aSource ) const
{
if( !FlashLayer( aLayer ) )
@ -715,6 +733,22 @@ void PCB_TRACK::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
MessageTextFromValue( units, clearance ) ),
wxString::Format( _( "(from %s)" ), source ) );
MINOPTMAX<int> c = GetWidthConstraint( &source );
if( c.HasMax() )
{
aList.emplace_back( wxString::Format( _( "Width Constraints: min %s, max %s" ),
MessageTextFromValue( units, c.Min() ),
MessageTextFromValue( units, c.Max() ) ),
wxString::Format( _( "(from %s)" ), source ) );
}
else
{
aList.emplace_back( wxString::Format( _( "Width Constraints: min %s" ),
MessageTextFromValue( units, c.Min() ) ),
wxString::Format( _( "(from %s)" ), source ) );
}
}

View File

@ -38,7 +38,8 @@
#include <board_connected_item.h>
#include <convert_to_biu.h>
#include <geometry/shape_segment.h>
#include "core/minoptmax.h"
class PCB_TRACK;
class PCB_VIA;
@ -192,6 +193,8 @@ public:
*/
int GetLocalClearance( wxString* aSource ) const override;
MINOPTMAX<int> GetWidthConstraint( wxString* aSource ) const;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
BITMAPS GetMenuImage() const override;

View File

@ -159,7 +159,7 @@ void BOARD_INSPECTION_TOOL::reportClearance( DRC_CONSTRAINT_T aClearanceType, PC
for( ZONE* zone : footprint->Zones() )
zone->CacheBoundingBox();
footprint->BuildPolyCourtyards();
footprint->BuildCourtyardCaches();
}
DRC_CONSTRAINT constraint = drcEngine.EvalRules( aClearanceType, aA, aB, aLayer, r );
@ -351,7 +351,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
for( ZONE* z : f->Zones() )
z->CacheBoundingBox();
f->BuildPolyCourtyards();
f->BuildCourtyardCaches();
}
auto hasHole =
@ -518,8 +518,8 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
for( PCB_LAYER_ID layer : { F_CrtYd, B_CrtYd } )
{
bool aCourtyard = aFP && !aFP->GetPolyCourtyard( layer ).IsEmpty();
bool bCourtyard = bFP && !bFP->GetPolyCourtyard( layer ).IsEmpty();
bool aCourtyard = aFP && !aFP->GetCourtyard( layer ).IsEmpty();
bool bCourtyard = bFP && !bFP->GetCourtyard( layer ).IsEmpty();
if( aCourtyard && bCourtyard )
{
@ -714,7 +714,7 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
for( ZONE* zone : footprint->Zones() )
zone->CacheBoundingBox();
footprint->BuildPolyCourtyards();
footprint->BuildCourtyardCaches();
if( ( footprint->GetFlags() & MALFORMED_COURTYARDS ) != 0 )
courtyardError = true;

View File

View File

@ -133,7 +133,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
}
// Rules may depend on insideCourtyard() or other expressions
footprint->BuildPolyCourtyards();
footprint->BuildCourtyardCaches();
}
// Sort by priority to reduce deferrals waiting on higher priority zones.