diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index ae0b4b6c57..95edee56d0 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -842,8 +842,18 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion ) wxPoint start( aArc.GetP0() ); wxPoint end( aArc.GetP1() ); wxPoint center( aArc.GetCenter() ); - double start_angle = aArc.GetStartAngle(); - double end_angle = aArc.GetEndAngle(); + double startAngle = aArc.GetStartAngle(); + double endAngle = aArc.GetEndAngle(); + + if( startAngle > endAngle ) + { + if( endAngle < 0.0 ) + endAngle = NormalizeAnglePos( endAngle ) ; + else + { + startAngle = NormalizeAnglePos( startAngle ) - 3600.0; + } + } if( !aPlotInRegion ) MoveTo( start); @@ -855,7 +865,7 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion ) fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode - if( start_angle < end_angle ) + if( startAngle > endAngle ) fprintf( m_outputFile, "G03*\n" ); // Active circular interpolation, CCW else fprintf( m_outputFile, "G02*\n" ); // Active circular interpolation, CW @@ -1010,6 +1020,10 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int const SHAPE_ARC& arc = aPoly.Arc( arcindex ); plotArc( arc, ii > 0 ); + + // skip points on arcs, since we plot the arc itself + while( ii+1 < aPoly.PointCount() && arcindex == aPoly.ArcIndex( ii+1 ) ) + ii++; } } @@ -1040,12 +1054,17 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int const SHAPE_ARC& arc = aPoly.Arc( arcindex ); plotArc( arc, ii > 0 ); + + // skip points on arcs, since we plot the arc itself + while( ii+1 < aPoly.PointCount() && arcindex == aPoly.ArcIndex( ii+1 ) ) + ii++; } } // Ensure the thick outline is closed for filled polygons // (if not filled, could be only a polyline) - if( aFill != FILL_T::NO_FILL && ( aPoly.CPoint( 0 ) != aPoly.CPoint( -1 ) ) ) + if( ( aPoly.CPoint( 0 ) != aPoly.CPoint( -1 ) ) + && ( aPoly.IsClosed() || aFill != FILL_T::NO_FILL ) ) LineTo( wxPoint( aPoly.CPoint( 0 ) ) ); PenFinish(); diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 022784f840..172bdcb711 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -651,7 +651,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( const FP_SHAPE* aShape ) } } - if( sketch || thickness > 0 ) + if( sketch ) { for( size_t i = 1; i < cornerList.size(); i++ ) { @@ -663,8 +663,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( const FP_SHAPE* aShape ) GetPlotMode(), &gbr_metadata ); } - - if( !sketch && aShape->IsFilled() ) + else { // This must be simplified and fractured to prevent overlapping polygons // from generating invalid Gerber files @@ -675,11 +674,12 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( const FP_SHAPE* aShape ) line.SetClosed( true ); tmpPoly.AddOutline( line ); tmpPoly.Fracture( SHAPE_POLY_SET::PM_FAST ); + FILL_T fill = aShape->IsFilled() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL; for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj ) { SHAPE_LINE_CHAIN &poly = tmpPoly.Outline( jj ); - m_plotter->PlotPoly( poly, FILL_T::FILLED_SHAPE, thickness, &gbr_metadata ); + m_plotter->PlotPoly( poly, fill, thickness, &gbr_metadata ); } } } @@ -936,7 +936,7 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape ) case SHAPE_T::POLY: if( aShape->IsPolyShapeValid() ) { - if( sketch || thickness > 0 ) + if( sketch ) { for( auto it = aShape->GetPolyShape().CIterateSegments( 0 ); it; it++ ) { @@ -945,8 +945,7 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape ) thickness, GetPlotMode(), &gbr_metadata ); } } - - if( !sketch && aShape->IsFilled() ) + else { m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata ); @@ -955,13 +954,18 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape ) // ( for the future or to show a non expected shape ) // This must be simplified and fractured to prevent overlapping polygons // from generating invalid Gerber files - auto tmpPoly = SHAPE_POLY_SET( aShape->GetPolyShape() ); + SHAPE_POLY_SET tmpPoly = SHAPE_POLY_SET( aShape->GetPolyShape() ); tmpPoly.Fracture( SHAPE_POLY_SET::PM_FAST ); + FILL_T fill = aShape->IsFilled() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL; for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj ) { SHAPE_LINE_CHAIN& poly = tmpPoly.Outline( jj ); - m_plotter->PlotPoly( poly, FILL_T::FILLED_SHAPE, thickness, &gbr_metadata ); + + // Ensure the polygon is closed: + poly.SetClosed( true ); + + m_plotter->PlotPoly( poly, fill, thickness, &gbr_metadata ); } } }