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;
|
||||
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
corners[ii] += PadShapePos;
|
||||
outline << ClipperLib::IntPoint( corners[ii].x, corners[ii].y );
|
||||
}
|
||||
|
||||
ClipperLib::ClipperOffset offset_engine;
|
||||
// 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 );
|
||||
|
||||
// get new outline (only one polygon is expected)
|
||||
// For info, ClipperLib uses long long to handle integer coordinates
|
||||
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();
|
||||
aCornerBuffer.ImportFrom( shapeWithClearance );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -898,3 +898,14 @@ wxString ZONE_CONTAINER::GetSelectMenuText() const
|
|||
|
||||
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 );
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Copy polygons from m_FilledPolysList to aKiPolyList
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
#include <class_module.h>
|
||||
|
||||
|
||||
/**
|
||||
* Function Tracks_and_Vias_Size_Event
|
||||
* Event handler for tracks and vias size selection (and some options)
|
||||
/* Event handler for tracks and vias size selection (and some options)
|
||||
* relative to toolbars and popup events
|
||||
*/
|
||||
void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
|
||||
|
@ -51,11 +49,11 @@ void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
|
|||
int ii;
|
||||
int id = event.GetId();
|
||||
|
||||
/* Note: none of these events require aborting the current command (if any)
|
||||
* (like move, edit or block command)
|
||||
* so we do not test for a current command in progress and call
|
||||
* m_canvas->m_endMouseCaptureCallback( m_canvas, &dc );
|
||||
*/
|
||||
/* Note: none of these events require aborting the current command (if any)
|
||||
* (like move, edit or block command)
|
||||
* so we do not test for a current command in progress and call
|
||||
* m_canvas->m_endMouseCaptureCallback( m_canvas, &dc );
|
||||
*/
|
||||
switch( id )
|
||||
{
|
||||
case ID_AUX_TOOLBAR_PCB_SELECT_AUTO_WIDTH:
|
||||
|
@ -142,5 +140,7 @@ void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
|
|||
}*/
|
||||
//+hp
|
||||
//Refresh canvas, that we can see changes instantly. I use this because it dont,t throw mouse up-left corner.
|
||||
m_canvas->Refresh();
|
||||
|
||||
if( m_canvas->IsMouseCaptured() )
|
||||
m_canvas->Refresh();
|
||||
}
|
||||
|
|
|
@ -773,12 +773,25 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
|
||||
zone->TransformOutlinesShapeWithClearanceToPolygon( bufferPolys,
|
||||
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:
|
||||
// 1 - merge areas which are intersecting, i.e. remove gaps
|
||||
// 1 - merge polygons which are intersecting, i.e. remove gaps
|
||||
// having a thickness < aMinThickness
|
||||
// 2 - deflate resulting areas by aMinThickness/2
|
||||
// 2 - deflate resulting polygons by aMinThickness/2
|
||||
KI_POLYGON_SET areasToMerge;
|
||||
bufferPolys.ExportTo( areasToMerge );
|
||||
KI_POLYGON_SET initialAreas;
|
||||
|
@ -788,29 +801,44 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
// = aMinThickness/2, shapes too close ( dist < aMinThickness )
|
||||
// will be merged, because they are overlapping
|
||||
KI_POLYGON_SET areas;
|
||||
areas |= areasToMerge;
|
||||
areas |= areasToMerge; // Populates with merged polygons
|
||||
|
||||
// Deflate: remove the extra margin, to create the actual shapes
|
||||
// Here I am using polygon:resize, because this function creates better shapes
|
||||
// than deflate algo.
|
||||
// Use here deflate with arc creation and 18 segments per circle to create arcs
|
||||
// In boost polygon (at least v 1.54 and previous) in very rare cases resize crashes
|
||||
// with 16 segments (perhaps related to 45 degrees pads). So using 18 segments
|
||||
// is a workaround to try to avoid these crashes
|
||||
areas = resize( areas, -inflate , true, 18 );
|
||||
// Use here deflate made by Clipper, because:
|
||||
// Clipper is (by far) faster and better, event using arcs to deflate shapes
|
||||
// boost::polygon < 1.56 polygon resize function sometimes crashes when deflating using arcs
|
||||
// boost::polygon >=1.56 polygon resize function just does not work
|
||||
// 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;
|
||||
|
||||
// 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 );
|
||||
|
||||
itemplotter.PlotFilledAreas( &zone );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue