Pcbnew, export Solder masks in Gerber Format: fix not working export when the solder mask minimal width is not 0 (the exported shapes were the same as if the vule = 0) with boost version >= 1.56
This is due to the fact the boost::pylygon function resize ( a inflate/deflate function) used for calculations does not work with boost version >= 1.56. Use Clipper inflate/deflate function instead. It is faster and works fine.
This commit is contained in:
parent
cf9a885c55
commit
479af2a7a8
|
@ -580,7 +580,10 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerBuffer
|
||||||
ClipperLib::Paths shapeWithClearance;
|
ClipperLib::Paths shapeWithClearance;
|
||||||
|
|
||||||
for( int ii = 0; ii < 4; ii++ )
|
for( int ii = 0; ii < 4; ii++ )
|
||||||
|
{
|
||||||
|
corners[ii] += PadShapePos;
|
||||||
outline << ClipperLib::IntPoint( corners[ii].x, corners[ii].y );
|
outline << ClipperLib::IntPoint( corners[ii].x, corners[ii].y );
|
||||||
|
}
|
||||||
|
|
||||||
ClipperLib::ClipperOffset offset_engine;
|
ClipperLib::ClipperOffset offset_engine;
|
||||||
// Prepare an offset (inflate) transform, with edges connected by arcs
|
// Prepare an offset (inflate) transform, with edges connected by arcs
|
||||||
|
@ -600,19 +603,7 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerBuffer
|
||||||
offset_engine.Execute( shapeWithClearance, rounding_radius );
|
offset_engine.Execute( shapeWithClearance, rounding_radius );
|
||||||
|
|
||||||
// get new outline (only one polygon is expected)
|
// get new outline (only one polygon is expected)
|
||||||
// For info, ClipperLib uses long long to handle integer coordinates
|
aCornerBuffer.ImportFrom( shapeWithClearance );
|
||||||
ClipperLib::Path& polygon = shapeWithClearance[0];
|
|
||||||
|
|
||||||
for( unsigned jj = 0; jj < polygon.size(); jj++ )
|
|
||||||
{
|
|
||||||
corner_position.x = int( polygon[jj].X );
|
|
||||||
corner_position.y = int( polygon[jj].Y );
|
|
||||||
corner_position += PadShapePos;
|
|
||||||
CPolyPt polypoint( corner_position.x, corner_position.y );
|
|
||||||
aCornerBuffer.Append( polypoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
aCornerBuffer.CloseLastContour();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -898,3 +898,14 @@ wxString ZONE_CONTAINER::GetSelectMenuText() const
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy polygons stored in aKiPolyList to m_FilledPolysList
|
||||||
|
* The previous m_FilledPolysList contents is replaced.
|
||||||
|
*/
|
||||||
|
void ZONE_CONTAINER::CopyPolygonsFromClipperPathsToFilledPolysList(
|
||||||
|
ClipperLib::Paths& aClipperPolyList )
|
||||||
|
{
|
||||||
|
m_FilledPolysList.RemoveAllContours();
|
||||||
|
m_FilledPolysList.ImportFrom( aClipperPolyList );
|
||||||
|
}
|
||||||
|
|
|
@ -305,6 +305,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void CopyPolygonsFromKiPolygonListToFilledPolysList( KI_POLYGON_SET& aKiPolyList );
|
void CopyPolygonsFromKiPolygonListToFilledPolysList( KI_POLYGON_SET& aKiPolyList );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CopyPolygonsFromClipperPathsToFilledPolysList
|
||||||
|
* Copy polygons stored in aKiPolyList to m_FilledPolysList
|
||||||
|
* The previous m_FilledPolysList contents is replaced.
|
||||||
|
* @param aClipperPolyList = a ClipperLib::Paths containing polygons.
|
||||||
|
*/
|
||||||
|
void CopyPolygonsFromClipperPathsToFilledPolysList( ClipperLib::Paths& aClipperPolyList );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CopyPolygonsFromFilledPolysListToKiPolygonList
|
* Function CopyPolygonsFromFilledPolysListToKiPolygonList
|
||||||
* Copy polygons from m_FilledPolysList to aKiPolyList
|
* Copy polygons from m_FilledPolysList to aKiPolyList
|
||||||
|
|
|
@ -41,9 +41,7 @@
|
||||||
#include <class_module.h>
|
#include <class_module.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/* Event handler for tracks and vias size selection (and some options)
|
||||||
* Function Tracks_and_Vias_Size_Event
|
|
||||||
* Event handler for tracks and vias size selection (and some options)
|
|
||||||
* relative to toolbars and popup events
|
* relative to toolbars and popup events
|
||||||
*/
|
*/
|
||||||
void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
|
void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
|
||||||
|
@ -142,5 +140,7 @@ void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
|
||||||
}*/
|
}*/
|
||||||
//+hp
|
//+hp
|
||||||
//Refresh canvas, that we can see changes instantly. I use this because it dont,t throw mouse up-left corner.
|
//Refresh canvas, that we can see changes instantly. I use this because it dont,t throw mouse up-left corner.
|
||||||
|
|
||||||
|
if( m_canvas->IsMouseCaptured() )
|
||||||
m_canvas->Refresh();
|
m_canvas->Refresh();
|
||||||
}
|
}
|
||||||
|
|
|
@ -773,12 +773,25 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
||||||
|
|
||||||
zone->TransformOutlinesShapeWithClearanceToPolygon( bufferPolys,
|
zone->TransformOutlinesShapeWithClearanceToPolygon( bufferPolys,
|
||||||
inflate, true );
|
inflate, true );
|
||||||
|
zone->TransformOutlinesShapeWithClearanceToPolygon( initialPolys,
|
||||||
|
0, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To avoid a lot of code, use a ZONE_CONTAINER
|
||||||
|
// to handle and plot polygons, because our polygons look exactly like
|
||||||
|
// filled areas in zones
|
||||||
|
// Note, also this code is not optimized: it creates a lot of copy/duplicate data
|
||||||
|
// However it is not complex, and fast enough for plot purposes (copy/convert data
|
||||||
|
// is only a very small calculation time for these calculations)
|
||||||
|
ZONE_CONTAINER zone( aBoard );
|
||||||
|
zone.SetArcSegmentCount( 32 );
|
||||||
|
zone.SetMinThickness( 0 ); // trace polygons only
|
||||||
|
zone.SetLayer ( layer );
|
||||||
|
|
||||||
// Now:
|
// Now:
|
||||||
// 1 - merge areas which are intersecting, i.e. remove gaps
|
// 1 - merge polygons which are intersecting, i.e. remove gaps
|
||||||
// having a thickness < aMinThickness
|
// having a thickness < aMinThickness
|
||||||
// 2 - deflate resulting areas by aMinThickness/2
|
// 2 - deflate resulting polygons by aMinThickness/2
|
||||||
KI_POLYGON_SET areasToMerge;
|
KI_POLYGON_SET areasToMerge;
|
||||||
bufferPolys.ExportTo( areasToMerge );
|
bufferPolys.ExportTo( areasToMerge );
|
||||||
KI_POLYGON_SET initialAreas;
|
KI_POLYGON_SET initialAreas;
|
||||||
|
@ -788,29 +801,44 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
||||||
// = aMinThickness/2, shapes too close ( dist < aMinThickness )
|
// = aMinThickness/2, shapes too close ( dist < aMinThickness )
|
||||||
// will be merged, because they are overlapping
|
// will be merged, because they are overlapping
|
||||||
KI_POLYGON_SET areas;
|
KI_POLYGON_SET areas;
|
||||||
areas |= areasToMerge;
|
areas |= areasToMerge; // Populates with merged polygons
|
||||||
|
|
||||||
// Deflate: remove the extra margin, to create the actual shapes
|
// Deflate: remove the extra margin, to create the actual shapes
|
||||||
// Here I am using polygon:resize, because this function creates better shapes
|
// Here I am using polygon:resize, because this function creates better shapes
|
||||||
// than deflate algo.
|
// than deflate algo.
|
||||||
// Use here deflate with arc creation and 18 segments per circle to create arcs
|
// Use here deflate made by Clipper, because:
|
||||||
// In boost polygon (at least v 1.54 and previous) in very rare cases resize crashes
|
// Clipper is (by far) faster and better, event using arcs to deflate shapes
|
||||||
// with 16 segments (perhaps related to 45 degrees pads). So using 18 segments
|
// boost::polygon < 1.56 polygon resize function sometimes crashes when deflating using arcs
|
||||||
// is a workaround to try to avoid these crashes
|
// boost::polygon >=1.56 polygon resize function just does not work
|
||||||
areas = resize( areas, -inflate , true, 18 );
|
// Note also we combine polygons using boost::polygon, which works better than Clipper,
|
||||||
|
// especially with zones using holes linked to main outlines by overlapping segments
|
||||||
|
CPOLYGONS_LIST tmp;
|
||||||
|
tmp.ImportFrom( areas );
|
||||||
|
|
||||||
// Resize slightly changes shapes. So *ensure* initial shapes are kept
|
// Deflate area using Clipper, better than boost::polygon
|
||||||
|
ClipperLib::Paths areasDeflate;
|
||||||
|
tmp.ExportTo( areasDeflate );
|
||||||
|
|
||||||
|
// Deflate areas: they will have the right size after deflate
|
||||||
|
ClipperLib::ClipperOffset offset_engine;
|
||||||
|
circleToSegmentsCount = 16;
|
||||||
|
offset_engine.ArcTolerance = (double)inflate / 3.14 / circleToSegmentsCount;
|
||||||
|
offset_engine.AddPaths( areasDeflate, ClipperLib::jtRound, ClipperLib::etClosedPolygon );
|
||||||
|
offset_engine.Execute( areasDeflate, -inflate );
|
||||||
|
|
||||||
|
// Combine the current areas to initial areas. This is mandatory because
|
||||||
|
// inflate/deflate transform is not perfect, and we want the initial areas perfectly kept
|
||||||
|
tmp.RemoveAllContours();
|
||||||
|
tmp.ImportFrom( areasDeflate );
|
||||||
|
areas.clear();
|
||||||
|
tmp.ExportTo( areas );
|
||||||
|
|
||||||
|
// Resize slightly changes shapes (the transform is not perfect).
|
||||||
|
// So *ensure* initial shapes are kept
|
||||||
areas |= initialAreas;
|
areas |= initialAreas;
|
||||||
|
|
||||||
// To avoid a lot of code, use a ZONE_CONTAINER
|
|
||||||
// to plot polygons, because they are exactly like
|
|
||||||
// filled areas in zones
|
|
||||||
ZONE_CONTAINER zone( aBoard );
|
|
||||||
zone.SetArcSegmentCount( 32 );
|
|
||||||
zone.SetMinThickness( 0 ); // trace polygons only
|
|
||||||
zone.SetLayer ( layer );
|
|
||||||
|
|
||||||
zone.CopyPolygonsFromKiPolygonListToFilledPolysList( areas );
|
zone.CopyPolygonsFromKiPolygonListToFilledPolysList( areas );
|
||||||
|
|
||||||
itemplotter.PlotFilledAreas( &zone );
|
itemplotter.PlotFilledAreas( &zone );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue