Pcbnew: seriously speedup calculation time when plotting large filled areas.

This commit is contained in:
jean-pierre charras 2019-08-27 13:32:00 +02:00
parent 37b166348a
commit 9dac8534c1
3 changed files with 29 additions and 13 deletions

View File

@ -851,14 +851,16 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
plotter->EndPlot(); plotter->EndPlot();
delete plotter; delete plotter;
msg.Printf( _( "Plot file \"%s\" created." ), GetChars( fn.GetFullPath() ) ); msg.Printf( _( "Plot file \"%s\" created." ), fn.GetFullPath() );
reporter.Report( msg, REPORTER::RPT_ACTION ); reporter.Report( msg, REPORTER::RPT_ACTION );
} }
else else
{ {
msg.Printf( _( "Unable to create file \"%s\"." ), GetChars( fn.GetFullPath() ) ); msg.Printf( _( "Unable to create file \"%s\"." ), fn.GetFullPath() );
reporter.Report( msg, REPORTER::RPT_ERROR ); reporter.Report( msg, REPORTER::RPT_ERROR );
} }
wxSafeYield(); // displays report message.
} }
if( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER && m_plotOpts.GetCreateGerberJobFile() ) if( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER && m_plotOpts.GetCreateGerberJobFile() )

View File

@ -573,6 +573,9 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
plotted.insert( zone ); plotted.insert( zone );
SHAPE_POLY_SET aggregateArea = zone->GetFilledPolysList(); SHAPE_POLY_SET aggregateArea = zone->GetFilledPolysList();
bool needFracture = false; // If 2 or more filled areas are combined, resulting
// aggregateArea will be simplified and fractured
// (Long calculation time)
for( ZONE_CONTAINER* candidate : aBoard->Zones() ) for( ZONE_CONTAINER* candidate : aBoard->Zones() )
{ {
@ -586,7 +589,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
// having compatible settings for drawings: // having compatible settings for drawings:
// use or not outline thickness, and if using outline thickness, // use or not outline thickness, and if using outline thickness,
// having the same thickness // having the same thickness
// becuase after merging only one outline thickness is used // because after merging only one outline thickness is used
if( candidate->GetFilledPolysUseThickness() != zone->GetFilledPolysUseThickness() ) if( candidate->GetFilledPolysUseThickness() != zone->GetFilledPolysUseThickness() )
// Should not happens, because usually the same option is used for filling // Should not happens, because usually the same option is used for filling
continue; continue;
@ -596,10 +599,16 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
continue; continue;
plotted.insert( candidate ); plotted.insert( candidate );
aggregateArea.BooleanAdd( candidate->GetFilledPolysList(), SHAPE_POLY_SET::PM_FAST ); aggregateArea.Append( candidate->GetFilledPolysList() );
needFracture = true;
}
if( needFracture )
{
aggregateArea.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
aggregateArea.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
} }
aggregateArea.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
itemplotter.PlotFilledAreas( zone, aggregateArea ); itemplotter.PlotFilledAreas( zone, aggregateArea );
} }
aPlotter->EndBlock( NULL ); aPlotter->EndBlock( NULL );

View File

@ -653,8 +653,7 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone, SHAPE_POLY_SET& p
} }
// We need a buffer to store corners coordinates: // We need a buffer to store corners coordinates:
static std::vector< wxPoint > cornerList; std::vector< wxPoint > cornerList;
cornerList.clear();
m_plotter->SetColor( getColor( aZone->GetLayer() ) ); m_plotter->SetColor( getColor( aZone->GetLayer() ) );
@ -666,12 +665,20 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone, SHAPE_POLY_SET& p
*/ */
int outline_thickness = aZone->GetFilledPolysUseThickness() ? aZone->GetMinThickness() : 0; int outline_thickness = aZone->GetFilledPolysUseThickness() ? aZone->GetMinThickness() : 0;
for( auto ic = polysList.CIterate(); ic; ++ic ) for( int idx = 0; idx < polysList.OutlineCount(); ++idx )
{ {
wxPoint pos( ic->x, ic->y ); SHAPE_LINE_CHAIN& outline = polysList.Outline( idx );
cornerList.push_back( pos );
if( ic.IsEndContour() ) // Plot the current filled area outline cornerList.clear();
cornerList.reserve( outline.PointCount() );
for( int ic = 0; ic < outline.PointCount(); ++ic )
{
VECTOR2I& point = outline.Point( ic );
cornerList.emplace_back( wxPoint( point.x, point.y ) );
}
if( cornerList.size() ) // Plot the current filled area outline
{ {
// First, close the outline // First, close the outline
if( cornerList[0] != cornerList[cornerList.size() - 1] ) if( cornerList[0] != cornerList[cornerList.size() - 1] )
@ -696,8 +703,6 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone, SHAPE_POLY_SET& p
m_plotter->SetCurrentLineWidth( -1 ); m_plotter->SetCurrentLineWidth( -1 );
} }
cornerList.clear();
} }
} }
} }