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 SetLocalFlags( 0 ); // flags tempoarry used in zone calculations
m_Poly = new SHAPE_POLY_SET(); // Outlines m_Poly = new SHAPE_POLY_SET(); // Outlines
aBoard->GetZoneSettings().ExportSetting( *this ); 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() ); SetLayerSet( aZone.GetLayerSet() );
SetLocalFlags( aZone.GetLocalFlags() ); SetLocalFlags( aZone.GetLocalFlags() );
SetNeedRefill( aZone.NeedRefill() );
} }
@ -220,6 +224,9 @@ void ZONE_CONTAINER::SetLayerSet( LSET aLayerSet )
return; return;
} }
if( m_layerSet != aLayerSet )
SetNeedRefill( true );
m_layerSet = aLayerSet; m_layerSet = aLayerSet;
// Set the single layer to the first selected layer // 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 ) void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
{ {
if( m_cornerRadius != aRadius )
SetNeedRefill( true );
m_cornerRadius = aRadius; 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( aEdge ) += VECTOR2I( offset );
m_Poly->Vertex( next_corner ) += VECTOR2I( offset ); m_Poly->Vertex( next_corner ) += VECTOR2I( offset );
Hatch(); Hatch();
SetNeedRefill( true );
} }
} }
@ -1013,6 +1025,8 @@ void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
m_Poly->AddOutline( outline ); m_Poly->AddOutline( outline );
else else
m_Poly->AddHole( outline ); 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 ); m_Poly->Append( aPosition.x, aPosition.y, -1, aHoleIdx, aAllowDuplication );
SetNeedRefill( true );
return true; return true;
} }

View File

@ -175,6 +175,9 @@ public:
void SetThermalReliefCopperBridge( int aThermalReliefCopperBridge ) void SetThermalReliefCopperBridge( int aThermalReliefCopperBridge )
{ {
if( m_ThermalReliefCopperBridge != aThermalReliefCopperBridge )
SetNeedRefill( true );
m_ThermalReliefCopperBridge = aThermalReliefCopperBridge; m_ThermalReliefCopperBridge = aThermalReliefCopperBridge;
} }
int GetThermalReliefCopperBridge( D_PAD* aPad = NULL ) const; int GetThermalReliefCopperBridge( D_PAD* aPad = NULL ) const;
@ -185,6 +188,9 @@ public:
bool IsFilled() const { return m_IsFilled; } bool IsFilled() const { return m_IsFilled; }
void SetIsFilled( bool isFilled ) { m_IsFilled = 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; } int GetZoneClearance() const { return m_ZoneClearance; }
void SetZoneClearance( int aZoneClearance ) { m_ZoneClearance = aZoneClearance; } void SetZoneClearance( int aZoneClearance ) { m_ZoneClearance = aZoneClearance; }
@ -192,7 +198,13 @@ public:
void SetPadConnection( ZoneConnection aPadConnection ) { m_PadConnection = aPadConnection; } void SetPadConnection( ZoneConnection aPadConnection ) { m_PadConnection = aPadConnection; }
int GetMinThickness() const { return m_ZoneMinThickness; } 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 int GetSelectedCorner() const
{ {
@ -488,6 +500,10 @@ public:
// Convert global to relative indices // Convert global to relative indices
if( m_Poly->GetRelativeIndices( aCornerIndex, &relativeIndices ) ) 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 ).x = new_pos.x;
m_Poly->Vertex( relativeIndices ).y = new_pos.y; 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. */ /** True when a zone was filled, false after deleting the filled areas. */
bool m_IsFilled; 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. ///< Width of the gap in thermal reliefs.
int m_ThermalReliefGap; 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(); return zone.release();
} }

View File

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

View File

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