Pcbnew, Zone refill: avoid useless refilling, when zone parameters are not modified.

Previously, in many cases the selected zone was refilled on exit selection, even if the zone was not modified.
This is annoying, because the zone fill can be really time consuming, and cannot be called without a good reason.
Now the refilling is made only if a zone parameter is actually modified.
This commit is contained in:
jean-pierre charras 2019-03-14 14:35:55 +01:00
parent 2bd2cf6a6b
commit 353d9d7c9e
6 changed files with 64 additions and 12 deletions

View File

@ -68,6 +68,8 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) :
SetLocalFlags( 0 ); // flags tempoarry used in zone calculations
m_Poly = new SHAPE_POLY_SET(); // Outlines
aBoard->GetZoneSettings().ExportSetting( *this );
m_needRefill = false; // True only after some edition.
}
@ -107,6 +109,8 @@ ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) :
SetLayerSet( aZone.GetLayerSet() );
SetLocalFlags( aZone.GetLocalFlags() );
SetNeedRefill( aZone.NeedRefill() );
}
@ -220,6 +224,9 @@ void ZONE_CONTAINER::SetLayerSet( LSET aLayerSet )
return;
}
if( m_layerSet != aLayerSet )
SetNeedRefill( true );
m_layerSet = aLayerSet;
// Set the single layer to the first selected layer
@ -641,6 +648,9 @@ int ZONE_CONTAINER::GetThermalReliefCopperBridge( D_PAD* aPad ) const
void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
{
if( m_cornerRadius != aRadius )
SetNeedRefill( true );
m_cornerRadius = aRadius;
}
@ -910,6 +920,8 @@ void ZONE_CONTAINER::MoveEdge( const wxPoint& offset, int aEdge )
m_Poly->Vertex( aEdge ) += VECTOR2I( offset );
m_Poly->Vertex( next_corner ) += VECTOR2I( offset );
Hatch();
SetNeedRefill( true );
}
}
@ -1013,6 +1025,8 @@ void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
m_Poly->AddOutline( outline );
else
m_Poly->AddHole( outline );
SetNeedRefill( true );
}
@ -1030,6 +1044,8 @@ bool ZONE_CONTAINER::AppendCorner( wxPoint aPosition, int aHoleIdx, bool aAllowD
m_Poly->Append( aPosition.x, aPosition.y, -1, aHoleIdx, aAllowDuplication );
SetNeedRefill( true );
return true;
}

View File

@ -175,6 +175,9 @@ public:
void SetThermalReliefCopperBridge( int aThermalReliefCopperBridge )
{
if( m_ThermalReliefCopperBridge != aThermalReliefCopperBridge )
SetNeedRefill( true );
m_ThermalReliefCopperBridge = aThermalReliefCopperBridge;
}
int GetThermalReliefCopperBridge( D_PAD* aPad = NULL ) const;
@ -185,6 +188,9 @@ public:
bool IsFilled() const { return m_IsFilled; }
void SetIsFilled( bool isFilled ) { m_IsFilled = isFilled; }
bool NeedRefill() const { return m_needRefill; }
void SetNeedRefill( bool aNeedRefill ) { m_needRefill = aNeedRefill; }
int GetZoneClearance() const { return m_ZoneClearance; }
void SetZoneClearance( int aZoneClearance ) { m_ZoneClearance = aZoneClearance; }
@ -192,7 +198,13 @@ public:
void SetPadConnection( ZoneConnection aPadConnection ) { m_PadConnection = aPadConnection; }
int GetMinThickness() const { return m_ZoneMinThickness; }
void SetMinThickness( int aMinThickness ) { m_ZoneMinThickness = aMinThickness; }
void SetMinThickness( int aMinThickness )
{
if( m_ZoneMinThickness != aMinThickness )
SetNeedRefill( true );
m_ZoneMinThickness = aMinThickness;
}
int GetSelectedCorner() const
{
@ -488,6 +500,10 @@ public:
// Convert global to relative indices
if( m_Poly->GetRelativeIndices( aCornerIndex, &relativeIndices ) )
{
if( m_Poly->Vertex( relativeIndices ).x != new_pos.x ||
m_Poly->Vertex( relativeIndices ).y != new_pos.y )
SetNeedRefill( true );
m_Poly->Vertex( relativeIndices ).x = new_pos.x;
m_Poly->Vertex( relativeIndices ).y = new_pos.y;
}
@ -723,6 +739,12 @@ private:
/** True when a zone was filled, false after deleting the filled areas. */
bool m_IsFilled;
/** False when a zone was refilled, true after changes in zone params.
* m_needRefill = false does not imply filled areas are up to date, just
* the zone was refilled after edition, and does not need refilling
*/
bool m_needRefill;
///< Width of the gap in thermal reliefs.
int m_ThermalReliefGap;

View File

@ -3347,6 +3347,9 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER()
}
}
// Clear flags used in zone edition:
zone->SetNeedRefill( false );
return zone.release();
}

View File

@ -561,7 +561,12 @@ void POINT_EDITOR::updateItem() const
SHAPE_POLY_SET& outline = *zone->Outline();
for( int i = 0; i < outline.TotalVertices(); ++i )
{
if( outline.Vertex( i ) != m_editPoints->Point( i ).GetPosition() )
zone->SetNeedRefill( true );
outline.Vertex( i ) = m_editPoints->Point( i ).GetPosition();
}
validatePolygon( outline );
zone->Hatch();
@ -636,7 +641,7 @@ void POINT_EDITOR::finishItem()
{
auto zone = static_cast<ZONE_CONTAINER*>( item );
if( zone->IsFilled() && m_refill )
if( zone->IsFilled() && m_refill && zone->NeedRefill() )
{
ZONE_FILLER filler( board() );
WX_PROGRESS_REPORTER reporter( getEditFrame<PCB_BASE_FRAME>(), _( "Refill Zones" ), 4 );
@ -740,7 +745,7 @@ void POINT_EDITOR::updatePoints()
case PCB_ZONE_AREA_T:
{
const ZONE_CONTAINER* zone = static_cast<const ZONE_CONTAINER*>( item );
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
const SHAPE_POLY_SET* outline = zone->Outline();
if( m_editPoints->PointsSize() != (unsigned) outline->TotalVertices() )
@ -989,7 +994,11 @@ int POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
SHAPE_POLY_SET* zoneOutline;
if( item->Type() == PCB_ZONE_AREA_T )
zoneOutline = static_cast<ZONE_CONTAINER*>( item )->Outline();
{
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
zoneOutline = zone->Outline();
zone->SetNeedRefill( true );
}
else
zoneOutline = &( graphicItem->GetPolyShape() );
@ -1100,6 +1109,7 @@ int POINT_EDITOR::removeCorner( const TOOL_EVENT& aEvent )
{
auto zone = static_cast<ZONE_CONTAINER*>( item );
polygon = zone->Outline();
zone->SetNeedRefill( true );
}
else if( (item->Type() == PCB_MODULE_EDGE_T ) || ( item->Type() == PCB_LINE_T ) )
{

View File

@ -805,7 +805,7 @@ void ZONE_FILLER::computeRawFilledAreas( const ZONE_CONTAINER* aZone,
* The solid areas can be more than one on copper layers, and do not have holes
* ( holes are linked by overlapping segments to the main outline)
*/
bool ZONE_FILLER::fillSingleZone( const ZONE_CONTAINER* aZone, SHAPE_POLY_SET& aRawPolys,
bool ZONE_FILLER::fillSingleZone( ZONE_CONTAINER* aZone, SHAPE_POLY_SET& aRawPolys,
SHAPE_POLY_SET& aFinalPolys ) const
{
SHAPE_POLY_SET smoothedPoly;
@ -829,10 +829,11 @@ bool ZONE_FILLER::fillSingleZone( const ZONE_CONTAINER* aZone, SHAPE_POLY_SET& a
aFinalPolys.Fracture( SHAPE_POLY_SET::PM_FAST );
}
aZone->SetNeedRefill( false );
return true;
}
bool ZONE_FILLER::fillZoneWithSegments( const ZONE_CONTAINER* aZone,
bool ZONE_FILLER::fillZoneWithSegments( ZONE_CONTAINER* aZone,
const SHAPE_POLY_SET& aFilledPolys,
ZONE_SEGMENT_FILL& aFillSegs ) const
{
@ -891,6 +892,7 @@ bool ZONE_FILLER::fillZoneWithSegments( const ZONE_CONTAINER* aZone,
}
}
aZone->SetNeedRefill( false );
return success;
}

View File

@ -77,7 +77,7 @@ private:
* a list of SEGZONE items is built, line per line
* @return true if success, false on error
*/
bool fillZoneWithSegments( const ZONE_CONTAINER* aZone,
bool fillZoneWithSegments( ZONE_CONTAINER* aZone,
const SHAPE_POLY_SET& aFilledPolys,
ZONE_SEGMENT_FILL& aFillSegs ) const;
@ -111,9 +111,8 @@ private:
* by aZone->GetMinThickness() / 2 to be drawn with a outline thickness = aZone->GetMinThickness()
* aFinalPolys are polygons that will be drawn on screen and plotted
*/
bool fillSingleZone( const ZONE_CONTAINER* aZone,
SHAPE_POLY_SET& aRawPolys,
SHAPE_POLY_SET& aFinalPolys ) const;
bool fillSingleZone( ZONE_CONTAINER* aZone,
SHAPE_POLY_SET& aRawPolys, SHAPE_POLY_SET& aFinalPolys ) const;
BOARD* m_board;
COMMIT* m_commit;