Gerbview,export to pcbnew: avoid exporting not valid polygons.

Gerber regions are exported as polygons (they are filled polygon).
The fix ensure the polygons are simple and valid.
This commit is contained in:
jean-pierre charras 2019-12-15 11:50:19 +01:00
parent 1abb198fb4
commit 25504319df
1 changed files with 82 additions and 5 deletions

View File

@ -78,12 +78,20 @@ private:
void export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer ); void export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
/** /**
* write a non copper polygon item to the board file. * write anot filled polygon item to the board file.
* @param aGbrItem = the Gerber item (line, arc) to export * @param aGbrItem = the Gerber item (line, arc) to export
* @param aLayer = the technical layer to use * @param aLayer = the technical layer to use
*/ */
void writePcbPolygonItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer ); void writePcbPolygonItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
/**
* write a zone item to the board file.
* Currently: only experimental, for tests
* @param aGbrItem = the Gerber item (line, arc) to export
* @param aLayer = the technical layer to use
*/
void writePcbZoneItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
/** /**
* write a track or via) to the board file. * write a track or via) to the board file.
* @param aGbrItem = the Gerber item (line, arc, flashed) to export * @param aGbrItem = the Gerber item (line, arc, flashed) to export
@ -339,9 +347,16 @@ void GBR_TO_PCB_EXPORTER::export_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_
break; break;
case GBR_POLYGON: case GBR_POLYGON:
// Currently: Pcbnew does not really handle polygons on copper layers (no DRC test). // One can use a polygon or a zone to output a Gerber region.
// However, we can export them if the purpose of this export is to help recreate a board // none are perfect.
// The current way is use a polygon, as the zone export
// is exprimental and only for tests.
#if 1
writePcbPolygonItem( aGbrItem, aLayer ); writePcbPolygonItem( aGbrItem, aLayer );
#else
// Only for tests:
writePcbZoneItem( aGbrItem, aLayer );
#endif
break; break;
default: default:
@ -536,11 +551,21 @@ void GBR_TO_PCB_EXPORTER::writePcbLineItem( bool aIsArc, wxPoint& aStart, wxPoin
void GBR_TO_PCB_EXPORTER::writePcbPolygonItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer ) void GBR_TO_PCB_EXPORTER::writePcbPolygonItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
{ {
fprintf( m_fp, "(gr_poly (pts " );
SHAPE_POLY_SET polys = aGbrItem->m_Polygon; SHAPE_POLY_SET polys = aGbrItem->m_Polygon;
// Cleanup the polygon
polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
// Ensure the polygon is valid:
if( polys.OutlineCount() == 0 )
return;
polys.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
SHAPE_LINE_CHAIN& poly = polys.Outline( 0 ); SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
fprintf( m_fp, "(gr_poly (pts " );
#define MAX_COORD_CNT 4 #define MAX_COORD_CNT 4
int jj = MAX_COORD_CNT; int jj = MAX_COORD_CNT;
int cnt_max = poly.PointCount() -1; int cnt_max = poly.PointCount() -1;
@ -569,3 +594,55 @@ void GBR_TO_PCB_EXPORTER::writePcbPolygonItem( GERBER_DRAW_ITEM* aGbrItem, LAYER
fprintf( m_fp, "(layer %s) (width 0) )\n", fprintf( m_fp, "(layer %s) (width 0) )\n",
TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) ); TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
} }
void GBR_TO_PCB_EXPORTER::writePcbZoneItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
{
SHAPE_POLY_SET polys = aGbrItem->m_Polygon;
polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
if( polys.OutlineCount() == 0 )
return;
fprintf( m_fp, "(zone (net 0) (net_name \"\") (layer %s) (tstamp 0000000) (hatch edge 0.508)\n",
TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
fprintf( m_fp, " (connect_pads (clearance 0.0))\n" );
fprintf( m_fp, " (min_thickness 0.1) (filled_areas_thickness no)\n"
" (fill (thermal_gap 0.3) (thermal_bridge_width 0.3))\n" );
// Now, write the zone outlines with holes.
// first polygon is the main outline, next are holes
// One cannot know the initial zone outline.
// However most of (if not all) holes are just items with clearance,
// not really a hole in the initial zone outline.
// So we build a zone outline only with no hole.
fprintf( m_fp, " (polygon\n (pts" );
SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
#define MAX_COORD_CNT 4
int jj = MAX_COORD_CNT;
int cnt_max = poly.PointCount() -1;
// Do not generate last corner, if it is the same point as the first point:
if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) )
cnt_max--;
for( int ii = 0; ii <= cnt_max; ii++ )
{
if( --jj == 0 )
{
jj = MAX_COORD_CNT;
fprintf( m_fp, "\n " );
}
fprintf( m_fp, " (xy %s %s)", Double2Str( MapToPcbUnits( poly.CPoint( ii ).x ) ).c_str(),
Double2Str( MapToPcbUnits( -poly.CPoint( ii ).y ) ).c_str() );
}
fprintf( m_fp, ")\n" );
fprintf( m_fp, " )\n)\n" );
}