Require explicit decl of maxError and errorLocations.

This should reduce both performance issues and clearance issues.
This commit is contained in:
Jeff Young 2020-10-13 11:55:24 +01:00
parent 58ba5a5cc1
commit 1703729269
36 changed files with 387 additions and 318 deletions

View File

@ -349,7 +349,7 @@ void BOARD_ADAPTER::createNewPadWithClearance( const D_PAD* aPad,
{
D_PAD dummy( *aPad );
dummy.SetSize( aPad->GetSize() + aClearanceValue + aClearanceValue );
dummy.TransformShapeWithClearanceToPolygon( poly, aLayer, 0 );
dummy.TransformShapeWithClearanceToPolygon( poly, aLayer, 0, ARC_HIGH_DEF, ERROR_INSIDE );
aClearanceValue = { 0, 0 };
}
else
@ -683,7 +683,8 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const PCB_SHAPE* aDrawSegm
SHAPE_POLY_SET polyList;
aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aLayerId,
aClearanceValue );
aClearanceValue,
ARC_HIGH_DEF, ERROR_INSIDE );
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
@ -736,7 +737,8 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const PCB_SHAPE* aDrawSegm
{
SHAPE_POLY_SET polyList;
aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aLayerId, aClearanceValue );
aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aLayerId, aClearanceValue,
ARC_HIGH_DEF, ERROR_INSIDE );
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );

View File

@ -392,10 +392,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
const int hole_outer_radius = (holediameter / 2) + GetHolePlatingThicknessBIU();
TransformCircleToPolygon( *layerOuterHolesPoly, via->GetStart(),
hole_outer_radius, ARC_HIGH_DEF );
hole_outer_radius, ARC_HIGH_DEF, ERROR_INSIDE );
TransformCircleToPolygon( *layerInnerHolesPoly, via->GetStart(),
holediameter / 2, ARC_HIGH_DEF );
holediameter / 2, ARC_HIGH_DEF, ERROR_INSIDE );
}
else if( curr_layer_id == layer_id[0] ) // it only adds once the THT holes
{
@ -406,17 +406,18 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// Add through hole contourns
// /////////////////////////////////////////////////////////
TransformCircleToPolygon( m_through_outer_holes_poly, via->GetStart(),
hole_outer_radius, ARC_HIGH_DEF );
hole_outer_radius, ARC_HIGH_DEF, ERROR_INSIDE );
// Add same thing for vias only
TransformCircleToPolygon( m_through_outer_holes_vias_poly,
via->GetStart(), hole_outer_radius, ARC_HIGH_DEF );
TransformCircleToPolygon( m_through_outer_holes_vias_poly, via->GetStart(),
hole_outer_radius, ARC_HIGH_DEF, ERROR_INSIDE );
if( GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS ) )
{
TransformCircleToPolygon( m_through_outer_ring_holes_poly,
via->GetStart(), hole_outer_ring_radius, ARC_HIGH_DEF );
via->GetStart(), hole_outer_ring_radius,
ARC_HIGH_DEF, ERROR_INSIDE );
}
}
}
@ -451,7 +452,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
continue;
// Add the track/via contour
track->TransformShapeWithClearanceToPolygon( *layerPoly, curr_layer_id, 0 );
track->TransformShapeWithClearanceToPolygon( *layerPoly, curr_layer_id, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
}
}
}
@ -506,17 +508,26 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
if( pad->GetAttribute () != PAD_ATTRIB_NPTH )
{
if( GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS ) )
pad->TransformHoleWithClearanceToPolygon( m_through_outer_ring_holes_poly, inflate );
{
pad->TransformHoleWithClearanceToPolygon( m_through_outer_ring_holes_poly,
inflate,
ARC_HIGH_DEF, ERROR_INSIDE );
}
pad->TransformHoleWithClearanceToPolygon( m_through_outer_holes_poly, inflate );
pad->TransformHoleWithClearanceToPolygon( m_through_outer_holes_poly, inflate,
ARC_HIGH_DEF, ERROR_INSIDE );
}
else
{
// If not plated, no copper.
if( GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS ) )
pad->TransformHoleWithClearanceToPolygon( m_through_outer_ring_holes_poly, 0 );
{
pad->TransformHoleWithClearanceToPolygon( m_through_outer_ring_holes_poly, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
}
pad->TransformHoleWithClearanceToPolygon( m_through_outer_holes_poly_NPTH, 0 );
pad->TransformHoleWithClearanceToPolygon( m_through_outer_holes_poly_NPTH, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
}
}
}
@ -535,19 +546,11 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
// Note: NPTH pads are not drawn on copper layers when the pad
// has same shape as its hole
AddPadsShapesWithClearanceToContainer( module,
layerContainer,
curr_layer_id,
0,
true,
renderPlatedPadsAsPlated,
false );
AddPadsShapesWithClearanceToContainer( module, layerContainer, curr_layer_id, 0,
true, renderPlatedPadsAsPlated, false );
// Micro-wave modules may have items on copper layers
AddGraphicsShapesWithClearanceToContainer( module,
layerContainer,
curr_layer_id,
0 );
AddGraphicsShapesWithClearanceToContainer( module, layerContainer, curr_layer_id, 0 );
}
}
@ -556,21 +559,11 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// ADD PLATED PADS
for( MODULE* module : m_board->Modules() )
{
AddPadsShapesWithClearanceToContainer( module,
m_platedpads_container2D_F_Cu,
F_Cu,
0,
true,
false,
true );
AddPadsShapesWithClearanceToContainer( module, m_platedpads_container2D_F_Cu, F_Cu, 0,
true, false, true );
AddPadsShapesWithClearanceToContainer( module,
m_platedpads_container2D_B_Cu,
B_Cu,
0,
true,
false,
true );
AddPadsShapesWithClearanceToContainer( module, m_platedpads_container2D_B_Cu, B_Cu, 0,
true, false, true );
}
}
@ -589,9 +582,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
// Note: NPTH pads are not drawn on copper layers when the pad
// has same shape as its hole
module->TransformPadsShapesWithClearanceToPolygon( curr_layer_id, *layerPoly,
0, ARC_HIGH_DEF, true,
renderPlatedPadsAsPlated,
module->TransformPadsShapesWithClearanceToPolygon( *layerPoly, curr_layer_id,
0, ARC_HIGH_DEF, ERROR_INSIDE,
true, renderPlatedPadsAsPlated,
false );
transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
@ -603,15 +596,15 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// ADD PLATED PADS contourns
for( auto module : m_board->Modules() )
{
module->TransformPadsShapesWithClearanceToPolygon( F_Cu, *m_F_Cu_PlatedPads_poly,
0, ARC_HIGH_DEF, true,
false, true );
module->TransformPadsShapesWithClearanceToPolygon( *m_F_Cu_PlatedPads_poly, F_Cu,
0, ARC_HIGH_DEF, ERROR_INSIDE,
true, false, true );
//transformGraphicModuleEdgeToPolygonSet( module, F_Cu, *m_F_Cu_PlatedPads_poly );
module->TransformPadsShapesWithClearanceToPolygon( B_Cu, *m_B_Cu_PlatedPads_poly,
0, ARC_HIGH_DEF, true,
false, true );
module->TransformPadsShapesWithClearanceToPolygon( *m_B_Cu_PlatedPads_poly, B_Cu,
0, ARC_HIGH_DEF, ERROR_INSIDE,
true, false, true );
//transformGraphicModuleEdgeToPolygonSet( module, B_Cu, *m_B_Cu_PlatedPads_poly );
}
@ -636,17 +629,13 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
case PCB_SHAPE_T:
{
AddShapeWithClearanceToContainer( (PCB_SHAPE*)item,
layerContainer,
curr_layer_id,
AddShapeWithClearanceToContainer( (PCB_SHAPE*)item, layerContainer, curr_layer_id,
0 );
}
break;
case PCB_TEXT_T:
AddShapeWithClearanceToContainer( (PCB_TEXT*) item,
layerContainer,
curr_layer_id,
AddShapeWithClearanceToContainer( (PCB_TEXT*) item, layerContainer, curr_layer_id,
0 );
break;
@ -654,9 +643,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
case PCB_DIM_CENTER_T:
case PCB_DIM_ORTHOGONAL_T:
case PCB_DIM_LEADER_T:
AddShapeWithClearanceToContainer( (DIMENSION*) item,
layerContainer,
curr_layer_id,
AddShapeWithClearanceToContainer( (DIMENSION*) item, layerContainer, curr_layer_id,
0 );
break;
@ -689,11 +676,15 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
case PCB_SHAPE_T:
( (PCB_SHAPE*) item )->TransformShapeWithClearanceToPolygon( *layerPoly,
cur_layer_id, 0 );
cur_layer_id, 0,
ARC_HIGH_DEF,
ERROR_INSIDE );
break;
case PCB_TEXT_T:
( (PCB_TEXT*) item )->TransformShapeWithClearanceToPolygonSet( *layerPoly, 0 );
( (PCB_TEXT*) item )->TransformShapeWithClearanceToPolygonSet( *layerPoly, 0,
ARC_HIGH_DEF,
ERROR_INSIDE );
break;
default:
@ -972,11 +963,15 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
case PCB_SHAPE_T:
( (PCB_SHAPE*) item )->TransformShapeWithClearanceToPolygon( *layerPoly,
curr_layer_id, 0 );
curr_layer_id, 0,
ARC_HIGH_DEF,
ERROR_INSIDE );
break;
case PCB_TEXT_T:
( (PCB_TEXT*) item )->TransformShapeWithClearanceToPolygonSet( *layerPoly, 0 );
( (PCB_TEXT*) item )->TransformShapeWithClearanceToPolygonSet( *layerPoly, 0,
ARC_HIGH_DEF,
ERROR_INSIDE );
break;
default:
@ -1030,11 +1025,13 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
}
else
{
module->TransformPadsShapesWithClearanceToPolygon( curr_layer_id, *layerPoly, 0 );
module->TransformPadsShapesWithClearanceToPolygon( *layerPoly, curr_layer_id, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
}
// On tech layers, use a poor circle approximation, only for texts (stroke font)
module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id, *layerPoly, 0 );
module->TransformGraphicTextWithClearanceToPolygonSet( *layerPoly, curr_layer_id, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
// Add the remaining things with dynamic seg count for circles
transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );

View File

@ -41,7 +41,7 @@ void BOARD_ADAPTER::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // Draw a ring
{
TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(), aPad->GetSize().x / 2,
ARC_HIGH_DEF, aWidth );
aWidth, ARC_HIGH_DEF, ERROR_INSIDE );
return;
}
@ -54,7 +54,8 @@ void BOARD_ADAPTER::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
const VECTOR2I& a = path.CPoint( ii );
const VECTOR2I& b = path.CPoint( ii + 1 );
TransformOvalToPolygon( aCornerBuffer, (wxPoint) a, (wxPoint) b, aWidth, ARC_HIGH_DEF );
TransformOvalToPolygon( aCornerBuffer, (wxPoint) a, (wxPoint) b, aWidth, ARC_HIGH_DEF,
ERROR_INSIDE );
}
}
@ -70,7 +71,10 @@ void BOARD_ADAPTER::transformGraphicModuleEdgeToPolygonSet( const MODULE *aModul
FP_SHAPE* outline = (FP_SHAPE*) item;
if( outline->GetLayer() == aLayer )
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0 );
{
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
ARC_HIGH_DEF, ERROR_INSIDE );
}
}
}
}

View File

@ -825,9 +825,10 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
const int copperThickness = m_boardAdapter.GetHolePlatingThicknessBIU();
pad->TransformHoleWithClearanceToPolygon( tht_outer_holes_poly,
copperThickness, ARC_LOW_DEF );
pad->TransformHoleWithClearanceToPolygon( tht_inner_holes_poly,
0, ARC_LOW_DEF );
copperThickness,
ARC_LOW_DEF, ERROR_INSIDE );
pad->TransformHoleWithClearanceToPolygon( tht_inner_holes_poly, 0,
ARC_LOW_DEF, ERROR_INSIDE );
}
}
}

View File

@ -533,7 +533,7 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
{
TransformOvalToPolygon( bufferOutline, aCornerList[ ii - 1 ], aCornerList[ ii ],
aWidth, GetPlotterArcHighDef() );
aWidth, GetPlotterArcHighDef(), ERROR_INSIDE );
}
// enter the initial polygon:
@ -620,7 +620,8 @@ void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int
{
std::vector<wxPoint> cornerList;
SHAPE_POLY_SET outlineBuffer;
TransformOvalToPolygon( outlineBuffer, aStart, aEnd, aWidth, GetPlotterArcHighDef() );
TransformOvalToPolygon( outlineBuffer, aStart, aEnd, aWidth, GetPlotterArcHighDef(),
ERROR_INSIDE );
const SHAPE_LINE_CHAIN& path = outlineBuffer.COutline( 0 );
cornerList.reserve( path.PointCount() );
@ -777,7 +778,7 @@ void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize
{
SHAPE_POLY_SET outline;
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
aCornerRadius, 0.0, 0, GetPlotterArcHighDef(), ERROR_INSIDE );
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );

View File

@ -1227,7 +1227,7 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
{
SHAPE_POLY_SET outline;
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
aCornerRadius, 0.0, 0, GetPlotterArcHighDef(), ERROR_INSIDE );
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
outline.Inflate( -GetCurrentLineWidth()/2, 16 );
@ -1489,10 +1489,9 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const wxPoint& aShapePos, const w
if( aPlotMode != FILLED || hasRoundedCorner || m_gerberDisableApertMacros )
#endif
{
TransformRoundChamferedRectToPolygon( outline, aShapePos, aPadSize,
aPadOrient, aCornerRadius,
aChamferRatio,
aChamferPositions, m_IUsPerDecimil * 2 );
TransformRoundChamferedRectToPolygon( outline, aShapePos, aPadSize, aPadOrient,
aCornerRadius, aChamferRatio, aChamferPositions,
GetPlotterArcHighDef(), ERROR_INSIDE );
// Build the corner list
const SHAPE_LINE_CHAIN& corners = outline.Outline(0);
@ -1535,9 +1534,9 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const wxPoint& aShapePos, const w
}
// Build the chamfered polygon (4 to 8 corners )
TransformRoundChamferedRectToPolygon( outline, wxPoint( 0, 0 ), aPadSize,
0.0, 0, aChamferRatio,
aChamferPositions, 0 );
TransformRoundChamferedRectToPolygon( outline, wxPoint( 0, 0 ), aPadSize, 0.0, 0,
aChamferRatio, aChamferPositions,
GetPlotterArcHighDef(), ERROR_INSIDE );
// Build the corner list
const SHAPE_LINE_CHAIN& corners = outline.Outline(0);

View File

@ -640,8 +640,8 @@ void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSiz
aCornerRadius = std::min( aCornerRadius, std::min( size.x, size.y ) /2 );
}
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient, aCornerRadius,
0.0, 0, GetPlotterArcHighDef(), ERROR_INSIDE );
// TransformRoundRectToPolygon creates only one convex polygon
std::vector<wxPoint> cornerList;

View File

@ -192,8 +192,8 @@ void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
SHAPE_POLY_SET outline;
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient, aCornerRadius,
0.0, 0, GetPlotterArcHighDef(), ERROR_INSIDE );
std::vector< wxPoint > cornerList;
// TransformRoundRectToPolygon creates only one convex polygon

View File

@ -311,11 +311,14 @@ void AM_PRIMITIVE::DrawBasicShape( const GERBER_DRAW_ITEM* aParent,
if( outerDiam <= penThickness )
{ // No room to draw a ring (no room for the hole):
// draw a circle instead (with no hole), with the right diameter
TransformCircleToPolygon( aShapeBuffer, center, outerDiam / 2, ARC_HIGH_DEF );
TransformCircleToPolygon( aShapeBuffer, center, outerDiam / 2, ARC_HIGH_DEF,
ERROR_INSIDE );
}
else
{
TransformRingToPolygon( aShapeBuffer, center, ( outerDiam - penThickness ) / 2,
ARC_HIGH_DEF, penThickness );
penThickness, ARC_HIGH_DEF, ERROR_INSIDE );
}
}
// Draw the cross:

View File

@ -306,7 +306,8 @@ void D_CODE::ConvertShapeToPolygon()
switch( m_Shape )
{
case APT_CIRCLE: // creates only a circle with rectangular hole
TransformCircleToPolygon( m_Polygon, initialpos, m_Size.x >> 1, ARC_HIGH_DEF );
TransformCircleToPolygon( m_Polygon, initialpos, m_Size.x >> 1, ARC_HIGH_DEF,
ERROR_INSIDE );
addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
break;
@ -428,7 +429,8 @@ static void addHoleToPolygon( SHAPE_POLY_SET* aPolygon,
if( aHoleShape == APT_DEF_ROUND_HOLE )
{
TransformCircleToPolygon( holeBuffer, wxPoint( 0, 0 ), aSize.x / 2, ARC_HIGH_DEF );
TransformCircleToPolygon( holeBuffer, wxPoint( 0, 0 ), aSize.x / 2, ARC_HIGH_DEF,
ERROR_INSIDE );
}
else if( aHoleShape == APT_DEF_RECT_HOLE )
{

View File

@ -36,7 +36,7 @@
#include <convert_to_biu.h>
#include <gr_basic.h>
#include <layers_id_colors_and_visibility.h>
#include <geometry/geometry_utils.h>
class BOARD;
class BOARD_ITEM_CONTAINER;
@ -360,13 +360,13 @@ public:
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aError = the maximum deviation from true circle
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
virtual void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer,
int aClearanceValue,
int aError = ARC_LOW_DEF,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth = false ) const;
struct ptr_cmp

View File

@ -25,13 +25,11 @@
#ifndef CONVERT_BASIC_SHAPES_TO_POLYGON_H
#define CONVERT_BASIC_SHAPES_TO_POLYGON_H
/**
* @file convert_basic_shapes_to_polygon.h
*/
#include <geometry/shape_poly_set.h>
#include <geometry/geometry_utils.h>
#include <wx/gdicmn.h> // for wxPoint
// The chamfer positions of chamfered rect shape.
// the position is relative to a pad with orientation = 0
// we can have 1 to 4 chamfered corners (0 corner = roundrect)
@ -43,8 +41,10 @@ enum RECT_CHAMFER_POSITIONS : int
RECT_CHAMFER_TOP_RIGHT = 2,
RECT_CHAMFER_BOTTOM_LEFT = 4,
RECT_CHAMFER_BOTTOM_RIGHT = 8,
RECT_CHAMFER_ALL = RECT_CHAMFER_BOTTOM_RIGHT | RECT_CHAMFER_BOTTOM_LEFT
| RECT_CHAMFER_TOP_RIGHT | RECT_CHAMFER_TOP_LEFT
RECT_CHAMFER_ALL = RECT_CHAMFER_BOTTOM_RIGHT
| RECT_CHAMFER_BOTTOM_LEFT
| RECT_CHAMFER_TOP_RIGHT
| RECT_CHAMFER_TOP_LEFT
};
@ -55,11 +55,10 @@ enum RECT_CHAMFER_POSITIONS : int
* @param aCenter = the center of the circle
* @param aRadius = the radius of the circle
* @param aError = the IU allowed for error in approximation
* Note: the polygon is inside the circle, so if you want to have the polygon
* outside the circle, you should give aRadius calculated with a correction factor
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
*/
void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCenter, int aRadius,
int aError );
int aError, ERROR_LOC aErrorLoc );
/**
@ -75,9 +74,10 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCenter, i
* @param aEnd = the second point of the segment
* @param aWidth = the width of the segment
* @param aError = the IU allowed for error in approximation
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
*/
void TransformOvalToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aStart, wxPoint aEnd,
int aWidth, int aError );
int aWidth, int aError, ERROR_LOC aErrorLoc );
/**
@ -112,11 +112,13 @@ void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius, const wxPoint&
* 8 = BOTTOM_RIGHT
* One can have more than one chamfered corner by ORing the corner identifers
* @param aError = the IU allowed for error in approximation
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
*/
void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
const wxPoint& aPosition, const wxSize& aSize,
double aRotation, int aCornerRadius,
double aChamferRatio, int aChamferCorners, int aError );
double aChamferRatio, int aChamferCorners,
int aError, ERROR_LOC aErrorLoc );
/**
* Function TransformArcToPolygon
@ -126,11 +128,12 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
* @param aCentre = centre of the arc or circle
* @param aStart = start point of the arc, or a point on the circle
* @param aArcAngle = arc angle in 0.1 degrees. For a circle, aArcAngle = 3600
* @param aError = the IU allowed for error in approximation
* @param aWidth = width (thickness) of the line
* @param aError = the IU allowed for error in approximation
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
*/
void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCentre, wxPoint aStart,
double aArcAngle, int aError, int aWidth );
double aArcAngle, int aWidth, int aError, ERROR_LOC aErrorLoc );
/**
* Function TransformRingToPolygon
@ -139,10 +142,11 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCentre, wxPo
* @param aCornerBuffer = a buffer to store the polygon
* @param aCentre = centre of the arc or circle
* @param aRadius = radius of the circle
* @param aError = the IU allowed for error in approximation
* @param aWidth = width (thickness) of the ring
* @param aError = the IU allowed for error in approximation
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
*/
void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCentre, int aRadius,
int aError, int aWidth );
int aWidth, int aError, ERROR_LOC aErrorLoc );
#endif // CONVERT_BASIC_SHAPES_TO_POLYGON_H

View File

@ -37,6 +37,13 @@
class EDA_RECT;
/**
* When approximating an arc or circle, should the error be placed on the outside
* or inside of the curve? (Generally speaking filled shape errors go on the inside
* and knockout errors go on the outside. This preserves minimum clearances.)
*/
enum ERROR_LOC { ERROR_OUTSIDE, ERROR_INSIDE };
/**
* @return the number of segments to approximate a arc by segments
* with a given max error (this number is >= 1)

View File

@ -39,14 +39,15 @@
void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aCornerBuffer, wxPoint aCenter, int aRadius,
int aError )
int aError, ERROR_LOC aErrorLoc )
{
wxPoint corner_position;
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 );
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
int correction = GetCircleToPolyCorrection( aError );
int radius = aRadius + correction; // make segments outside the circles
double halfstep = delta / 2.0; // the starting value for rot angles
int radius = aRadius;
if( aErrorLoc == ERROR_OUTSIDE )
radius += GetCircleToPolyCorrection( aError );
for( int angle = 0; angle < 3600; angle += delta )
{
@ -62,13 +63,15 @@ void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aCornerBuffer, wxPoint aCenter,
void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCenter, int aRadius,
int aError )
int aError, ERROR_LOC aErrorLoc )
{
wxPoint corner_position;
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 );
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
int correction = GetCircleToPolyCorrection( aError );
int radius = aRadius + correction; // make segments outside the circles
int radius = aRadius;
if( aErrorLoc == ERROR_OUTSIDE )
radius += GetCircleToPolyCorrection( aError );
aCornerBuffer.NewOutline();
@ -90,7 +93,7 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCenter, i
void TransformOvalToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aStart, wxPoint aEnd,
int aWidth, int aError )
int aWidth, int aError, ERROR_LOC aErrorLoc )
{
// To build the polygonal shape outside the actual shape, we use a bigger
// radius to build rounded ends.
@ -102,7 +105,8 @@ void TransformOvalToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aStart, wxPo
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
int correction = GetCircleToPolyCorrection( aError );
radius += correction; // make segments outside the circles
if( aErrorLoc == ERROR_OUTSIDE )
radius += correction;
// end point is the coordinate relative to aStart
wxPoint endp = aEnd - aStart;
@ -218,7 +222,7 @@ void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius, const wxPoint&
void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer, const wxPoint& aPosition,
const wxSize& aSize, double aRotation,
int aCornerRadius, double aChamferRatio,
int aChamferCorners, int aError )
int aChamferCorners, int aError, ERROR_LOC aErrorLoc )
{
// Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
// or in actual position/orientation for round rect only
@ -244,28 +248,13 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer, const
// radius to build rounded corners.
int correction = GetCircleToPolyCorrection( aError );
int radius = aCornerRadius + correction; // make segments outside the circles
int radius = aCornerRadius;
if( aErrorLoc == ERROR_OUTSIDE )
radius += correction;
outline.Inflate( radius, numSegs );
if( correction > 1.0 )
{
// Refinement: clamp the inflated polygonal shape by the rectangular shape
// containing the rounded polygon
SHAPE_POLY_SET bbox; // the rectangular shape
bbox.NewOutline();
for( const wxPoint& corner : corners )
bbox.Append( corner );
// Just build the rectangular bbox
bbox.Inflate( aCornerRadius, 1, SHAPE_POLY_SET::CORNER_STRATEGY::ALLOW_ACUTE_CORNERS );
// Now, clamp the shape
outline.BooleanIntersection( bbox, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
// Note the final polygon is a simple, convex polygon with no hole
// due to the shape of initial polygons
}
if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
{
// Add the outline:
@ -334,7 +323,7 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer, const
void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCentre, wxPoint aStart,
double aArcAngle, int aError, int aWidth )
double aArcAngle, int aWidth, int aError, ERROR_LOC aErrorLoc )
{
wxPoint arc_start, arc_end;
int dist = EuclideanNorm( aCentre - aStart );
@ -360,34 +349,35 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCentre, wxPo
{
curr_end = arc_start;
RotatePoint( &curr_end, aCentre, -ii );
TransformOvalToPolygon( aCornerBuffer, curr_start, curr_end, aWidth, aError );
TransformOvalToPolygon( aCornerBuffer, curr_start, curr_end, aWidth, aError, aErrorLoc );
curr_start = curr_end;
}
if( curr_end != arc_end )
TransformOvalToPolygon( aCornerBuffer, curr_end, arc_end, aWidth, aError );
TransformOvalToPolygon( aCornerBuffer, curr_end, arc_end, aWidth, aError, aErrorLoc );
}
void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCentre, int aRadius,
int aError, int aWidth )
int aWidth, int aError, ERROR_LOC aErrorLoc )
{
int inner_radius = aRadius - ( aWidth / 2 );
int outer_radius = inner_radius + aWidth;
if( inner_radius <= 0 )
{ //In this case, the ring is just a circle (no hole inside)
TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ), aError );
TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ), aError,
aErrorLoc );
return;
}
SHAPE_POLY_SET buffer;
TransformCircleToPolygon( buffer, aCentre, outer_radius, aError );
TransformCircleToPolygon( buffer, aCentre, outer_radius, aError, aErrorLoc );
// Build the hole:
buffer.NewHole();
TransformCircleToPolygon( buffer.Hole( 0, 0 ), aCentre, inner_radius, aError );
TransformCircleToPolygon( buffer.Hole( 0, 0 ), aCentre, inner_radius, aError, aErrorLoc );
buffer.Fracture( SHAPE_POLY_SET::PM_FAST );
aCornerBuffer.Append( buffer );

View File

@ -46,40 +46,48 @@
// These variables are parameters used in addTextSegmToPoly.
// But addTextSegmToPoly is a call-back function,
// so we cannot send them as arguments.
struct TSEGM_2_POLY_PRMS {
struct TSEGM_2_POLY_PRMS
{
int m_textWidth;
int m_error;
SHAPE_POLY_SET* m_cornerBuffer;
};
TSEGM_2_POLY_PRMS prms;
// This is a call back function, used by GRText to draw the 3D text shape:
static void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData )
{
TSEGM_2_POLY_PRMS* prm = static_cast<TSEGM_2_POLY_PRMS*>( aData );
TransformOvalToPolygon( *prm->m_cornerBuffer, wxPoint( x0, y0 ), wxPoint( xf, yf ),
prm->m_textWidth, prm->m_error );
prm->m_textWidth, prm->m_error, ERROR_INSIDE );
}
void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aOutlines )
{
int maxError = GetDesignSettings().m_MaxError;
// convert tracks and vias:
for( auto track : m_tracks )
{
if( !track->IsOnLayer( aLayer ) )
continue;
track->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0 );
track->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
ERROR_INSIDE );
}
// convert pads
for( auto module : m_modules )
for( MODULE* module : m_modules )
{
module->TransformPadsShapesWithClearanceToPolygon( aLayer, aOutlines, 0 );
module->TransformPadsShapesWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
ERROR_INSIDE );
// Micro-wave modules may have items on copper layers
module->TransformGraphicShapesWithClearanceToPolygonSet( aLayer, aOutlines, 0 );
module->TransformGraphicShapesWithClearanceToPolygonSet( aOutlines, aLayer, 0, maxError,
ERROR_INSIDE );
}
// convert copper zones
@ -90,7 +98,7 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
}
// convert graphic items on copper layers (texts)
for( auto item : m_drawings )
for( BOARD_ITEM* item : m_drawings )
{
if( !item->IsOnLayer( aLayer ) )
continue;
@ -98,11 +106,18 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
switch( item->Type() )
{
case PCB_SHAPE_T:
( (PCB_SHAPE*) item )->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0 );
{
PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
shape->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
ERROR_INSIDE );
}
break;
case PCB_TEXT_T:
( (PCB_TEXT*) item )->TransformShapeWithClearanceToPolygonSet( aOutlines, 0 );
{
PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
text->TransformShapeWithClearanceToPolygonSet( aOutlines, 0, maxError, ERROR_INSIDE );
}
break;
default:
@ -112,9 +127,9 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
}
void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue, int aMaxError,
void MODULE::TransformPadsShapesWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearance,
int aMaxError, ERROR_LOC aErrorLoc,
bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads,
bool aSkipNonPlatedPads ) const
@ -160,7 +175,7 @@ void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
if( aSkipNonPlatedPads && !isPlated )
continue;
wxSize clearance( aInflateValue, aInflateValue );
wxSize clearance( aClearance, aClearance );
switch( aLayer )
{
@ -191,12 +206,13 @@ void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
{
D_PAD dummy( *pad );
dummy.SetSize( pad->GetSize() + clearance + clearance );
dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0, aMaxError );
dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
aMaxError, aErrorLoc );
}
else
{
pad->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, clearance.x,
aMaxError );
aMaxError, aErrorLoc );
}
}
}
@ -209,10 +225,9 @@ void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
* @aIncludeText = indicates footprint text items (reference, value, etc.) should be included
* in the outline
*/
void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue,
int aError,
void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc,
bool aIncludeText,
bool aIncludeEdges ) const
{
@ -233,7 +248,10 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLaye
FP_SHAPE* outline = static_cast<FP_SHAPE*>( item );
if( aLayer != UNDEFINED_LAYER && outline->GetLayer() == aLayer )
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0, aError );
{
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
aError, aErrorLoc );
}
}
}
@ -253,7 +271,7 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLaye
bool forceBold = true;
int penWidth = 0; // force max width for bold text
prms.m_textWidth = textmod->GetEffectiveTextPenWidth() + ( 2 * aInflateValue );
prms.m_textWidth = textmod->GetEffectiveTextPenWidth() + ( 2 * aClearance );
prms.m_error = aError;
wxSize size = textmod->GetTextSize();
@ -339,7 +357,8 @@ void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( SHAPE_POLY_SET* aCorn
* @aError = the maximum error to allow when approximating curves
*/
void PCB_TEXT::TransformShapeWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue, int aError ) const
int aClearanceValue,
int aError, ERROR_LOC aErrorLoc ) const
{
wxSize size = GetTextSize();
@ -378,8 +397,8 @@ void PCB_TEXT::TransformShapeWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerB
void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer,
int aClearanceValue, int aError,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth ) const
{
int width = ignoreLineWidth ? 0 : m_Width;
@ -397,9 +416,15 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf
{
case S_CIRCLE:
if( width == 0 )
TransformCircleToPolygon( aCornerBuffer, GetCenter(), GetRadius(), aError );
{
TransformCircleToPolygon( aCornerBuffer, GetCenter(), GetRadius(), aError,
aErrorLoc );
}
else
TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(), aError, width );
{
TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(), width, aError,
aErrorLoc );
}
break;
case S_RECT:
@ -417,20 +442,21 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf
if( width > 0 )
{
// Add in segments
TransformOvalToPolygon( aCornerBuffer, pts[0], pts[1], width, aError );
TransformOvalToPolygon( aCornerBuffer, pts[1], pts[2], width, aError );
TransformOvalToPolygon( aCornerBuffer, pts[2], pts[3], width, aError );
TransformOvalToPolygon( aCornerBuffer, pts[3], pts[0], width, aError );
TransformOvalToPolygon( aCornerBuffer, pts[0], pts[1], width, aError, aErrorLoc );
TransformOvalToPolygon( aCornerBuffer, pts[1], pts[2], width, aError, aErrorLoc );
TransformOvalToPolygon( aCornerBuffer, pts[2], pts[3], width, aError, aErrorLoc );
TransformOvalToPolygon( aCornerBuffer, pts[3], pts[0], width, aError, aErrorLoc );
}
}
break;
case S_ARC:
TransformArcToPolygon( aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, aError, width );
TransformArcToPolygon( aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, width,
aError, aErrorLoc );
break;
case S_SEGMENT:
TransformOvalToPolygon( aCornerBuffer, m_Start, m_End, width, aError );
TransformOvalToPolygon( aCornerBuffer, m_Start, m_End, width, aError, aErrorLoc );
break;
case S_POLYGON:
@ -470,7 +496,10 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf
for( wxPoint pt2 : poly )
{
if( pt2 != pt1 )
TransformOvalToPolygon( aCornerBuffer, pt1, pt2, width, aError );
{
TransformOvalToPolygon( aCornerBuffer, pt1, pt2, width,
aError, aErrorLoc );
}
pt1 = pt2;
}
@ -488,7 +517,10 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf
if( width != 0 )
{
for( unsigned ii = 1; ii < poly.size(); ii++ )
TransformOvalToPolygon( aCornerBuffer, poly[ii-1], poly[ii], width, aError );
{
TransformOvalToPolygon( aCornerBuffer, poly[ii-1], poly[ii], width,
aError, aErrorLoc );
}
}
}
break;
@ -502,8 +534,8 @@ void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf
void TRACK::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer,
int aClearanceValue, int aError,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth ) const
{
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for tracks." );
@ -514,7 +546,7 @@ void TRACK::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
case PCB_VIA_T:
{
int radius = ( m_Width / 2 ) + aClearanceValue;
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aError );
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aError, aErrorLoc );
}
break;
@ -525,7 +557,8 @@ void TRACK::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
VECTOR2D center( arc->GetCenter() );
double angle = arc->GetAngle();
TransformArcToPolygon( aCornerBuffer, (wxPoint) center, GetStart(), angle, aError, width );
TransformArcToPolygon( aCornerBuffer, (wxPoint) center, GetStart(), angle, width,
aError, aErrorLoc );
}
break;
@ -533,7 +566,7 @@ void TRACK::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
{
int width = m_Width + ( 2 * aClearanceValue );
TransformOvalToPolygon( aCornerBuffer, m_Start, m_End, width, aError );
TransformOvalToPolygon( aCornerBuffer, m_Start, m_End, width, aError, aErrorLoc );
}
break;
}
@ -541,8 +574,8 @@ void TRACK::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer,
int aClearanceValue, int aError,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth ) const
{
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for pads." );
@ -564,7 +597,8 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
case PAD_SHAPE_OVAL:
if( dx == dy )
{
TransformCircleToPolygon( aCornerBuffer, padShapePos, dx + aClearanceValue, aError );
TransformCircleToPolygon( aCornerBuffer, padShapePos, dx + aClearanceValue, aError,
aErrorLoc );
}
else
{
@ -574,7 +608,7 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
RotatePoint( &delta, angle );
TransformOvalToPolygon( aCornerBuffer, padShapePos - delta, padShapePos + delta,
( half_width + aClearanceValue ) * 2, aError );
( half_width + aClearanceValue ) * 2, aError, aErrorLoc );
}
break;
@ -619,19 +653,19 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
case PAD_SHAPE_CHAMFERED_RECT:
case PAD_SHAPE_ROUNDRECT:
{
int radius = GetRoundRectCornerRadius() + aClearanceValue;
int clearance = aClearanceValue + GetCircleToPolyCorrection( aError );
int radius = GetRoundRectCornerRadius();
wxSize shapesize( m_size );
radius = radius + GetCircleToPolyCorrection( aError );
shapesize.x += clearance * 2;
shapesize.y += clearance * 2;
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
radius += aClearanceValue;
shapesize.x += aClearanceValue * 2;
shapesize.y += aClearanceValue * 2;
SHAPE_POLY_SET outline;
TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle, radius,
doChamfer ? GetChamferRectRatio() : 0.0,
doChamfer ? GetChamferPositions() : 0, aError );
doChamfer ? GetChamferPositions() : 0,
aError, aErrorLoc );
aCornerBuffer.Append( outline );
}
@ -648,7 +682,10 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
{
int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ),
pad_min_seg_per_circle_count );
int clearance = aClearanceValue + GetCircleToPolyCorrection( aError );
int clearance = aClearanceValue;
if( aErrorLoc == ERROR_OUTSIDE )
clearance += GetCircleToPolyCorrection( aError );
outline.Inflate( clearance, numSegs );
outline.Simplify( SHAPE_POLY_SET::PM_FAST );
@ -669,7 +706,7 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
bool D_PAD::TransformHoleWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aInflateValue,
int aError ) const
int aError, ERROR_LOC aErrorLoc ) const
{
wxSize drillsize = GetDrillSize();
@ -679,7 +716,7 @@ bool D_PAD::TransformHoleWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
const SHAPE_SEGMENT* seg = GetEffectiveHoleShape();
TransformOvalToPolygon( aCornerBuffer, (wxPoint) seg->GetSeg().A, (wxPoint) seg->GetSeg().B,
seg->GetWidth() + aInflateValue * 2, aError );
seg->GetWidth() + aInflateValue * 2, aError, aErrorLoc );
return true;
}
@ -687,7 +724,8 @@ bool D_PAD::TransformHoleWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearance,
int aError, bool ignoreLineWidth ) const
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth ) const
{
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for zones." );

View File

@ -598,12 +598,9 @@ public:
wxPoint* aErrorLocation = nullptr );
/**
* Build a set of polygons which are the outlines of copper items
* (pads, tracks, vias, texts, zones)
* Holes in vias or pads are ignored
* Useful to export the shape of copper layers to dxf polygons
* or 3D viewer
* the polygons are not merged.
* Build a set of polygons which are the outlines of copper items (pads, tracks, vias, texts,
* zones). Holes in vias or pads are ignored. The polygons are not merged.
* Useful to export the shape of copper layers to dxf polygons or 3D viewer
* @param aLayer = A copper layer, like B_Cu, etc.
* @param aOutlines The SHAPE_POLY_SET to fill in with items outline.
*/

View File

@ -128,8 +128,8 @@ void BOARD_ITEM::SwapData( BOARD_ITEM* aImage )
void BOARD_ITEM::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer,
int aClearanceValue, int aError,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth ) const
{
wxASSERT_MSG( false, "Called TransformShapeWithClearanceToPolygon() on unsupported BOARD_ITEM." );

View File

@ -349,8 +349,7 @@ public:
* when a full polygonal approach is needed
* @param aLayer = the layer to consider, or UNDEFINED_LAYER to consider all
* @param aCornerBuffer = the buffer to store polygons
* @param aInflateValue = an additionnal size to add to pad shapes
* aInflateValue = 0 to have the exact pad size
* @param aClearance = an additionnal size to add to pad shapes
* @param aMaxError = Maximum deviation from true for arcs
* @param aSkipNPTHPadsWihNoCopper = if true, do not add a NPTH pad shape, if the shape has
* same size and position as the hole. Usually, these pads are not drawn on copper
@ -361,8 +360,9 @@ public:
* @param aSkipPlatedPads = used on 3D-Viewer to extract plated and nontplated pads.
* @param aSkipNonPlatedPads = used on 3D-Viewer to extract plated and plated pads.
*/
void TransformPadsShapesWithClearanceToPolygon(PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aMaxError = ARC_HIGH_DEF,
void TransformPadsShapesWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer,int aClearance,
int aMaxError, ERROR_LOC aErrorLoc,
bool aSkipNPTHPadsWihNoCopper = false,
bool aSkipPlatedPads = false,
bool aSkipNonPlatedPads = false ) const;
@ -375,26 +375,28 @@ public:
* when a full polygonal approach is needed
* @param aLayer = the layer to consider, or UNDEFINED_LAYER to consider all
* @param aCornerBuffer = the buffer to store polygons
* @param aInflateValue = a value to inflate shapes
* aInflateValue = 0 to have the exact shape size
* @param aClearance = a value to inflate shapes
* @param aError = Maximum error between true arc and polygon approx
* @param aIncludeText = True to transform text shapes
* @param aIncludeEdges = True to transform module shapes
*/
void TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError = ARC_HIGH_DEF,
bool aIncludeText = true, bool aIncludeEdges = true ) const;
void TransformGraphicShapesWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc,
bool aIncludeText = true,
bool aIncludeEdges = true ) const;
/**
* @brief TransformGraphicTextWithClearanceToPolygonSet
* This function is the same as TransformGraphicShapesWithClearanceToPolygonSet
* but only generate text
*/
void TransformGraphicTextWithClearanceToPolygonSet( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError = ARC_HIGH_DEF ) const
void TransformGraphicTextWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc ) const
{
TransformGraphicShapesWithClearanceToPolygonSet( aLayer, aCornerBuffer, aInflateValue,
aError, true, false );
TransformGraphicShapesWithClearanceToPolygonSet( aCornerBuffer, aLayer, aClearance,
aError, aErrorLoc, true, false );
}
/**

View File

@ -287,6 +287,9 @@ int D_PAD::GetBoundingRadius() const
void D_PAD::BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const
{
BOARD* board = GetBoard();
int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF;
m_effectiveShape = std::make_shared<SHAPE_COMPOUND>();
m_effectiveHoleShape = nullptr;
@ -385,15 +388,10 @@ void D_PAD::BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const
case PAD_SHAPE_CHAMFERED_RECT:
{
SHAPE_POLY_SET outline;
auto board = GetBoard();
int maxError = ARC_HIGH_DEF;
if( board )
maxError = board->GetDesignSettings().m_MaxError;
TransformRoundChamferedRectToPolygon( outline, shapePos, GetSize(), m_orient,
GetRoundRectCornerRadius(), GetChamferRectRatio(),
GetChamferPositions(), maxError );
GetChamferPositions(), maxError, ERROR_INSIDE );
add( new SHAPE_SIMPLE( outline.COutline( 0 ) ) );
}
@ -421,7 +419,7 @@ void D_PAD::BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const
// Polygon
//
m_effectivePolygon = std::make_shared<SHAPE_POLY_SET>();
TransformShapeWithClearanceToPolygon( *m_effectivePolygon, aLayer, 0 );
TransformShapeWithClearanceToPolygon( *m_effectivePolygon, aLayer, 0, maxError, ERROR_INSIDE );
// Bounding box and radius
//

View File

@ -372,10 +372,12 @@ public:
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aMaxError = maximum error from true when converting arcs
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
* @param ignoreLineWidth = used for edge cuts where the line width is only for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer,
int aClearanceValue, int aMaxError = ARC_HIGH_DEF,
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aMaxError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth = false ) const override;
/**
@ -384,10 +386,11 @@ public:
* @param aCornerBuffer = a buffer to fill.
* @param aInflateValue = the clearance or margin value.
* @param aError = maximum deviation of an arc from the polygon approximation
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
* @return false if the pad has no hole, true otherwise
*/
bool TransformHoleWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aInflateValue,
int aError = ARC_HIGH_DEF ) const;
int aError, ERROR_LOC aErrorLoc ) const;
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
@ -634,7 +637,7 @@ public:
private:
void addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, PCB_LAYER_ID aLayer,
int aError ) const;
int aError, ERROR_LOC aErrorLoc ) const;
private:
wxString m_name; // Pad name (pin number in schematic)

View File

@ -164,8 +164,9 @@ public:
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer,
int aClearanceValue, int aError = ARC_HIGH_DEF,
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth = false ) const override;
// @copydoc BOARD_ITEM::GetEffectiveShape

View File

@ -386,8 +386,9 @@ public:
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer,
int aClearanceValue, int aError = ARC_HIGH_DEF,
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth = false ) const override;
/**

View File

@ -338,7 +338,8 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
// Output the outline perimeter as polygon.
if( graphic->GetShape() == S_CIRCLE )
{
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), aTolerance );
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(),
ARC_LOW_DEF, ERROR_INSIDE );
}
else if( graphic->GetShape() == S_RECT )
{

View File

@ -1146,8 +1146,8 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P
{
SHAPE_POLY_SET polySet;
const int corner_radius = aPad->GetRoundRectCornerRadius();
TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), aPad->GetSize(),
0.0, corner_radius, 0.0, 0, ARC_HIGH_DEF );
TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), aPad->GetSize(), 0.0,
corner_radius, 0.0, 0, ARC_HIGH_DEF, ERROR_INSIDE );
std::vector< wxRealPoint > cornerList;
// TransformRoundChamferedRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN poly( polySet.Outline( 0 ) );

View File

@ -173,12 +173,12 @@ void D_PAD::DeletePrimitivesList()
void D_PAD::addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, PCB_LAYER_ID aLayer,
int aError ) const
int aError, ERROR_LOC aErrorLoc ) const
{
SHAPE_POLY_SET polyset;
for( const std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
primitive->TransformShapeWithClearanceToPolygon( polyset, aLayer, 0, aError );
primitive->TransformShapeWithClearanceToPolygon( polyset, aLayer, 0, aError, aErrorLoc );
polyset.Simplify( SHAPE_POLY_SET::PM_FAST );
@ -192,11 +192,8 @@ void D_PAD::addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, PCB_LAYER
void D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon, PCB_LAYER_ID aLayer ) const
{
auto board = GetBoard();
int maxError = ARC_HIGH_DEF;
if( board )
maxError = board->GetDesignSettings().m_MaxError;
BOARD* board = GetBoard();
int maxError = board ? board->GetDesignSettings().m_MaxError: ARC_HIGH_DEF;
aMergedPolygon->RemoveAllContours();
@ -213,18 +210,19 @@ void D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon, PCB_LAYER_
default:
case PAD_SHAPE_CIRCLE:
TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, maxError );
TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, maxError,
ERROR_INSIDE );
break;
}
addPadPrimitivesToPolygon( aMergedPolygon, aLayer, maxError );
addPadPrimitivesToPolygon( aMergedPolygon, aLayer, maxError, ERROR_INSIDE );
}
bool D_PAD::GetBestAnchorPosition( VECTOR2I& aPos )
{
SHAPE_POLY_SET poly;
addPadPrimitivesToPolygon( &poly, UNDEFINED_LAYER, ARC_LOW_DEF );
addPadPrimitivesToPolygon( &poly, UNDEFINED_LAYER, ARC_LOW_DEF, ERROR_INSIDE );
if( poly.OutlineCount() > 1 )
return false;

View File

@ -186,7 +186,8 @@ static void insideCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
SHAPE_POLY_SET testPoly;
item->TransformShapeWithClearanceToPolygon( testPoly, context->GetLayer(), 0 );
item->TransformShapeWithClearanceToPolygon( testPoly, context->GetLayer(), 0,
ARC_LOW_DEF, ERROR_INSIDE );
testPoly.BooleanIntersection( footprintCourtyard, SHAPE_POLY_SET::PM_FAST );
if( testPoly.OutlineCount() )
@ -242,7 +243,8 @@ static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
{
SHAPE_POLY_SET testPoly;
item->TransformShapeWithClearanceToPolygon( testPoly, context->GetLayer(), 0 );
item->TransformShapeWithClearanceToPolygon( testPoly, context->GetLayer(), 0,
ARC_LOW_DEF, ERROR_INSIDE );
testPoly.BooleanIntersection( *zone->Outline(), SHAPE_POLY_SET::PM_FAST );
if( testPoly.OutlineCount() )

View File

@ -858,6 +858,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
}
// Pad drawing
BOARD_DESIGN_SETTINGS& bds = aPad->GetBoard()->GetDesignSettings();
COLOR4D color;
// Pad hole color is pad-type-specific: the background color for plated holes and the
@ -947,7 +948,8 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
else
{
SHAPE_POLY_SET polySet;
aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ), margin.x );
aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ), margin.x,
bds.m_MaxError, ERROR_INSIDE );
m_gal->DrawPolygon( polySet );
}
@ -991,13 +993,14 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
{
SHAPE_POLY_SET polySet;
aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ),
clearance );
clearance,
bds.m_MaxError, ERROR_OUTSIDE );
m_gal->DrawPolygon( polySet );
}
}
else if( aPad->GetEffectiveHoleShape() )
{
clearance += aPad->GetBoard()->GetDesignSettings().GetHolePlatingThickness();
clearance += bds.GetHolePlatingThickness();
const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,

View File

@ -311,8 +311,9 @@ public:
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer,
int aClearanceValue, int aError = ARC_HIGH_DEF,
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
PCB_LAYER_ID aLayer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth = false ) const override;
virtual wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;

View File

@ -116,11 +116,11 @@ public:
* Used in 3D viewer
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the text
* @param aClearance = the clearance around the text
* @param aError = deviation from true arc position to segment approx
*/
void TransformShapeWithClearanceToPolygonSet(
SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError = ARC_HIGH_DEF ) const;
void TransformShapeWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerBuffer, int aClearance,
int aError, ERROR_LOC aErrorLoc ) const;
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;

View File

@ -756,6 +756,7 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
const PCB_PLOT_PARAMS& aPlotOpt, int aMinThickness )
{
int maxError = aBoard->GetDesignSettings().m_MaxError;
PCB_LAYER_ID layer = aLayerMask[B_Mask] ? B_Mask : F_Mask;
SHAPE_POLY_SET buffer;
SHAPE_POLY_SET* boardOutline = nullptr;
@ -763,10 +764,6 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
if( aBoard->GetBoardPolygonOutlines( buffer ) )
boardOutline = &buffer;
// Set the current arc to segment max approx error
int currMaxError = aBoard->GetDesignSettings().m_MaxError;
aBoard->GetDesignSettings().m_MaxError = Millimeter2iu( 0.005 );
// We remove 1nm as we expand both sides of the shapes, so allowing for
// a strictly greater than or equal comparison in the shape separation (boolean add)
// means that we will end up with separate shapes that then are shrunk
@ -814,9 +811,11 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
for( MODULE* module : aBoard->Modules() )
{
// add shapes with their exact mask layer size in initialPolys
module->TransformPadsShapesWithClearanceToPolygon( layer, initialPolys, 0 );
module->TransformPadsShapesWithClearanceToPolygon( initialPolys, layer, 0, maxError,
ERROR_OUTSIDE );
// add shapes inflated by aMinThickness/2 in areas
module->TransformPadsShapesWithClearanceToPolygon( layer, areas, inflate );
module->TransformPadsShapesWithClearanceToPolygon( areas, layer, inflate, maxError,
ERROR_OUTSIDE );
}
// Plot vias on solder masks, if aPlotOpt.GetPlotViaOnMaskLayer() is true,
@ -846,9 +845,11 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
continue;
// add shapes with their exact mask layer size in initialPolys
via->TransformShapeWithClearanceToPolygon( initialPolys, layer, via_clearance );
via->TransformShapeWithClearanceToPolygon( initialPolys, layer, via_clearance,
maxError, ERROR_OUTSIDE );
// add shapes inflated by aMinThickness/2 in areas
via->TransformShapeWithClearanceToPolygon( areas, layer, via_margin );
via->TransformShapeWithClearanceToPolygon( areas, layer, via_margin, maxError,
ERROR_OUTSIDE );
}
}
@ -870,16 +871,12 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
zone->TransformSmoothedOutlineToPolygon( initialPolys, zone_margin, boardOutline );
}
int maxError = aBoard->GetDesignSettings().m_MaxError;
int numSegs = GetArcToSegmentCount( inflate, maxError, 360.0 );
// Merge all polygons: After deflating, not merged (not overlapping) polygons
// will have the initial shape (with perhaps small changes due to deflating transform)
areas.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
areas.Deflate( inflate, numSegs );
// Restore initial settings:
aBoard->GetDesignSettings().m_MaxError = currMaxError;
}
#if !NEW_ALGO

View File

@ -1541,7 +1541,7 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
zone->SetDoNotAllowCopperPour( true );
shape.TransformShapeWithClearanceToPolygon( *zone->Outline(), klayer, 0, ARC_HIGH_DEF,
false );
ERROR_INSIDE );
zone->Outline()->Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); // the outline is not a single polygon!
zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
@ -2094,7 +2094,7 @@ void ALTIUM_PCB::ParseTracks6Data( const CFB::CompoundFileReader& aReader,
zone->SetDoNotAllowCopperPour( true );
shape.TransformShapeWithClearanceToPolygon( *zone->Outline(), klayer, 0, ARC_HIGH_DEF,
false );
ERROR_INSIDE );
zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
ZONE_CONTAINER::GetDefaultHatchPitch(), true );

View File

@ -487,7 +487,8 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
0, rradius,
aPad->GetChamferRectRatio(),
doChamfer ? aPad->GetChamferPositions() : 0,
aBoard->GetDesignSettings().m_MaxError );
aBoard->GetDesignSettings().m_MaxError,
ERROR_INSIDE );
SHAPE_LINE_CHAIN& polygonal_shape = cornerBuffer.Outline( 0 );
for( int ndx=0; ndx < reportedLayers; ++ndx )

View File

@ -613,10 +613,14 @@ PCB_LAYER_ID PAD_TOOL::explodePad( D_PAD* aPad )
void PAD_TOOL::recombinePad( D_PAD* aPad )
{
auto findNext = [&]( PCB_LAYER_ID aLayer ) -> FP_SHAPE*
int maxError = board()->GetDesignSettings().m_MaxError;
auto findNext =
[&]( PCB_LAYER_ID aLayer ) -> FP_SHAPE*
{
SHAPE_POLY_SET padPoly;
aPad->TransformShapeWithClearanceToPolygon( padPoly, aLayer, 0 );
aPad->TransformShapeWithClearanceToPolygon( padPoly, aLayer, 0, maxError,
ERROR_INSIDE );
for( BOARD_ITEM* item : board()->GetFirstModule()->GraphicalItems() )
{
@ -629,7 +633,8 @@ void PAD_TOOL::recombinePad( D_PAD* aPad )
continue;
SHAPE_POLY_SET drawPoly;
draw->TransformShapeWithClearanceToPolygon( drawPoly, aLayer, 0 );
draw->TransformShapeWithClearanceToPolygon( drawPoly, aLayer, 0, maxError,
ERROR_INSIDE );
drawPoly.BooleanIntersection( padPoly, SHAPE_POLY_SET::PM_FAST );
if( !drawPoly.IsEmpty() )
@ -666,7 +671,8 @@ void PAD_TOOL::recombinePad( D_PAD* aPad )
// to a polygon primitive
SHAPE_POLY_SET existingOutline;
int maxError = board()->GetDesignSettings().m_MaxError;
aPad->TransformShapeWithClearanceToPolygon( existingOutline, layer, 0, maxError );
aPad->TransformShapeWithClearanceToPolygon( existingOutline, layer, 0, maxError,
ERROR_INSIDE );
aPad->SetAnchorPadShape( PAD_SHAPE_CIRCLE );
wxSize minAnnulus( Millimeter2iu( 0.2 ), Millimeter2iu( 0.2 ) );

View File

@ -342,7 +342,8 @@ void TRACKS_CLEANER::deleteTracksInPads()
if( pad->HitTest( track->GetStart() ) && pad->HitTest( track->GetEnd() ) )
{
SHAPE_POLY_SET poly;
track->TransformShapeWithClearanceToPolygon( poly, track->GetLayer(), 0 );
track->TransformShapeWithClearanceToPolygon( poly, track->GetLayer(), 0,
ARC_HIGH_DEF, ERROR_INSIDE );
poly.BooleanSubtract( *pad->GetEffectivePolygon(), SHAPE_POLY_SET::PM_FAST );

View File

@ -577,7 +577,8 @@ void ZONE_FILLER::addKnockout( D_PAD* aPad, PCB_LAYER_ID aLayer, int aGap, SHAPE
if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
{
SHAPE_POLY_SET poly;
aPad->TransformShapeWithClearanceToPolygon( poly, aLayer, aGap, m_maxError );
aPad->TransformShapeWithClearanceToPolygon( poly, aLayer, aGap, m_maxError,
ERROR_OUTSIDE );
// the pad shape in zone can be its convex hull or the shape itself
if( aPad->GetCustomShapeInZoneOpt() == CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL )
@ -595,7 +596,8 @@ void ZONE_FILLER::addKnockout( D_PAD* aPad, PCB_LAYER_ID aLayer, int aGap, SHAPE
}
else
{
aPad->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError );
aPad->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError,
ERROR_OUTSIDE );
}
}
@ -613,7 +615,7 @@ void ZONE_FILLER::addKnockout( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int aGap,
{
PCB_SHAPE* shape = (PCB_SHAPE*) aItem;
shape->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError,
aIgnoreLineWidth );
ERROR_OUTSIDE, aIgnoreLineWidth );
break;
}
case PCB_TEXT_T:
@ -626,7 +628,7 @@ void ZONE_FILLER::addKnockout( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int aGap,
{
FP_SHAPE* shape = (FP_SHAPE*) aItem;
shape->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError,
aIgnoreLineWidth );
ERROR_OUTSIDE, aIgnoreLineWidth );
break;
}
case PCB_FP_TEXT_T:
@ -790,16 +792,19 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE_CONTAINER* aZone, PCB_LA
if( !via->FlashLayer( aLayer ) )
{
int radius = via->GetDrillValue() / 2 + bds.GetHolePlatingThickness() + gap;
TransformCircleToPolygon( aHoles, via->GetPosition(), radius, m_maxError );
TransformCircleToPolygon( aHoles, via->GetPosition(), radius, m_maxError,
ERROR_OUTSIDE );
}
else
{
via->TransformShapeWithClearanceToPolygon( aHoles, aLayer, gap, m_maxError );
via->TransformShapeWithClearanceToPolygon( aHoles, aLayer, gap, m_maxError,
ERROR_OUTSIDE );
}
}
else
{
track->TransformShapeWithClearanceToPolygon( aHoles, aLayer, gap, m_maxError );
track->TransformShapeWithClearanceToPolygon( aHoles, aLayer, gap, m_maxError,
ERROR_OUTSIDE );
}
}
}
@ -872,7 +877,9 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE_CONTAINER* aZone, PCB_LA
{
// 6.0 uses filled areas with clearance
SHAPE_POLY_SET poly;
aKnockout->TransformShapeWithClearanceToPolygon( poly, aLayer, gap );
aKnockout->TransformShapeWithClearanceToPolygon( poly, aLayer, gap,
m_maxError,
ERROR_OUTSIDE );
aHoles.Append( poly );
}
}
@ -1448,7 +1455,8 @@ void ZONE_FILLER::addHatchFillTypeOnZone( const ZONE_CONTAINER* aZone, PCB_LAYER
int r = std::max( min_apron_radius,
via->GetDrillValue() / 2 + outline_margin );
TransformCircleToPolygon( aprons, via->GetPosition(), r, ARC_HIGH_DEF );
TransformCircleToPolygon( aprons, via->GetPosition(), r, ARC_HIGH_DEF,
ERROR_OUTSIDE );
}
}
}
@ -1474,7 +1482,7 @@ void ZONE_FILLER::addHatchFillTypeOnZone( const ZONE_CONTAINER* aZone, PCB_LAYER
clearance = std::max( 0, clearance - linethickness / 2 );
pad->TransformShapeWithClearanceToPolygon( aprons, aLayer, clearance,
ARC_HIGH_DEF );
ARC_HIGH_DEF, ERROR_OUTSIDE );
}
}
}

View File

@ -45,7 +45,8 @@ void process( const BOARD_CONNECTED_ITEM* item, int net )
SHAPE_POLY_SET pset;
item->TransformShapeWithClearanceToPolygon( pset, UNDEFINED_LAYER, 1, ARC_HIGH_DEF );
item->TransformShapeWithClearanceToPolygon( pset, UNDEFINED_LAYER, 1, ARC_HIGH_DEF,
ERROR_OUTSIDE );
SHAPE_FILE_IO shapeIo; // default = stdout
shapeIo.Write( &pset );