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 );
|
int corner_radius = aPad->GetRoundRectCornerRadius( shapesize );
|
||||||
TransformRoundChamferedRectToPolygon( polyList, PadShapePos, shapesize, aPad->GetOrientation(),
|
TransformRoundChamferedRectToPolygon( polyList, PadShapePos, shapesize, aPad->GetOrientation(),
|
||||||
corner_radius, aPad->GetChamferRectRatio(),
|
corner_radius, aPad->GetChamferRectRatio(),
|
||||||
aPad->GetChamferPositions(), 32 );
|
aPad->GetChamferPositions(), ARC_HIGH_DEF );
|
||||||
|
|
||||||
// Add the PAD polygon
|
// Add the PAD polygon
|
||||||
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits, *aPad );
|
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 holediameter = via->GetDrillValue();
|
||||||
const int hole_outer_radius = (holediameter / 2) + GetCopperThicknessBIU();
|
const int hole_outer_radius = (holediameter / 2) + GetCopperThicknessBIU();
|
||||||
|
|
||||||
TransformCircleToPolygon( *layerOuterHolesPoly,
|
TransformCircleToPolygon( *layerOuterHolesPoly, via->GetStart(),
|
||||||
via->GetStart(),
|
hole_outer_radius, ARC_HIGH_DEF );
|
||||||
hole_outer_radius,
|
|
||||||
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
|
|
||||||
|
|
||||||
TransformCircleToPolygon( *layerInnerHolesPoly,
|
TransformCircleToPolygon( *layerInnerHolesPoly, via->GetStart(),
|
||||||
via->GetStart(),
|
holediameter / 2, ARC_HIGH_DEF );
|
||||||
holediameter / 2,
|
|
||||||
GetNrSegmentsCircle( holediameter ) );
|
|
||||||
}
|
}
|
||||||
else if( lIdx == 0 ) // it only adds once the THT holes
|
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
|
// Add through hole contourns
|
||||||
// /////////////////////////////////////////////////////////
|
// /////////////////////////////////////////////////////////
|
||||||
TransformCircleToPolygon( m_through_outer_holes_poly,
|
TransformCircleToPolygon( m_through_outer_holes_poly, via->GetStart(),
|
||||||
via->GetStart(),
|
hole_outer_radius, ARC_HIGH_DEF );
|
||||||
hole_outer_radius,
|
|
||||||
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
|
|
||||||
|
|
||||||
TransformCircleToPolygon( m_through_inner_holes_poly,
|
TransformCircleToPolygon( m_through_inner_holes_poly, via->GetStart(),
|
||||||
via->GetStart(),
|
holediameter / 2, ARC_HIGH_DEF );
|
||||||
holediameter / 2,
|
|
||||||
GetNrSegmentsCircle( holediameter ) );
|
|
||||||
|
|
||||||
// Add samething for vias only
|
// Add samething for vias only
|
||||||
|
|
||||||
TransformCircleToPolygon( m_through_outer_holes_vias_poly,
|
TransformCircleToPolygon( m_through_outer_holes_vias_poly, via->GetStart(),
|
||||||
via->GetStart(),
|
hole_outer_radius, ARC_HIGH_DEF );
|
||||||
hole_outer_radius,
|
|
||||||
GetNrSegmentsCircle( hole_outer_radius * 2 ) );
|
|
||||||
|
|
||||||
//TransformCircleToPolygon( m_through_inner_holes_vias_poly,
|
//TransformCircleToPolygon( m_through_inner_holes_vias_poly,
|
||||||
// via->GetStart(),
|
// via->GetStart(),
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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) 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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
|
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(),
|
TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(),
|
||||||
aPad->GetSize().x / 2, nr_sides_per_circle, aWidth );
|
aPad->GetSize().x / 2, ARC_HIGH_DEF, aWidth );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,8 +120,6 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon( const D_PAD* aPad,
|
||||||
// For other shapes, draw polygon outlines
|
// For other shapes, draw polygon outlines
|
||||||
SHAPE_POLY_SET corners;
|
SHAPE_POLY_SET corners;
|
||||||
|
|
||||||
auto nr_sides_per_circle =
|
|
||||||
GetNrSegmentsCircle( std::min( aPad->GetSize().x, aPad->GetSize().y ) );
|
|
||||||
buildPadShapePolygon( aPad, corners, wxSize( 0, 0 ) );
|
buildPadShapePolygon( aPad, corners, wxSize( 0, 0 ) );
|
||||||
|
|
||||||
// Add outlines as thick segments in polygon buffer
|
// 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& a = path.CPoint( ii );
|
||||||
const VECTOR2I& b = path.CPoint( ii + 1 );
|
const VECTOR2I& b = path.CPoint( ii + 1 );
|
||||||
|
|
||||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ),
|
||||||
wxPoint( a.x, a.y ),
|
wxPoint( b.x, b.y ), ARC_HIGH_DEF, aWidth );
|
||||||
wxPoint( b.x, b.y ),
|
|
||||||
nr_sides_per_circle,
|
|
||||||
aWidth );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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) 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -31,28 +31,23 @@
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <convert_basic_shapes_to_polygon.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,
|
void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aBuffer,
|
||||||
wxPoint aCenter, int aRadius,
|
wxPoint aCenter, int aRadius,
|
||||||
int aCircleToSegmentsCount )
|
int aError )
|
||||||
{
|
{
|
||||||
wxPoint corner_position;
|
wxPoint corner_position;
|
||||||
double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
|
int numSegs = std::max( GetArcToSegmentCount( aRadius, aError, 360.0 ), 6 );
|
||||||
double halfstep = delta/2; // the starting value for rot angles
|
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;
|
corner_position.y = 0;
|
||||||
double angle = (ii * delta) + halfstep;
|
double angle = (ii * delta) + halfstep;
|
||||||
RotatePoint( &corner_position, angle );
|
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,
|
void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aCenter, int aRadius,
|
wxPoint aCenter, int aRadius,
|
||||||
int aCircleToSegmentsCount )
|
int aError )
|
||||||
{
|
{
|
||||||
wxPoint corner_position;
|
wxPoint corner_position;
|
||||||
double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
|
int numSegs = std::max( GetArcToSegmentCount( aRadius, aError, 360.0 ), 6 );
|
||||||
double halfstep = delta/2; // the starting value for rot angles
|
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();
|
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;
|
corner_position.y = 0;
|
||||||
double angle = (ii * delta) + halfstep;
|
double angle = (ii * delta) + halfstep;
|
||||||
RotatePoint( &corner_position, angle );
|
RotatePoint( &corner_position, angle );
|
||||||
|
@ -95,9 +83,10 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aStart, wxPoint aEnd, int aWidth,
|
wxPoint aStart, wxPoint aEnd, int aWidth,
|
||||||
int aCircleToSegmentsCount, double aCorrectionFactor )
|
int aError )
|
||||||
{
|
{
|
||||||
// To build the polygonal shape outside the actual shape, we use a bigger
|
// To build the polygonal shape outside the actual shape, we use a bigger
|
||||||
// radius to build rounded ends.
|
// 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
|
// so, later, we will clamp the polygonal shape with the bounding box
|
||||||
// of the segment.
|
// of the segment.
|
||||||
int radius = aWidth / 2;
|
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
|
radius = radius * correction; // make segments outside the circles
|
||||||
// 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
|
|
||||||
|
|
||||||
// end point is the coordinate relative to aStart
|
// end point is the coordinate relative to aStart
|
||||||
wxPoint endp = aEnd - 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 );
|
double delta_angle = atan2( (double)endp.y, (double)endp.x );
|
||||||
int seg_len = KiROUND( EuclideanNorm( endp ) );
|
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
|
// Compute the outlines of the segment, and creates a polygon
|
||||||
// Note: the polygonal shape is built from the equivalent horizontal
|
// Note: the polygonal shape is built from the equivalent horizontal
|
||||||
// segment starting ar 0,0, and ending at seg_len,0
|
// segment starting ar 0,0, and ending at seg_len,0
|
||||||
|
|
||||||
// add right rounded end:
|
// add right rounded end:
|
||||||
for( int ii = 0; ii < aCircleToSegmentsCount/2; ii++ )
|
for( int ii = 0; ii < numSegs / 2; ii++ )
|
||||||
{
|
{
|
||||||
corner = wxPoint( 0, radius );
|
corner = wxPoint( 0, radius );
|
||||||
RotatePoint( &corner, delta*ii );
|
RotatePoint( &corner, delta * ii );
|
||||||
corner.x += seg_len;
|
corner.x += seg_len;
|
||||||
polyshape.Append( corner.x, corner.y );
|
polyshape.Append( corner.x, corner.y );
|
||||||
}
|
}
|
||||||
|
@ -153,10 +139,10 @@ void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
polyshape.Append( corner.x, corner.y );
|
polyshape.Append( corner.x, corner.y );
|
||||||
|
|
||||||
// add left rounded end:
|
// add left rounded end:
|
||||||
for( int ii = 0; ii < aCircleToSegmentsCount/2; ii++ )
|
for( int ii = 0; ii < numSegs / 2; ii++ )
|
||||||
{
|
{
|
||||||
corner = wxPoint( 0, -radius );
|
corner = wxPoint( 0, -radius );
|
||||||
RotatePoint( &corner, delta*ii );
|
RotatePoint( &corner, delta * ii );
|
||||||
polyshape.Append( corner.x, corner.y );
|
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
|
// 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,
|
// the polygonal shape bbox equivalent to the segment has a too big height,
|
||||||
// and the right width
|
// and the right width
|
||||||
if( aCorrectionFactor > 1.0 )
|
if( correction > 1.0 )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET bbox;
|
SHAPE_POLY_SET bbox;
|
||||||
bbox.NewOutline();
|
bbox.NewOutline();
|
||||||
|
@ -197,8 +183,7 @@ void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
aCornerBuffer.Append( polyshape);
|
aCornerBuffer.Append( polyshape);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the centers of the rounded corners of a rect.
|
|
||||||
*/
|
|
||||||
void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
|
void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
|
||||||
const wxPoint& aPosition, const wxSize& aSize, double aRotation )
|
const wxPoint& aPosition, const wxSize& aSize, double aRotation )
|
||||||
{
|
{
|
||||||
|
@ -243,7 +228,7 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
const wxPoint& aPosition, const wxSize& aSize,
|
const wxPoint& aPosition, const wxSize& aSize,
|
||||||
double aRotation, int aCornerRadius,
|
double aRotation, int aCornerRadius,
|
||||||
double aChamferRatio, int aChamferCorners,
|
double aChamferRatio, int aChamferCorners,
|
||||||
int aCircleToSegmentsCount )
|
int aError )
|
||||||
{
|
{
|
||||||
// Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
|
// Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
|
||||||
// or in actual position/orientation for round rect only
|
// 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 )
|
for( int ii = 0; ii < 4; ++ii )
|
||||||
outline.Append( corners[ii].x, corners[ii].y );
|
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
|
if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
|
||||||
{
|
{
|
||||||
|
@ -299,9 +285,9 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
chamfered_corner.RemoveAllContours();
|
chamfered_corner.RemoveAllContours();
|
||||||
chamfered_corner.NewOutline();
|
chamfered_corner.NewOutline();
|
||||||
chamfered_corner.Append( 0, 0 );
|
chamfered_corner.Append( 0, 0 );
|
||||||
chamfered_corner.Append( 0, signY[ii]*aSize.y/2 );
|
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, signY[ii] * aSize.y / 2 );
|
||||||
chamfered_corner.Append( signX[ii]*aSize.x/2, 0 );
|
chamfered_corner.Append( signX[ii] * aSize.x / 2, 0 );
|
||||||
chamfered_corner.Move( corner_pos );
|
chamfered_corner.Move( corner_pos );
|
||||||
outline.BooleanAdd( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
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.RemoveAllContours();
|
||||||
chamfered_corner.NewOutline();
|
chamfered_corner.NewOutline();
|
||||||
chamfered_corner.Append( 0, 0 );
|
chamfered_corner.Append( 0, 0 );
|
||||||
chamfered_corner.Append( 0, signY[ii]*chamfer_value );
|
chamfered_corner.Append( 0, signY[ii] * chamfer_value );
|
||||||
chamfered_corner.Append( signX[ii]*chamfer_value, 0 );
|
chamfered_corner.Append( signX[ii] * chamfer_value, 0 );
|
||||||
chamfered_corner.Move( corner_pos );
|
chamfered_corner.Move( corner_pos );
|
||||||
outline.BooleanSubtract( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
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,
|
void TransformRoundedEndsSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aStart, wxPoint aEnd,
|
wxPoint aStart, wxPoint aEnd,
|
||||||
int aCircleToSegmentsCount,
|
int aError, int aWidth )
|
||||||
int aWidth )
|
|
||||||
{
|
{
|
||||||
int radius = aWidth / 2;
|
int radius = aWidth / 2;
|
||||||
wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
|
wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
|
||||||
wxPoint startp = aStart;
|
wxPoint startp = aStart;
|
||||||
wxPoint corner;
|
wxPoint corner;
|
||||||
VECTOR2I polypoint;
|
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();
|
aCornerBuffer.NewOutline();
|
||||||
|
|
||||||
// normalize the position in order to have endp.x >= 0;
|
// 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
|
double delta_angle = ArcTangente( endp.y, endp.x ); // delta_angle is in 0.1 degrees
|
||||||
int seg_len = KiROUND( EuclideanNorm( endp ) );
|
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
|
// Compute the outlines of the segment, and creates a polygon
|
||||||
// add right rounded end:
|
// add right rounded end:
|
||||||
for( int ii = 0; ii < 1800; ii += delta )
|
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,
|
void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aCentre, wxPoint aStart, double aArcAngle,
|
wxPoint aCentre, wxPoint aStart, double aArcAngle,
|
||||||
int aCircleToSegmentsCount, int aWidth )
|
int aError, int aWidth )
|
||||||
{
|
{
|
||||||
wxPoint arc_start, arc_end;
|
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;
|
arc_end = arc_start = aStart;
|
||||||
|
|
||||||
|
@ -447,31 +413,19 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
{
|
{
|
||||||
curr_end = arc_start;
|
curr_end = arc_start;
|
||||||
RotatePoint( &curr_end, aCentre, -ii );
|
RotatePoint( &curr_end, aCentre, -ii );
|
||||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_start, curr_end,
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_start, curr_end, aError,
|
||||||
aCircleToSegmentsCount, aWidth );
|
aWidth );
|
||||||
curr_start = curr_end;
|
curr_start = curr_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( curr_end != arc_end )
|
if( curr_end != arc_end )
|
||||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_end, arc_end, aError, aWidth );
|
||||||
curr_end, arc_end,
|
|
||||||
aCircleToSegmentsCount, 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,
|
void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aCentre, int aRadius,
|
wxPoint aCentre, int aRadius,
|
||||||
int aCircleToSegmentsCount, int aWidth )
|
int aError, int aWidth )
|
||||||
{
|
{
|
||||||
// Compute the corners positions and creates the poly
|
// Compute the corners positions and creates the poly
|
||||||
wxPoint curr_point;
|
wxPoint curr_point;
|
||||||
|
@ -480,18 +434,17 @@ void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
|
|
||||||
if( inner_radius <= 0 )
|
if( inner_radius <= 0 )
|
||||||
{ //In this case, the ring is just a circle (no hole inside)
|
{ //In this case, the ring is just a circle (no hole inside)
|
||||||
TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ),
|
TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ), aError );
|
||||||
aCircleToSegmentsCount );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAPE_POLY_SET buffer;
|
SHAPE_POLY_SET buffer;
|
||||||
|
|
||||||
TransformCircleToPolygon( buffer, aCentre, outer_radius, aCircleToSegmentsCount );
|
TransformCircleToPolygon( buffer, aCentre, outer_radius, aError );
|
||||||
|
|
||||||
// Build the hole:
|
// Build the hole:
|
||||||
buffer.NewHole();
|
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 );
|
buffer.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
aCornerBuffer.Append( buffer );
|
aCornerBuffer.Append( buffer );
|
||||||
|
|
|
@ -496,7 +496,6 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
|
||||||
// polygon and its thick outline
|
// polygon and its thick outline
|
||||||
SHAPE_POLY_SET bufferOutline;
|
SHAPE_POLY_SET bufferOutline;
|
||||||
SHAPE_POLY_SET bufferPolybase;
|
SHAPE_POLY_SET bufferPolybase;
|
||||||
const int circleToSegmentsCount = 16;
|
|
||||||
|
|
||||||
bufferPolybase.NewOutline();
|
bufferPolybase.NewOutline();
|
||||||
|
|
||||||
|
@ -504,7 +503,7 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
|
||||||
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
|
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
|
||||||
{
|
{
|
||||||
TransformRoundedEndsSegmentToPolygon( bufferOutline,
|
TransformRoundedEndsSegmentToPolygon( bufferOutline,
|
||||||
aCornerList[ii-1], aCornerList[ii], circleToSegmentsCount, aWidth );
|
aCornerList[ii-1], aCornerList[ii], GetPlotterArcHighDef(), aWidth );
|
||||||
}
|
}
|
||||||
|
|
||||||
// enter the initial polygon:
|
// enter the initial polygon:
|
||||||
|
@ -591,7 +590,7 @@ void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int
|
||||||
std::vector<wxPoint> cornerList;
|
std::vector<wxPoint> cornerList;
|
||||||
SHAPE_POLY_SET outlineBuffer;
|
SHAPE_POLY_SET outlineBuffer;
|
||||||
TransformOvalClearanceToPolygon( outlineBuffer,
|
TransformOvalClearanceToPolygon( outlineBuffer,
|
||||||
aStart, aEnd, aWidth, 32 , 1.0 );
|
aStart, aEnd, aWidth, GetPlotterArcHighDef() );
|
||||||
const SHAPE_LINE_CHAIN& path = outlineBuffer.COutline(0 );
|
const SHAPE_LINE_CHAIN& path = outlineBuffer.COutline(0 );
|
||||||
|
|
||||||
for( int jj = 0; jj < path.PointCount(); jj++ )
|
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;
|
SHAPE_POLY_SET outline;
|
||||||
const int segmentToCircleCount = 64;
|
const int segmentToCircleCount = 64;
|
||||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
|
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
|
||||||
aCornerRadius, 0.0, 0, segmentToCircleCount );
|
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
|
||||||
|
|
||||||
// TransformRoundRectToPolygon creates only one convex polygon
|
// TransformRoundRectToPolygon creates only one convex polygon
|
||||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
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.
|
// Currently, a Pad RoundRect is plotted as polygon.
|
||||||
// TODO: use Aperture macro and flash it
|
// TODO: use Aperture macro and flash it
|
||||||
SHAPE_POLY_SET outline;
|
SHAPE_POLY_SET outline;
|
||||||
const int segmentToCircleCount = 64;
|
|
||||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
|
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
|
||||||
aCornerRadius, 0.0, 0, segmentToCircleCount );
|
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
|
||||||
|
|
||||||
if( aTraceMode != FILLED )
|
if( aTraceMode != FILLED )
|
||||||
outline.Inflate( -GetCurrentLineWidth()/2, 16 );
|
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 )
|
EDA_DRAW_MODE_T aTraceMode, void* aData )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET outline;
|
SHAPE_POLY_SET outline;
|
||||||
const int segmentToCircleCount = 32;
|
|
||||||
|
|
||||||
wxSize size = aSize;
|
wxSize size = aSize;
|
||||||
|
|
||||||
|
@ -643,11 +642,10 @@ void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSiz
|
||||||
}
|
}
|
||||||
|
|
||||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
|
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
|
||||||
aCornerRadius, 0.0, 0, segmentToCircleCount );
|
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
|
||||||
|
|
||||||
// TransformRoundRectToPolygon creates only one convex polygon
|
// TransformRoundRectToPolygon creates only one convex polygon
|
||||||
std::vector< wxPoint > cornerList;
|
std::vector< wxPoint > cornerList;
|
||||||
cornerList.reserve( segmentToCircleCount + 5 );
|
|
||||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
||||||
|
|
||||||
for( int ii = 0; ii < poly.PointCount(); ++ii )
|
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;
|
SHAPE_POLY_SET outline;
|
||||||
const int segmentToCircleCount = 64;
|
|
||||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
|
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
|
||||||
aCornerRadius, 0.0, 0, segmentToCircleCount );
|
aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
|
||||||
|
|
||||||
std::vector< wxPoint > cornerList;
|
std::vector< wxPoint > cornerList;
|
||||||
cornerList.reserve( segmentToCircleCount + 5 );
|
|
||||||
// TransformRoundRectToPolygon creates only one convex polygon
|
// TransformRoundRectToPolygon creates only one convex polygon
|
||||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
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) 1992-2017 Jean-Pierre Charras <jp.charras at wanadoo.fr>
|
||||||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <trigo.h>
|
#include <trigo.h>
|
||||||
|
#include <convert_to_biu.h>
|
||||||
#include <convert_basic_shapes_to_polygon.h>
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
#include <gr_basic.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
|
const int seg_per_circle = 64; // Number of segments to approximate a circle
|
||||||
|
|
||||||
void AM_PRIMITIVE::DrawBasicShape( const GERBER_DRAW_ITEM* aParent,
|
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 )
|
if( outerDiam <= penThickness )
|
||||||
{ // No room to draw a ring (no room for the hole):
|
{ // No room to draw a ring (no room for the hole):
|
||||||
// draw a circle instead (with no hole), with the right diameter
|
// draw a circle instead (with no hole), with the right diameter
|
||||||
TransformCircleToPolygon( aShapeBuffer, center,
|
TransformCircleToPolygon( aShapeBuffer, center, outerDiam / 2, ARC_HIGH_DEF );
|
||||||
outerDiam / 2, seg_per_circle );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TransformRingToPolygon( aShapeBuffer, center,
|
TransformRingToPolygon( aShapeBuffer, center, ( outerDiam - penThickness ) / 2,
|
||||||
(outerDiam - penThickness) / 2,
|
ARC_HIGH_DEF, penThickness );
|
||||||
seg_per_circle, penThickness );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the cross:
|
// Draw the cross:
|
||||||
|
|
|
@ -289,7 +289,7 @@ void D_CODE::DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent,
|
||||||
GRClosedPoly( aClipBox, aDC, pointCount, &points[0], aFilled, aColor, aColor );
|
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
|
#define SEGS_CNT 64 // number of segments to approximate a circle
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ void D_CODE::ConvertShapeToPolygon()
|
||||||
switch( m_Shape )
|
switch( m_Shape )
|
||||||
{
|
{
|
||||||
case APT_CIRCLE: // creates only a circle with rectangular hole
|
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 );
|
addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -435,7 +435,7 @@ static void addHoleToPolygon( SHAPE_POLY_SET* aPolygon,
|
||||||
|
|
||||||
if( aHoleShape == APT_DEF_ROUND_HOLE )
|
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 )
|
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.
|
* 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) 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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 aCornerBuffer = a buffer to store the polygon
|
||||||
* @param aCenter = the center of the circle
|
* @param aCenter = the center of the circle
|
||||||
* @param aRadius = the radius 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
|
* 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
|
* outside the circle, you should give aRadius calculated with a correction factor
|
||||||
*/
|
*/
|
||||||
void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aCenter, int aRadius,
|
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 aStart = the first point of the segment
|
||||||
* @param aEnd = the second point of the segment
|
* @param aEnd = the second point of the segment
|
||||||
* @param aWidth = the width of the segment
|
* @param aWidth = the width of the segment
|
||||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
* @param aError = the IU allowed for error in approximation
|
||||||
* @param aCorrectionFactor = the coefficient to have segments outside the circle
|
|
||||||
* if aCorrectionFactor = 1.0, the shape will be the same as
|
|
||||||
* TransformRoundedEndsSegmentToPolygon
|
|
||||||
*/
|
*/
|
||||||
void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aStart, wxPoint aEnd, int aWidth,
|
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
|
* 4 = BOTTOM_LEFT
|
||||||
* 8 = BOTTOM_RIGHT
|
* 8 = BOTTOM_RIGHT
|
||||||
* One can have more than one chamfered corner by ORing the corner identifers
|
* 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,
|
void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
const wxPoint& aPosition, const wxSize& aSize,
|
const wxPoint& aPosition, const wxSize& aSize,
|
||||||
double aRotation, int aCornerRadius,
|
double aRotation, int aCornerRadius,
|
||||||
double aChamferRatio, int aChamferCorners,
|
double aChamferRatio, int aChamferCorners,
|
||||||
int aCircleToSegmentsCount );
|
int aError );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformRoundedEndsSegmentToPolygon
|
* Function TransformRoundedEndsSegmentToPolygon
|
||||||
|
@ -135,14 +132,14 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
* @param aCornerBuffer = a buffer to store the polygon
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
* @param aStart = the segment start point coordinate
|
* @param aStart = the segment start point coordinate
|
||||||
* @param aEnd = the segment end 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
|
* @param aWidth = the segment width
|
||||||
* Note: the polygon is inside the arc ends, so if you want to have the polygon
|
* 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
|
* outside the circle, you should give aStart and aEnd calculated with a correction factor
|
||||||
*/
|
*/
|
||||||
void TransformRoundedEndsSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
void TransformRoundedEndsSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aStart, wxPoint aEnd,
|
wxPoint aStart, wxPoint aEnd,
|
||||||
int aCircleToSegmentsCount,
|
int aError,
|
||||||
int aWidth );
|
int aWidth );
|
||||||
|
|
||||||
|
|
||||||
|
@ -154,12 +151,12 @@ void TransformRoundedEndsSegmentToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
* @param aCentre = centre of the arc or circle
|
* @param aCentre = centre of the arc or circle
|
||||||
* @param aStart = start point of the arc, or a point on the 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 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
|
* @param aWidth = width (thickness) of the line
|
||||||
*/
|
*/
|
||||||
void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aCentre, wxPoint aStart, double aArcAngle,
|
wxPoint aCentre, wxPoint aStart, double aArcAngle,
|
||||||
int aCircleToSegmentsCount, int aWidth );
|
int aError, int aWidth );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformRingToPolygon
|
* Function TransformRingToPolygon
|
||||||
|
@ -168,11 +165,11 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
* @param aCornerBuffer = a buffer to store the polygon
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
* @param aCentre = centre of the arc or circle
|
* @param aCentre = centre of the arc or circle
|
||||||
* @param aRadius = radius of the 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
|
* @param aWidth = width (thickness) of the ring
|
||||||
*/
|
*/
|
||||||
void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
void TransformRingToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||||
wxPoint aCentre, int aRadius,
|
wxPoint aCentre, int aRadius,
|
||||||
int aCircleToSegmentsCount, int aWidth );
|
int aError, int aWidth );
|
||||||
|
|
||||||
#endif // CONVERT_BASIC_SHAPES_TO_POLYGON_H
|
#endif // CONVERT_BASIC_SHAPES_TO_POLYGON_H
|
||||||
|
|
|
@ -216,6 +216,9 @@ public:
|
||||||
*/
|
*/
|
||||||
double GetIUsPerDecimil() const { return m_IUsPerDecimil; }
|
double GetIUsPerDecimil() const { return m_IUsPerDecimil; }
|
||||||
|
|
||||||
|
int GetPlotterArcLowDef() const { return m_IUsPerDecimil * 8; }
|
||||||
|
int GetPlotterArcHighDef() const { return m_IUsPerDecimil * 2; }
|
||||||
|
|
||||||
// Low level primitives
|
// Low level primitives
|
||||||
virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
|
virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
|
||||||
int width = USE_DEFAULT_LINE_WIDTH ) = 0;
|
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.
|
* 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) 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
// so we cannot send them as arguments.
|
// so we cannot send them as arguments.
|
||||||
struct TSEGM_2_POLY_PRMS {
|
struct TSEGM_2_POLY_PRMS {
|
||||||
int m_textWidth;
|
int m_textWidth;
|
||||||
int m_textCircle2SegmentCount;
|
int m_error;
|
||||||
SHAPE_POLY_SET* m_cornerBuffer;
|
SHAPE_POLY_SET* m_cornerBuffer;
|
||||||
};
|
};
|
||||||
TSEGM_2_POLY_PRMS prms;
|
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 );
|
TSEGM_2_POLY_PRMS* prm = static_cast<TSEGM_2_POLY_PRMS*>( aData );
|
||||||
TransformRoundedEndsSegmentToPolygon( *prm->m_cornerBuffer,
|
TransformRoundedEndsSegmentToPolygon( *prm->m_cornerBuffer,
|
||||||
wxPoint( x0, y0), wxPoint( xf, yf ),
|
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];
|
TEXTE_MODULE *textmod = texts[ii];
|
||||||
prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
|
prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
|
||||||
prms.m_textCircle2SegmentCount =
|
prms.m_error = aError;
|
||||||
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
|
|
||||||
wxSize size = textmod->GetTextSize();
|
wxSize size = textmod->GetTextSize();
|
||||||
|
|
||||||
if( textmod->IsMirrored() )
|
if( textmod->IsMirrored() )
|
||||||
|
@ -304,8 +303,7 @@ void MODULE::TransformGraphicTextWithClearanceToPolygonSet(
|
||||||
{
|
{
|
||||||
TEXTE_MODULE *textmod = texts[ii];
|
TEXTE_MODULE *textmod = texts[ii];
|
||||||
prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
|
prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
|
||||||
prms.m_textCircle2SegmentCount =
|
prms.m_error = aError;
|
||||||
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
|
|
||||||
wxSize size = textmod->GetTextSize();
|
wxSize size = textmod->GetTextSize();
|
||||||
|
|
||||||
if( textmod->IsMirrored() )
|
if( textmod->IsMirrored() )
|
||||||
|
@ -327,8 +325,6 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
|
||||||
if( GetFilledPolysList().IsEmpty() )
|
if( GetFilledPolysList().IsEmpty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int numSegs = std::max( GetArcToSegmentCount( GetMinThickness() / 2, aError, 360.0 ), 6 );
|
|
||||||
|
|
||||||
// add filled areas polygons
|
// add filled areas polygons
|
||||||
aCornerBuffer.Append( m_FilledPolysList );
|
aCornerBuffer.Append( m_FilledPolysList );
|
||||||
|
|
||||||
|
@ -343,7 +339,7 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
|
||||||
const VECTOR2I& b = path.CPoint( j + 1 );
|
const VECTOR2I& b = path.CPoint( j + 1 );
|
||||||
|
|
||||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ),
|
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_cornerBuffer = &aCornerBuffer;
|
||||||
prms.m_textWidth = GetThickness() + ( 2 * aClearanceValue );
|
prms.m_textWidth = GetThickness() + ( 2 * aClearanceValue );
|
||||||
prms.m_textCircle2SegmentCount =
|
prms.m_error = aError;
|
||||||
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
|
|
||||||
COLOR4D color = COLOR4D::BLACK; // not actually used, but needed by DrawGraphicText
|
COLOR4D color = COLOR4D::BLACK; // not actually used, but needed by DrawGraphicText
|
||||||
|
|
||||||
if( IsMultilineAllowed() )
|
if( IsMultilineAllowed() )
|
||||||
|
@ -446,9 +441,6 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
|
||||||
|
|
||||||
linewidth += 2 * aClearanceValue;
|
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
|
// Creating a reliable clearance shape for circles and arcs is not so easy, due to
|
||||||
// the error created by segment approximation.
|
// the error created by segment approximation.
|
||||||
// for a circle this is not so hard: create a polygon from a circle slightly bigger:
|
// 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:
|
case S_CIRCLE:
|
||||||
TransformRingToPolygon(
|
TransformRingToPolygon(
|
||||||
aCornerBuffer, GetCenter(), GetRadius(), numSegs, correction * linewidth );
|
aCornerBuffer, GetCenter(), GetRadius(), aError, linewidth );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ARC:
|
case S_ARC:
|
||||||
TransformArcToPolygon(
|
TransformArcToPolygon(
|
||||||
aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, numSegs, linewidth );
|
aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, aError, linewidth );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_SEGMENT:
|
case S_SEGMENT:
|
||||||
TransformOvalClearanceToPolygon(
|
TransformOvalClearanceToPolygon(
|
||||||
aCornerBuffer, m_Start, m_End, linewidth, numSegs, correction );
|
aCornerBuffer, m_Start, m_End, linewidth, aError );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_POLYGON:
|
case S_POLYGON:
|
||||||
|
@ -500,12 +492,12 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
|
||||||
{
|
{
|
||||||
for( size_t ii = 1; ii < poly.size(); ii++ )
|
for( size_t ii = 1; ii < poly.size(); ii++ )
|
||||||
{
|
{
|
||||||
TransformOvalClearanceToPolygon(
|
TransformOvalClearanceToPolygon( aCornerBuffer, poly[ii - 1], poly[ii],
|
||||||
aCornerBuffer, poly[ii - 1], poly[ii], linewidth, numSegs, correction );
|
linewidth, aError );
|
||||||
}
|
}
|
||||||
|
|
||||||
TransformOvalClearanceToPolygon(
|
TransformOvalClearanceToPolygon( aCornerBuffer, poly.back(), poly.front(),
|
||||||
aCornerBuffer, poly.back(), poly.front(), linewidth, numSegs, correction );
|
linewidth, aError );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +522,7 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
|
||||||
if( corner2 != corner1 )
|
if( corner2 != corner1 )
|
||||||
{
|
{
|
||||||
TransformRoundedEndsSegmentToPolygon(
|
TransformRoundedEndsSegmentToPolygon(
|
||||||
aCornerBuffer, corner1, corner2, numSegs, linewidth );
|
aCornerBuffer, corner1, corner2, aError, linewidth );
|
||||||
}
|
}
|
||||||
|
|
||||||
corner1 = corner2;
|
corner1 = corner2;
|
||||||
|
@ -549,7 +541,7 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
|
||||||
for( unsigned ii = 1; ii < poly.size(); ii++ )
|
for( unsigned ii = 1; ii < poly.size(); ii++ )
|
||||||
{
|
{
|
||||||
TransformRoundedEndsSegmentToPolygon(
|
TransformRoundedEndsSegmentToPolygon(
|
||||||
aCornerBuffer, poly[ii - 1], poly[ii], numSegs, linewidth );
|
aCornerBuffer, poly[ii - 1], poly[ii], aError, linewidth );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -566,21 +558,18 @@ void TRACK::TransformShapeWithClearanceToPolygon(
|
||||||
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for tracks." );
|
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for tracks." );
|
||||||
|
|
||||||
int radius = ( m_Width / 2 ) + aClearanceValue;
|
int radius = ( m_Width / 2 ) + aClearanceValue;
|
||||||
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
|
|
||||||
double correction = GetCircletoPolyCorrectionFactor( numSegs );
|
|
||||||
|
|
||||||
switch( Type() )
|
switch( Type() )
|
||||||
{
|
{
|
||||||
case PCB_VIA_T:
|
case PCB_VIA_T:
|
||||||
{
|
{
|
||||||
radius = KiROUND( radius * correction );
|
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aError );
|
||||||
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, numSegs );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TransformOvalClearanceToPolygon( aCornerBuffer, m_Start, m_End,
|
TransformOvalClearanceToPolygon( aCornerBuffer, m_Start, m_End,
|
||||||
m_Width + ( 2 * aClearanceValue ), numSegs, correction );
|
m_Width + ( 2 * aClearanceValue ), aError );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -602,10 +591,7 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
|
||||||
{
|
{
|
||||||
case PAD_SHAPE_CIRCLE:
|
case PAD_SHAPE_CIRCLE:
|
||||||
{
|
{
|
||||||
int numSegs = std::max( GetArcToSegmentCount( dx, aError, 360.0 ), 6 );
|
TransformCircleToPolygon( aCornerBuffer, padShapePos, dx, aError );
|
||||||
double correction = GetCircletoPolyCorrectionFactor( numSegs );
|
|
||||||
dx = KiROUND( dx * correction );
|
|
||||||
TransformCircleToPolygon( aCornerBuffer, padShapePos, dx, numSegs );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -625,13 +611,10 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
|
||||||
width = dy * 2;
|
width = dy * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numSegs = std::max( GetArcToSegmentCount( width / 2, aError, 360.0 ), 6 );
|
|
||||||
double correction = GetCircletoPolyCorrectionFactor( numSegs );
|
|
||||||
|
|
||||||
RotatePoint( &shape_offset, angle );
|
RotatePoint( &shape_offset, angle );
|
||||||
wxPoint start = padShapePos - shape_offset;
|
wxPoint start = padShapePos - shape_offset;
|
||||||
wxPoint end = padShapePos + shape_offset;
|
wxPoint end = padShapePos + shape_offset;
|
||||||
TransformOvalClearanceToPolygon( aCornerBuffer, start, end, width, numSegs, correction );
|
TransformOvalClearanceToPolygon( aCornerBuffer, start, end, width, aError );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -671,13 +654,13 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
|
||||||
int rounding_radius = GetRoundRectCornerRadius() + clearance;
|
int rounding_radius = GetRoundRectCornerRadius() + clearance;
|
||||||
wxSize shapesize( m_Size );
|
wxSize shapesize( m_Size );
|
||||||
|
|
||||||
shapesize.x += clearance*2;
|
shapesize.x += clearance * 2;
|
||||||
shapesize.y += clearance*2;
|
shapesize.y += clearance * 2;
|
||||||
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
||||||
|
|
||||||
TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle,
|
TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle,
|
||||||
rounding_radius, doChamfer ? GetChamferRectRatio() : 0.0,
|
rounding_radius, doChamfer ? GetChamferRectRatio() : 0.0,
|
||||||
doChamfer ? GetChamferPositions() : 0, numSegs );
|
doChamfer ? GetChamferPositions() : 0, aError );
|
||||||
|
|
||||||
aCornerBuffer.Append( outline );
|
aCornerBuffer.Append( outline );
|
||||||
}
|
}
|
||||||
|
@ -769,8 +752,7 @@ bool D_PAD::BuildPadDrillShapePolygon(
|
||||||
if( drillsize.x == drillsize.y ) // usual round hole
|
if( drillsize.x == drillsize.y ) // usual round hole
|
||||||
{
|
{
|
||||||
int radius = ( drillsize.x / 2 ) + aInflateValue;
|
int radius = ( drillsize.x / 2 ) + aInflateValue;
|
||||||
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
|
TransformCircleToPolygon( aCornerBuffer, GetPosition(), radius, aError );
|
||||||
TransformCircleToPolygon( aCornerBuffer, GetPosition(), radius, numSegs );
|
|
||||||
}
|
}
|
||||||
else // Oblong hole
|
else // Oblong hole
|
||||||
{
|
{
|
||||||
|
@ -780,10 +762,9 @@ bool D_PAD::BuildPadDrillShapePolygon(
|
||||||
GetOblongDrillGeometry( start, end, width );
|
GetOblongDrillGeometry( start, end, width );
|
||||||
|
|
||||||
width += aInflateValue * 2;
|
width += aInflateValue * 2;
|
||||||
int numSegs = std::max( GetArcToSegmentCount( width / 2, aError, 360.0 ), 6 );
|
|
||||||
|
|
||||||
TransformRoundedEndsSegmentToPolygon(
|
TransformRoundedEndsSegmentToPolygon(
|
||||||
aCornerBuffer, GetPosition() + start, GetPosition() + end, numSegs, width );
|
aCornerBuffer, GetPosition() + start, GetPosition() + end, aError, width );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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) 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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
|
// Check for hit in polygon
|
||||||
SHAPE_POLY_SET outline;
|
SHAPE_POLY_SET outline;
|
||||||
int segmentToCircleCount = std::max<int>(
|
|
||||||
GetArcToSegmentCount( GetRoundRectCornerRadius(), ARC_HIGH_DEF, 360.0 ), 3 );
|
|
||||||
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
||||||
|
|
||||||
TransformRoundChamferedRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
|
TransformRoundChamferedRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
|
||||||
GetRoundRectCornerRadius(),
|
GetRoundRectCornerRadius(),
|
||||||
doChamfer ? GetChamferRectRatio() : 0.0,
|
doChamfer ? GetChamferRectRatio() : 0.0,
|
||||||
doChamfer ? GetChamferPositions() : 0,
|
doChamfer ? GetChamferPositions() : 0,
|
||||||
segmentToCircleCount );
|
ARC_HIGH_DEF );
|
||||||
|
|
||||||
const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
|
const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
|
||||||
return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
|
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.
|
// Output the outline perimeter as polygon.
|
||||||
if( graphic->GetShape() == S_CIRCLE )
|
if( graphic->GetShape() == S_CIRCLE )
|
||||||
{
|
{
|
||||||
int steps = std::max<int>( 4, GetArcToSegmentCount( graphic->GetRadius(), aTolerance, 360.0 ) );
|
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), aTolerance );
|
||||||
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), steps );
|
|
||||||
}
|
}
|
||||||
else if( graphic->GetShape() == S_POLYGON )
|
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(),
|
TransformRoundChamferedRectToPolygon( polysetref, wxPoint( 0, 0 ), aRefPad->GetSize(),
|
||||||
aRefPad->GetOrientation(),
|
aRefPad->GetOrientation(),
|
||||||
padRadius, aRefPad->GetChamferRectRatio(),
|
padRadius, aRefPad->GetChamferRectRatio(),
|
||||||
aRefPad->GetChamferPositions(), 64 );
|
aRefPad->GetChamferPositions(), ARC_HIGH_DEF );
|
||||||
}
|
}
|
||||||
else if( aRefPad->GetShape() == PAD_SHAPE_CUSTOM )
|
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(),
|
TransformRoundChamferedRectToPolygon( polysetcompare, relativePadPos, aPad->GetSize(),
|
||||||
aPad->GetOrientation(),
|
aPad->GetOrientation(),
|
||||||
padRadius, aPad->GetChamferRectRatio(),
|
padRadius, aPad->GetChamferRectRatio(),
|
||||||
aPad->GetChamferPositions(), 64 );
|
aPad->GetChamferPositions(), ARC_HIGH_DEF );
|
||||||
}
|
}
|
||||||
else if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
|
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(),
|
TransformRoundChamferedRectToPolygon( polyset, m_padToTestPos, aPad->GetSize(),
|
||||||
aPad->GetOrientation(),
|
aPad->GetOrientation(),
|
||||||
padRadius, aPad->GetChamferRectRatio(),
|
padRadius, aPad->GetChamferRectRatio(),
|
||||||
aPad->GetChamferPositions(), 64 );
|
aPad->GetChamferPositions(), ARC_HIGH_DEF );
|
||||||
// Rotate also coordinates by m_segmAngle, because the segment orient
|
// Rotate also coordinates by m_segmAngle, because the segment orient
|
||||||
// is m_segmAngle.
|
// is m_segmAngle.
|
||||||
// we are using a horizontal segment for test, because we know here
|
// 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:
|
case PAD_SHAPE_CHAMFERED_RECT:
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET polySet;
|
SHAPE_POLY_SET polySet;
|
||||||
int segmentToCircleCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
|
|
||||||
const int corner_radius = aPad->GetRoundRectCornerRadius( aPad->GetSize() );
|
const int corner_radius = aPad->GetRoundRectCornerRadius( aPad->GetSize() );
|
||||||
TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), 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;
|
std::vector< wxRealPoint > cornerList;
|
||||||
// TransformRoundChamferedRectToPolygon creates only one convex polygon
|
// TransformRoundChamferedRectToPolygon creates only one convex polygon
|
||||||
SHAPE_LINE_CHAIN poly( polySet.Outline( 0 ) );
|
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.
|
* 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) 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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++ )
|
for( unsigned ii = 1; ii < poly.size(); ii++ )
|
||||||
{
|
{
|
||||||
int numSegs = std::max(
|
|
||||||
GetArcToSegmentCount( bshape.m_Thickness / 2, aError, 360.0 ), 6 );
|
|
||||||
TransformRoundedEndsSegmentToPolygon(
|
TransformRoundedEndsSegmentToPolygon(
|
||||||
aux_polyset, poly[ii - 1], poly[ii], numSegs, bshape.m_Thickness );
|
aux_polyset, poly[ii - 1], poly[ii], aError, bshape.m_Thickness );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case S_SEGMENT: // usual segment : line with rounded ends
|
case S_SEGMENT: // usual segment : line with rounded ends
|
||||||
{
|
{
|
||||||
int numSegs =
|
|
||||||
std::max( GetArcToSegmentCount( bshape.m_Thickness / 2, aError, 360.0 ), 6 );
|
|
||||||
TransformRoundedEndsSegmentToPolygon(
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case S_ARC: // Arc with rounded ends
|
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,
|
TransformArcToPolygon( aux_polyset, bshape.m_Start, bshape.m_End, bshape.m_ArcAngle,
|
||||||
numSegs, bshape.m_Thickness );
|
aError, bshape.m_Thickness );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case S_CIRCLE: // ring or circle
|
case S_CIRCLE: // ring or circle
|
||||||
{
|
{
|
||||||
int numSegs = std::max( GetArcToSegmentCount( bshape.m_Radius, aError, 360.0 ), 6 );
|
|
||||||
if( bshape.m_Thickness ) // ring
|
if( bshape.m_Thickness ) // ring
|
||||||
TransformRingToPolygon(
|
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
|
else // Filled circle
|
||||||
TransformCircleToPolygon( aux_polyset, bshape.m_Start, bshape.m_Radius, numSegs );
|
TransformCircleToPolygon( aux_polyset, bshape.m_Start, bshape.m_Radius, aError );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,12 +318,8 @@ bool D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case PAD_SHAPE_CIRCLE:
|
case PAD_SHAPE_CIRCLE:
|
||||||
{
|
TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, ARC_HIGH_DEF );
|
||||||
int numSegs = std::max( GetArcToSegmentCount( GetSize().x / 2, ARC_HIGH_DEF, 360.0 ), 6 );
|
|
||||||
TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, numSegs );
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case PAD_SHAPE_RECT:
|
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(),
|
TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
|
||||||
corner_radius, GetChamferRectRatio(),
|
corner_radius, GetChamferRectRatio(),
|
||||||
doChamfer ? GetChamferPositions() : 0,
|
doChamfer ? GetChamferPositions() : 0,
|
||||||
SEGCOUNT );
|
ARC_HIGH_DEF );
|
||||||
|
|
||||||
// Draw the polygon: Inflate creates only one convex polygon
|
// Draw the polygon: Inflate creates only one convex polygon
|
||||||
bool filled = aDrawInfo.m_ShowPadFilled;
|
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(),
|
TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
|
||||||
corner_radius, GetChamferRectRatio(),
|
corner_radius, GetChamferRectRatio(),
|
||||||
doChamfer ? GetChamferPositions() : 0,
|
doChamfer ? GetChamferPositions() : 0,
|
||||||
SEGCOUNT );
|
ARC_HIGH_DEF );
|
||||||
|
|
||||||
// Draw the polygon: Inflate creates only one convex polygon
|
// Draw the polygon: Inflate creates only one convex polygon
|
||||||
SHAPE_LINE_CHAIN& clearance_poly = outline.Outline( 0 );
|
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;
|
SHAPE_POLY_SET polySet;
|
||||||
wxSize prsize( size.x * 2, size.y * 2 ); // size is the half pad area size)
|
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 );
|
const int corner_radius = aPad->GetRoundRectCornerRadius( prsize );
|
||||||
bool doChamfer = shape == PAD_SHAPE_CHAMFERED_RECT;
|
bool doChamfer = shape == PAD_SHAPE_CHAMFERED_RECT;
|
||||||
|
|
||||||
TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
|
TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
|
||||||
0.0, corner_radius, aPad->GetChamferRectRatio(),
|
0.0, corner_radius, aPad->GetChamferRectRatio(),
|
||||||
doChamfer ? aPad->GetChamferPositions() : 0, segmentToCircleCount );
|
doChamfer ? aPad->GetChamferPositions() : 0, ARC_HIGH_DEF );
|
||||||
m_gal->DrawPolygon( polySet );
|
m_gal->DrawPolygon( polySet );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,11 +184,10 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPl
|
||||||
case PAD_SHAPE_CHAMFERED_RECT:
|
case PAD_SHAPE_CHAMFERED_RECT:
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET polygons;
|
SHAPE_POLY_SET polygons;
|
||||||
const int segmentToCircleCount = 64;
|
|
||||||
const int corner_radius = aPad->GetRoundRectCornerRadius( aPad->GetSize() );
|
const int corner_radius = aPad->GetRoundRectCornerRadius( aPad->GetSize() );
|
||||||
TransformRoundChamferedRectToPolygon( polygons, shape_pos, aPad->GetSize(),
|
TransformRoundChamferedRectToPolygon( polygons, shape_pos, aPad->GetSize(),
|
||||||
aPad->GetOrientation(), corner_radius, aPad->GetChamferRectRatio(),
|
aPad->GetOrientation(), corner_radius, aPad->GetChamferRectRatio(),
|
||||||
aPad->GetChamferPositions(), segmentToCircleCount );
|
aPad->GetChamferPositions(), ARC_HIGH_DEF );
|
||||||
|
|
||||||
if( polygons.OutlineCount() == 0 )
|
if( polygons.OutlineCount() == 0 )
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -517,7 +517,7 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
||||||
0, rradius,
|
0, rradius,
|
||||||
aPad->GetChamferRectRatio(),
|
aPad->GetChamferRectRatio(),
|
||||||
doChamfer ? aPad->GetChamferPositions() : 0,
|
doChamfer ? aPad->GetChamferPositions() : 0,
|
||||||
circleToSegmentsCount );
|
ARC_HIGH_DEF );
|
||||||
SHAPE_LINE_CHAIN& polygonal_shape = cornerBuffer.Outline( 0 );
|
SHAPE_LINE_CHAIN& polygonal_shape = cornerBuffer.Outline( 0 );
|
||||||
|
|
||||||
for( int ndx=0; ndx < reportedLayers; ++ndx )
|
for( int ndx=0; ndx < reportedLayers; ++ndx )
|
||||||
|
|
Loading…
Reference in New Issue