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:
parent
323ecada8d
commit
ac435ecd68
|
@ -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 );
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ) );
|
||||
|
|
|
@ -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:
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
Loading…
Reference in New Issue