Moving further arc approximations down

This corrects an issue with fill segments-per-circle and moves the error
to segmetns calculation down in a number of functions to expose the
single value for approximation
This commit is contained in:
Seth Hillbrand 2019-05-22 06:33:48 -07:00
parent 323ecada8d
commit ac435ecd68
23 changed files with 150 additions and 257 deletions

View File

@ -502,7 +502,7 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
int corner_radius = aPad->GetRoundRectCornerRadius( shapesize );
TransformRoundChamferedRectToPolygon( polyList, PadShapePos, shapesize, aPad->GetOrientation(),
corner_radius, aPad->GetChamferRectRatio(),
aPad->GetChamferPositions(), 32 );
aPad->GetChamferPositions(), ARC_HIGH_DEF );
// Add the PAD polygon
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits, *aPad );

View File

@ -414,15 +414,11 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
const int holediameter = via->GetDrillValue();
const int hole_outer_radius = (holediameter / 2) + GetCopperThicknessBIU();
TransformCircleToPolygon( *layerOuterHolesPoly,
via->GetStart(),
hole_outer_radius,
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
TransformCircleToPolygon( *layerOuterHolesPoly, via->GetStart(),
hole_outer_radius, ARC_HIGH_DEF );
TransformCircleToPolygon( *layerInnerHolesPoly,
via->GetStart(),
holediameter / 2,
GetNrSegmentsCircle( holediameter ) );
TransformCircleToPolygon( *layerInnerHolesPoly, via->GetStart(),
holediameter / 2, ARC_HIGH_DEF );
}
else if( lIdx == 0 ) // it only adds once the THT holes
{
@ -431,22 +427,16 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
// Add through hole contourns
// /////////////////////////////////////////////////////////
TransformCircleToPolygon( m_through_outer_holes_poly,
via->GetStart(),
hole_outer_radius,
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
TransformCircleToPolygon( m_through_outer_holes_poly, via->GetStart(),
hole_outer_radius, ARC_HIGH_DEF );
TransformCircleToPolygon( m_through_inner_holes_poly,
via->GetStart(),
holediameter / 2,
GetNrSegmentsCircle( holediameter ) );
TransformCircleToPolygon( m_through_inner_holes_poly, via->GetStart(),
holediameter / 2, ARC_HIGH_DEF );
// Add samething for vias only
TransformCircleToPolygon( m_through_outer_holes_vias_poly,
via->GetStart(),
hole_outer_radius,
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
TransformCircleToPolygon( m_through_outer_holes_vias_poly, via->GetStart(),
hole_outer_radius, ARC_HIGH_DEF );
//TransformCircleToPolygon( m_through_inner_holes_vias_poly,
// via->GetStart(),

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -111,11 +111,8 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
{
if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // Draw a ring
{
unsigned int nr_sides_per_circle = GetNrSegmentsCircle( ( aPad->GetSize().x / 2 +
aWidth / 2 ) * 2 );
TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(),
aPad->GetSize().x / 2, nr_sides_per_circle, aWidth );
aPad->GetSize().x / 2, ARC_HIGH_DEF, aWidth );
return;
}
@ -123,8 +120,6 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
// For other shapes, draw polygon outlines
SHAPE_POLY_SET corners;
auto nr_sides_per_circle =
GetNrSegmentsCircle( std::min( aPad->GetSize().x, aPad->GetSize().y ) );
buildPadShapePolygon( aPad, corners, wxSize( 0, 0 ) );
// Add outlines as thick segments in polygon buffer
@ -136,11 +131,8 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
const VECTOR2I& a = path.CPoint( ii );
const VECTOR2I& b = path.CPoint( ii + 1 );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
wxPoint( a.x, a.y ),
wxPoint( b.x, b.y ),
nr_sides_per_circle,
aWidth );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ),
wxPoint( b.x, b.y ), ARC_HIGH_DEF, aWidth );
}
}

View File

@ -5,7 +5,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,28 +31,23 @@
#include <macros.h>
#include <common.h>
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/geometry_utils.h>
/**
* Function TransformCircleToPolygon
* convert a circle to a polygon, using multiple straight lines
* @param aBuffer = a SHAPE_LINE_CHAIN to store the polygon corners
* @param aCenter = the center of the circle
* @param aRadius = the radius of the circle
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* 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
*/
void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aBuffer,
wxPoint aCenter, int aRadius,
int aCircleToSegmentsCount )
int aError )
{
wxPoint corner_position;
double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
double halfstep = delta/2; // the starting value for rot angles
int numSegs = std::max( GetArcToSegmentCount( aRadius, aError, 360.0 ), 6 );
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int radius = aRadius * correction; // make segments outside the circles
double halfstep = delta/2; // the starting value for rot angles
for( int ii = 0; ii < aCircleToSegmentsCount; ii++ )
for( int ii = 0; ii < numSegs; ii++ )
{
corner_position.x = aRadius;
corner_position.x = radius;
corner_position.y = 0;
double angle = (ii * delta) + halfstep;
RotatePoint( &corner_position, angle );
@ -64,29 +59,22 @@ void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aBuffer,
}
/**
* Function TransformCircleToPolygon
* convert a circle to a polygon, using multiple straight lines
* @param aCornerBuffer = a SHAPE_POLY_SET to store the polygon
* @param aCenter = the center of the circle
* @param aRadius = the radius of the circle
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* 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
*/
void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aCenter, int aRadius,
int aCircleToSegmentsCount )
int aError )
{
wxPoint corner_position;
double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
double halfstep = delta/2; // the starting value for rot angles
int numSegs = std::max( GetArcToSegmentCount( aRadius, aError, 360.0 ), 6 );
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int radius = aRadius * correction; // make segments outside the circles
double halfstep = delta/2; // the starting value for rot angles
aCornerBuffer.NewOutline();
for( int ii = 0; ii < aCircleToSegmentsCount; ii++ )
for( int ii = 0; ii < numSegs; ii++ )
{
corner_position.x = aRadius;
corner_position.x = radius;
corner_position.y = 0;
double angle = (ii * delta) + halfstep;
RotatePoint( &corner_position, angle );
@ -95,9 +83,10 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
}
}
void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aStart, wxPoint aEnd, int aWidth,
int aCircleToSegmentsCount, double aCorrectionFactor )
wxPoint aStart, wxPoint aEnd, int aWidth,
int aError )
{
// To build the polygonal shape outside the actual shape, we use a bigger
// radius to build rounded ends.
@ -105,13 +94,11 @@ void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
// so, later, we will clamp the polygonal shape with the bounding box
// of the segment.
int radius = aWidth / 2;
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
double correction = GetCircletoPolyCorrectionFactor( numSegs );
// Note if we want to compensate the radius reduction of a circle due to
// the segment approx, aCorrectionFactor must be calculated like this:
// For a circle the min radius is radius * cos( 2PI / s_CircleToSegmentsCount / 2)
// aCorrectionFactor is 1 /cos( PI/s_CircleToSegmentsCount )
radius = radius * aCorrectionFactor; // make segments outside the circles
radius = radius * correction; // make segments outside the circles
// end point is the coordinate relative to aStart
wxPoint endp = aEnd - aStart;
@ -133,17 +120,16 @@ void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
double delta_angle = atan2( (double)endp.y, (double)endp.x );
int seg_len = KiROUND( EuclideanNorm( endp ) );
double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
// Compute the outlines of the segment, and creates a polygon
// Note: the polygonal shape is built from the equivalent horizontal
// segment starting ar 0,0, and ending at seg_len,0
// add right rounded end:
for( int ii = 0; ii < aCircleToSegmentsCount/2; ii++ )
for( int ii = 0; ii < numSegs / 2; ii++ )
{
corner = wxPoint( 0, radius );
RotatePoint( &corner, delta*ii );
RotatePoint( &corner, delta * ii );
corner.x += seg_len;
polyshape.Append( corner.x, corner.y );
}
@ -153,10 +139,10 @@ void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
polyshape.Append( corner.x, corner.y );
// add left rounded end:
for( int ii = 0; ii < aCircleToSegmentsCount/2; ii++ )
for( int ii = 0; ii < numSegs / 2; ii++ )
{
corner = wxPoint( 0, -radius );
RotatePoint( &corner, delta*ii );
RotatePoint( &corner, delta * ii );
polyshape.Append( corner.x, corner.y );
}
@ -167,7 +153,7 @@ void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
// Now, clamp the polygonal shape (too big) with the segment bounding box
// the polygonal shape bbox equivalent to the segment has a too big height,
// and the right width
if( aCorrectionFactor > 1.0 )
if( correction > 1.0 )
{
SHAPE_POLY_SET bbox;
bbox.NewOutline();
@ -197,8 +183,7 @@ void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
aCornerBuffer.Append( polyshape);
}
/* Returns the centers of the rounded corners of a rect.
*/
void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
const wxPoint& aPosition, const wxSize& aSize, double aRotation )
{
@ -243,7 +228,7 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
const wxPoint& aPosition, const wxSize& aSize,
double aRotation, int aCornerRadius,
double aChamferRatio, int aChamferCorners,
int aCircleToSegmentsCount )
int aError )
{
// Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
// or in actual position/orientation for round rect only
@ -258,7 +243,8 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
for( int ii = 0; ii < 4; ++ii )
outline.Append( corners[ii].x, corners[ii].y );
outline.Inflate( aCornerRadius, aCircleToSegmentsCount );
int numSegs = std::max( GetArcToSegmentCount( aCornerRadius, aError, 360.0 ), 6 );
outline.Inflate( aCornerRadius, numSegs );
if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
{
@ -299,9 +285,9 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
chamfered_corner.RemoveAllContours();
chamfered_corner.NewOutline();
chamfered_corner.Append( 0, 0 );
chamfered_corner.Append( 0, signY[ii]*aSize.y/2 );
chamfered_corner.Append( signX[ii]*aSize.x/2, signY[ii]*aSize.y/2 );
chamfered_corner.Append( signX[ii]*aSize.x/2, 0 );
chamfered_corner.Append( 0, signY[ii] * aSize.y / 2 );
chamfered_corner.Append( signX[ii] * aSize.x / 2, signY[ii] * aSize.y / 2 );
chamfered_corner.Append( signX[ii] * aSize.x / 2, 0 );
chamfered_corner.Move( corner_pos );
outline.BooleanAdd( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
}
@ -310,8 +296,8 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
chamfered_corner.RemoveAllContours();
chamfered_corner.NewOutline();
chamfered_corner.Append( 0, 0 );
chamfered_corner.Append( 0, signY[ii]*chamfer_value );
chamfered_corner.Append( signX[ii]*chamfer_value, 0 );
chamfered_corner.Append( 0, signY[ii] * chamfer_value );
chamfered_corner.Append( signX[ii] * chamfer_value, 0 );
chamfered_corner.Move( corner_pos );
outline.BooleanSubtract( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
}
@ -327,29 +313,20 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
}
/**
* Function TransformRoundedEndsSegmentToPolygon
* convert a segment with rounded ends to a polygon
* Convert arcs to multiple straight lines
* @param aCornerBuffer = a buffer to store the polygon
* @param aStart = the segment start point coordinate
* @param aEnd = the segment end point coordinate
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aWidth = the segment width
* Note: the polygon is inside the arc ends, so if you want to have the polygon
* outside the circle, you should give aStart and aEnd calculated with a correction factor
*/
void TransformRoundedEndsSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aStart, wxPoint aEnd,
int aCircleToSegmentsCount,
int aWidth )
int aError, int aWidth )
{
int radius = aWidth / 2;
wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
wxPoint startp = aStart;
wxPoint corner;
int radius = aWidth / 2;
wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
wxPoint startp = aStart;
wxPoint corner;
VECTOR2I polypoint;
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
radius = KiROUND( radius * correction );
aCornerBuffer.NewOutline();
// normalize the position in order to have endp.x >= 0;
@ -362,8 +339,6 @@ void TransformRoundedEndsSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer,
double delta_angle = ArcTangente( endp.y, endp.x ); // delta_angle is in 0.1 degrees
int seg_len = KiROUND( EuclideanNorm( endp ) );
int delta = 3600 / aCircleToSegmentsCount; // rot angle in 0.1 degree
// Compute the outlines of the segment, and creates a polygon
// add right rounded end:
for( int ii = 0; ii < 1800; ii += delta )
@ -408,23 +383,14 @@ void TransformRoundedEndsSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer,
}
/**
* Function TransformArcToPolygon
* Creates a polygon from an Arc
* Convert arcs to multiple straight segments
* @param aCornerBuffer = a buffer to store the polygon
* @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 aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aWidth = width (thickness) of the line
*/
void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aCentre, wxPoint aStart, double aArcAngle,
int aCircleToSegmentsCount, int aWidth )
int aError, int aWidth )
{
wxPoint arc_start, arc_end;
int delta = 3600 / aCircleToSegmentsCount; // rotate angle in 0.1 degree
int dist = EuclideanNorm( aCentre - aStart );
int numSegs = std::max( GetArcToSegmentCount( dist, aError, 360.0 ), 6 );
int delta = 3600 / numSegs; // rotate angle in 0.1 degree
arc_end = arc_start = aStart;
@ -447,31 +413,19 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
{
curr_end = arc_start;
RotatePoint( &curr_end, aCentre, -ii );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_start, curr_end,
aCircleToSegmentsCount, aWidth );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_start, curr_end, aError,
aWidth );
curr_start = curr_end;
}
if( curr_end != arc_end )
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
curr_end, arc_end,
aCircleToSegmentsCount, aWidth );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_end, arc_end, aError, aWidth );
}
/**
* Function TransformRingToPolygon
* Creates a polygon from a ring
* Convert arcs to multiple straight segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aCentre = centre of the arc or circle
* @param aRadius = radius of the circle
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aWidth = width (thickness) of the ring
*/
void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aCentre, int aRadius,
int aCircleToSegmentsCount, int aWidth )
int aError, int aWidth )
{
// Compute the corners positions and creates the poly
wxPoint curr_point;
@ -480,18 +434,17 @@ void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer,
if( inner_radius <= 0 )
{ //In this case, the ring is just a circle (no hole inside)
TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ),
aCircleToSegmentsCount );
TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ), aError );
return;
}
SHAPE_POLY_SET buffer;
TransformCircleToPolygon( buffer, aCentre, outer_radius, aCircleToSegmentsCount );
TransformCircleToPolygon( buffer, aCentre, outer_radius, aError );
// Build the hole:
buffer.NewHole();
TransformCircleToPolygon( buffer.Hole( 0, 0 ), aCentre, inner_radius, aCircleToSegmentsCount );
TransformCircleToPolygon( buffer.Hole( 0, 0 ), aCentre, inner_radius, aError );
buffer.Fracture( SHAPE_POLY_SET::PM_FAST );
aCornerBuffer.Append( buffer );

View File

@ -496,7 +496,6 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
// polygon and its thick outline
SHAPE_POLY_SET bufferOutline;
SHAPE_POLY_SET bufferPolybase;
const int circleToSegmentsCount = 16;
bufferPolybase.NewOutline();
@ -504,7 +503,7 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
{
TransformRoundedEndsSegmentToPolygon( bufferOutline,
aCornerList[ii-1], aCornerList[ii], circleToSegmentsCount, aWidth );
aCornerList[ii-1], aCornerList[ii], GetPlotterArcHighDef(), aWidth );
}
// enter the initial polygon:
@ -591,7 +590,7 @@ void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int
std::vector<wxPoint> cornerList;
SHAPE_POLY_SET outlineBuffer;
TransformOvalClearanceToPolygon( outlineBuffer,
aStart, aEnd, aWidth, 32 , 1.0 );
aStart, aEnd, aWidth, GetPlotterArcHighDef() );
const SHAPE_LINE_CHAIN& path = outlineBuffer.COutline(0 );
for( int jj = 0; jj < path.PointCount(); jj++ )
@ -748,7 +747,7 @@ void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
aCornerRadius, 0.0, 0, segmentToCircleCount );
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );

View File

@ -841,9 +841,8 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
// Currently, a Pad RoundRect is plotted as polygon.
// TODO: use Aperture macro and flash it
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
aCornerRadius, 0.0, 0, segmentToCircleCount );
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
if( aTraceMode != FILLED )
outline.Inflate( -GetCurrentLineWidth()/2, 16 );

View File

@ -625,7 +625,6 @@ void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSiz
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 32;
wxSize size = aSize;
@ -643,11 +642,10 @@ void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSiz
}
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
aCornerRadius, 0.0, 0, segmentToCircleCount );
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
// TransformRoundRectToPolygon creates only one convex polygon
std::vector< wxPoint > cornerList;
cornerList.reserve( segmentToCircleCount + 5 );
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
for( int ii = 0; ii < poly.PointCount(); ++ii )

View File

@ -200,12 +200,10 @@ void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
aCornerRadius, 0.0, 0, segmentToCircleCount );
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
std::vector< wxPoint > cornerList;
cornerList.reserve( segmentToCircleCount + 5 );
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );

View File

@ -7,7 +7,7 @@
*
* Copyright (C) 1992-2017 Jean-Pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,6 +31,7 @@
#include <common.h>
#include <macros.h>
#include <trigo.h>
#include <convert_to_biu.h>
#include <convert_basic_shapes_to_polygon.h>
#include <gr_basic.h>
@ -92,6 +93,7 @@ bool AM_PRIMITIVE::IsAMPrimitiveExposureOn( const GERBER_DRAW_ITEM* aParent ) co
}
}
// TODO(snh): Remove hard coded count
const int seg_per_circle = 64; // Number of segments to approximate a circle
void AM_PRIMITIVE::DrawBasicShape( const GERBER_DRAW_ITEM* aParent,
@ -313,13 +315,11 @@ 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, seg_per_circle );
TransformCircleToPolygon( aShapeBuffer, center, outerDiam / 2, ARC_HIGH_DEF );
}
else
TransformRingToPolygon( aShapeBuffer, center,
(outerDiam - penThickness) / 2,
seg_per_circle, penThickness );
TransformRingToPolygon( aShapeBuffer, center, ( outerDiam - penThickness ) / 2,
ARC_HIGH_DEF, penThickness );
}
// Draw the cross:

View File

@ -289,7 +289,7 @@ void D_CODE::DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent,
GRClosedPoly( aClipBox, aDC, pointCount, &points[0], aFilled, aColor, aColor );
}
// TODO(snh): Remove the hard-coded count
#define SEGS_CNT 64 // number of segments to approximate a circle
@ -310,7 +310,7 @@ 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, SEGS_CNT );
TransformCircleToPolygon( m_Polygon, initialpos, m_Size.x >> 1, ARC_HIGH_DEF );
addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
break;
@ -435,7 +435,7 @@ static void addHoleToPolygon( SHAPE_POLY_SET* aPolygon,
if( aHoleShape == APT_DEF_ROUND_HOLE )
{
TransformCircleToPolygon( holeBuffer, wxPoint( 0, 0 ), aSize.x / 2, SEGS_CNT );
TransformCircleToPolygon( holeBuffer, wxPoint( 0, 0 ), aSize.x / 2, ARC_HIGH_DEF );
}
else if( aHoleShape == APT_DEF_RECT_HOLE )
{

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 1992-2019 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -59,13 +59,13 @@ enum RECT_CHAMFER_POSITIONS : int
* @param aCornerBuffer = a buffer to store the polygon
* @param aCenter = the center of the circle
* @param aRadius = the radius of the circle
* @param aCircleToSegmentsCount = the number of segments to approximate a 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
*/
void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aCenter, int aRadius,
int aCircleToSegmentsCount );
int aError );
/**
@ -80,14 +80,11 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
* @param aStart = the first point of the segment
* @param aEnd = the second point of the segment
* @param aWidth = the width of the segment
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the coefficient to have segments outside the circle
* if aCorrectionFactor = 1.0, the shape will be the same as
* TransformRoundedEndsSegmentToPolygon
* @param aError = the IU allowed for error in approximation
*/
void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aStart, wxPoint aEnd, int aWidth,
int aCircleToSegmentsCount, double aCorrectionFactor );
int aError );
/**
@ -120,13 +117,13 @@ void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
* 4 = BOTTOM_LEFT
* 8 = BOTTOM_RIGHT
* One can have more than one chamfered corner by ORing the corner identifers
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aError = the IU allowed for error in approximation
*/
void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
const wxPoint& aPosition, const wxSize& aSize,
double aRotation, int aCornerRadius,
double aChamferRatio, int aChamferCorners,
int aCircleToSegmentsCount );
int aError );
/**
* Function TransformRoundedEndsSegmentToPolygon
@ -135,14 +132,14 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
* @param aCornerBuffer = a buffer to store the polygon
* @param aStart = the segment start point coordinate
* @param aEnd = the segment end point coordinate
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aError = the IU allowed for error in approximation
* @param aWidth = the segment width
* Note: the polygon is inside the arc ends, so if you want to have the polygon
* outside the circle, you should give aStart and aEnd calculated with a correction factor
*/
void TransformRoundedEndsSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aStart, wxPoint aEnd,
int aCircleToSegmentsCount,
int aError,
int aWidth );
@ -154,12 +151,12 @@ void TransformRoundedEndsSegmentToPolygon( 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 aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aError = the IU allowed for error in approximation
* @param aWidth = width (thickness) of the line
*/
void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aCentre, wxPoint aStart, double aArcAngle,
int aCircleToSegmentsCount, int aWidth );
int aError, int aWidth );
/**
* Function TransformRingToPolygon
@ -168,11 +165,11 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
* @param aCornerBuffer = a buffer to store the polygon
* @param aCentre = centre of the arc or circle
* @param aRadius = radius of the circle
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aError = the IU allowed for error in approximation
* @param aWidth = width (thickness) of the ring
*/
void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aCentre, int aRadius,
int aCircleToSegmentsCount, int aWidth );
int aError, int aWidth );
#endif // CONVERT_BASIC_SHAPES_TO_POLYGON_H

View File

@ -216,6 +216,9 @@ public:
*/
double GetIUsPerDecimil() const { return m_IUsPerDecimil; }
int GetPlotterArcLowDef() const { return m_IUsPerDecimil * 8; }
int GetPlotterArcHighDef() const { return m_IUsPerDecimil * 2; }
// Low level primitives
virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
int width = USE_DEFAULT_LINE_WIDTH ) = 0;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009-2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -56,7 +56,7 @@
// so we cannot send them as arguments.
struct TSEGM_2_POLY_PRMS {
int m_textWidth;
int m_textCircle2SegmentCount;
int m_error;
SHAPE_POLY_SET* m_cornerBuffer;
};
TSEGM_2_POLY_PRMS prms;
@ -67,7 +67,7 @@ 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 );
TransformRoundedEndsSegmentToPolygon( *prm->m_cornerBuffer,
wxPoint( x0, y0), wxPoint( xf, yf ),
prm->m_textCircle2SegmentCount, prm->m_textWidth );
prm->m_error, prm->m_textWidth );
}
@ -244,8 +244,7 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLaye
{
TEXTE_MODULE *textmod = texts[ii];
prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
prms.m_textCircle2SegmentCount =
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
prms.m_error = aError;
wxSize size = textmod->GetTextSize();
if( textmod->IsMirrored() )
@ -304,8 +303,7 @@ void MODULE::TransformGraphicTextWithClearanceToPolygonSet(
{
TEXTE_MODULE *textmod = texts[ii];
prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
prms.m_textCircle2SegmentCount =
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
prms.m_error = aError;
wxSize size = textmod->GetTextSize();
if( textmod->IsMirrored() )
@ -327,8 +325,6 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
if( GetFilledPolysList().IsEmpty() )
return;
int numSegs = std::max( GetArcToSegmentCount( GetMinThickness() / 2, aError, 360.0 ), 6 );
// add filled areas polygons
aCornerBuffer.Append( m_FilledPolysList );
@ -343,7 +339,7 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
const VECTOR2I& b = path.CPoint( j + 1 );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ),
wxPoint( b.x, b.y ), numSegs, GetMinThickness() );
wxPoint( b.x, b.y ), ARC_HIGH_DEF, GetMinThickness() );
}
}
}
@ -405,8 +401,7 @@ void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
prms.m_cornerBuffer = &aCornerBuffer;
prms.m_textWidth = GetThickness() + ( 2 * aClearanceValue );
prms.m_textCircle2SegmentCount =
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
prms.m_error = aError;
COLOR4D color = COLOR4D::BLACK; // not actually used, but needed by DrawGraphicText
if( IsMultilineAllowed() )
@ -446,9 +441,6 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
linewidth += 2 * aClearanceValue;
int numSegs = std::max( GetArcToSegmentCount( linewidth / 2, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
// Creating a reliable clearance shape for circles and arcs is not so easy, due to
// the error created by segment approximation.
// for a circle this is not so hard: create a polygon from a circle slightly bigger:
@ -460,17 +452,17 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
{
case S_CIRCLE:
TransformRingToPolygon(
aCornerBuffer, GetCenter(), GetRadius(), numSegs, correction * linewidth );
aCornerBuffer, GetCenter(), GetRadius(), aError, linewidth );
break;
case S_ARC:
TransformArcToPolygon(
aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, numSegs, linewidth );
aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, aError, linewidth );
break;
case S_SEGMENT:
TransformOvalClearanceToPolygon(
aCornerBuffer, m_Start, m_End, linewidth, numSegs, correction );
aCornerBuffer, m_Start, m_End, linewidth, aError );
break;
case S_POLYGON:
@ -500,12 +492,12 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
{
for( size_t ii = 1; ii < poly.size(); ii++ )
{
TransformOvalClearanceToPolygon(
aCornerBuffer, poly[ii - 1], poly[ii], linewidth, numSegs, correction );
TransformOvalClearanceToPolygon( aCornerBuffer, poly[ii - 1], poly[ii],
linewidth, aError );
}
TransformOvalClearanceToPolygon(
aCornerBuffer, poly.back(), poly.front(), linewidth, numSegs, correction );
TransformOvalClearanceToPolygon( aCornerBuffer, poly.back(), poly.front(),
linewidth, aError );
break;
}
@ -530,7 +522,7 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
if( corner2 != corner1 )
{
TransformRoundedEndsSegmentToPolygon(
aCornerBuffer, corner1, corner2, numSegs, linewidth );
aCornerBuffer, corner1, corner2, aError, linewidth );
}
corner1 = corner2;
@ -549,7 +541,7 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
for( unsigned ii = 1; ii < poly.size(); ii++ )
{
TransformRoundedEndsSegmentToPolygon(
aCornerBuffer, poly[ii - 1], poly[ii], numSegs, linewidth );
aCornerBuffer, poly[ii - 1], poly[ii], aError, linewidth );
}
}
break;
@ -566,21 +558,18 @@ void TRACK::TransformShapeWithClearanceToPolygon(
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for tracks." );
int radius = ( m_Width / 2 ) + aClearanceValue;
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
switch( Type() )
{
case PCB_VIA_T:
{
radius = KiROUND( radius * correction );
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, numSegs );
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aError );
}
break;
default:
TransformOvalClearanceToPolygon( aCornerBuffer, m_Start, m_End,
m_Width + ( 2 * aClearanceValue ), numSegs, correction );
m_Width + ( 2 * aClearanceValue ), aError );
break;
}
}
@ -602,10 +591,7 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
{
case PAD_SHAPE_CIRCLE:
{
int numSegs = std::max( GetArcToSegmentCount( dx, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
dx = KiROUND( dx * correction );
TransformCircleToPolygon( aCornerBuffer, padShapePos, dx, numSegs );
TransformCircleToPolygon( aCornerBuffer, padShapePos, dx, aError );
}
break;
@ -625,13 +611,10 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
width = dy * 2;
}
int numSegs = std::max( GetArcToSegmentCount( width / 2, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
RotatePoint( &shape_offset, angle );
wxPoint start = padShapePos - shape_offset;
wxPoint end = padShapePos + shape_offset;
TransformOvalClearanceToPolygon( aCornerBuffer, start, end, width, numSegs, correction );
TransformOvalClearanceToPolygon( aCornerBuffer, start, end, width, aError );
}
break;
@ -671,13 +654,13 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
int rounding_radius = GetRoundRectCornerRadius() + clearance;
wxSize shapesize( m_Size );
shapesize.x += clearance*2;
shapesize.y += clearance*2;
shapesize.x += clearance * 2;
shapesize.y += clearance * 2;
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle,
rounding_radius, doChamfer ? GetChamferRectRatio() : 0.0,
doChamfer ? GetChamferPositions() : 0, numSegs );
doChamfer ? GetChamferPositions() : 0, aError );
aCornerBuffer.Append( outline );
}
@ -769,8 +752,7 @@ bool D_PAD::BuildPadDrillShapePolygon(
if( drillsize.x == drillsize.y ) // usual round hole
{
int radius = ( drillsize.x / 2 ) + aInflateValue;
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
TransformCircleToPolygon( aCornerBuffer, GetPosition(), radius, numSegs );
TransformCircleToPolygon( aCornerBuffer, GetPosition(), radius, aError );
}
else // Oblong hole
{
@ -780,10 +762,9 @@ bool D_PAD::BuildPadDrillShapePolygon(
GetOblongDrillGeometry( start, end, width );
width += aInflateValue * 2;
int numSegs = std::max( GetArcToSegmentCount( width / 2, aError, 360.0 ), 6 );
TransformRoundedEndsSegmentToPolygon(
aCornerBuffer, GetPosition() + start, GetPosition() + end, numSegs, width );
aCornerBuffer, GetPosition() + start, GetPosition() + end, aError, width );
}
return true;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@ -937,15 +937,13 @@ bool D_PAD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
// Check for hit in polygon
SHAPE_POLY_SET outline;
int segmentToCircleCount = std::max<int>(
GetArcToSegmentCount( GetRoundRectCornerRadius(), ARC_HIGH_DEF, 360.0 ), 3 );
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
TransformRoundChamferedRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
GetRoundRectCornerRadius(),
doChamfer ? GetChamferRectRatio() : 0.0,
doChamfer ? GetChamferPositions() : 0,
segmentToCircleCount );
ARC_HIGH_DEF );
const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );

View File

@ -324,8 +324,7 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
// Output the outline perimeter as polygon.
if( graphic->GetShape() == S_CIRCLE )
{
int steps = std::max<int>( 4, GetArcToSegmentCount( graphic->GetRadius(), aTolerance, 360.0 ) );
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), steps );
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), aTolerance );
}
else if( graphic->GetShape() == S_POLYGON )
{

View File

@ -989,7 +989,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
TransformRoundChamferedRectToPolygon( polysetref, wxPoint( 0, 0 ), aRefPad->GetSize(),
aRefPad->GetOrientation(),
padRadius, aRefPad->GetChamferRectRatio(),
aRefPad->GetChamferPositions(), 64 );
aRefPad->GetChamferPositions(), ARC_HIGH_DEF );
}
else if( aRefPad->GetShape() == PAD_SHAPE_CUSTOM )
{
@ -1031,7 +1031,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
TransformRoundChamferedRectToPolygon( polysetcompare, relativePadPos, aPad->GetSize(),
aPad->GetOrientation(),
padRadius, aPad->GetChamferRectRatio(),
aPad->GetChamferPositions(), 64 );
aPad->GetChamferPositions(), ARC_HIGH_DEF );
}
else if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
{
@ -1422,7 +1422,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
TransformRoundChamferedRectToPolygon( polyset, m_padToTestPos, aPad->GetSize(),
aPad->GetOrientation(),
padRadius, aPad->GetChamferRectRatio(),
aPad->GetChamferPositions(), 64 );
aPad->GetChamferPositions(), ARC_HIGH_DEF );
// Rotate also coordinates by m_segmAngle, because the segment orient
// is m_segmAngle.
// we are using a horizontal segment for test, because we know here

View File

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

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -220,40 +220,33 @@ bool D_PAD::buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError )
for( unsigned ii = 1; ii < poly.size(); ii++ )
{
int numSegs = std::max(
GetArcToSegmentCount( bshape.m_Thickness / 2, aError, 360.0 ), 6 );
TransformRoundedEndsSegmentToPolygon(
aux_polyset, poly[ii - 1], poly[ii], numSegs, bshape.m_Thickness );
aux_polyset, poly[ii - 1], poly[ii], aError, bshape.m_Thickness );
}
break;
}
case S_SEGMENT: // usual segment : line with rounded ends
{
int numSegs =
std::max( GetArcToSegmentCount( bshape.m_Thickness / 2, aError, 360.0 ), 6 );
TransformRoundedEndsSegmentToPolygon(
aux_polyset, bshape.m_Start, bshape.m_End, numSegs, bshape.m_Thickness );
aux_polyset, bshape.m_Start, bshape.m_End, aError, bshape.m_Thickness );
break;
}
case S_ARC: // Arc with rounded ends
{
int radius = KiROUND( EuclideanNorm( ( bshape.m_Start - bshape.m_End ) ) );
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
TransformArcToPolygon( aux_polyset, bshape.m_Start, bshape.m_End, bshape.m_ArcAngle,
numSegs, bshape.m_Thickness );
aError, bshape.m_Thickness );
break;
}
case S_CIRCLE: // ring or circle
{
int numSegs = std::max( GetArcToSegmentCount( bshape.m_Radius, aError, 360.0 ), 6 );
if( bshape.m_Thickness ) // ring
TransformRingToPolygon(
aux_polyset, bshape.m_Start, bshape.m_Radius, numSegs, bshape.m_Thickness );
aux_polyset, bshape.m_Start, bshape.m_Radius, aError, bshape.m_Thickness );
else // Filled circle
TransformCircleToPolygon( aux_polyset, bshape.m_Start, bshape.m_Radius, numSegs );
TransformCircleToPolygon( aux_polyset, bshape.m_Start, bshape.m_Radius, aError );
break;
}
@ -325,12 +318,8 @@ bool D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon )
{
default:
case PAD_SHAPE_CIRCLE:
{
int numSegs = std::max( GetArcToSegmentCount( GetSize().x / 2, ARC_HIGH_DEF, 360.0 ), 6 );
TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, numSegs );
TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, ARC_HIGH_DEF );
break;
}
case PAD_SHAPE_RECT:
{

View File

@ -450,7 +450,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
corner_radius, GetChamferRectRatio(),
doChamfer ? GetChamferPositions() : 0,
SEGCOUNT );
ARC_HIGH_DEF );
// Draw the polygon: Inflate creates only one convex polygon
bool filled = aDrawInfo.m_ShowPadFilled;
@ -472,7 +472,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
corner_radius, GetChamferRectRatio(),
doChamfer ? GetChamferPositions() : 0,
SEGCOUNT );
ARC_HIGH_DEF );
// Draw the polygon: Inflate creates only one convex polygon
SHAPE_LINE_CHAIN& clearance_poly = outline.Outline( 0 );

View File

@ -823,13 +823,12 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
{
SHAPE_POLY_SET polySet;
wxSize prsize( size.x * 2, size.y * 2 ); // size is the half pad area size)
const int segmentToCircleCount = 64;
const int corner_radius = aPad->GetRoundRectCornerRadius( prsize );
bool doChamfer = shape == PAD_SHAPE_CHAMFERED_RECT;
TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
0.0, corner_radius, aPad->GetChamferRectRatio(),
doChamfer ? aPad->GetChamferPositions() : 0, segmentToCircleCount );
doChamfer ? aPad->GetChamferPositions() : 0, ARC_HIGH_DEF );
m_gal->DrawPolygon( polySet );
break;
}

View File

@ -184,11 +184,10 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPl
case PAD_SHAPE_CHAMFERED_RECT:
{
SHAPE_POLY_SET polygons;
const int segmentToCircleCount = 64;
const int corner_radius = aPad->GetRoundRectCornerRadius( aPad->GetSize() );
TransformRoundChamferedRectToPolygon( polygons, shape_pos, aPad->GetSize(),
aPad->GetOrientation(), corner_radius, aPad->GetChamferRectRatio(),
aPad->GetChamferPositions(), segmentToCircleCount );
aPad->GetChamferPositions(), ARC_HIGH_DEF );
if( polygons.OutlineCount() == 0 )
break;

View File

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