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();
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 );
}
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 );
}
wxSafeYield(); // displays report message.
}
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 );
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() )
{
@ -586,7 +589,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
// having compatible settings for drawings:
// use or not outline thickness, and if using outline 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() )
// Should not happens, because usually the same option is used for filling
continue;
@ -596,10 +599,16 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
continue;
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 );
}
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:
static std::vector< wxPoint > cornerList;
cornerList.clear();
std::vector< wxPoint > cornerList;
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;
for( auto ic = polysList.CIterate(); ic; ++ic )
for( int idx = 0; idx < polysList.OutlineCount(); ++idx )
{
wxPoint pos( ic->x, ic->y );
cornerList.push_back( pos );
SHAPE_LINE_CHAIN& outline = polysList.Outline( idx );
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
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 );
}
cornerList.clear();
}
}
}