Pcbnew: add a new primitive pad shape: chamfered round rect pad.
Allows 0 to 4 chamfered corners, not only one. A custom shape allow this kind of shape. However because it is a primitive, it is easier to edit and it support thermal reliefs.
This commit is contained in:
parent
d25d62295a
commit
d259459a14
|
@ -491,6 +491,25 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
|
|||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
{
|
||||
wxSize shapesize( aPad->GetSize() );
|
||||
shapesize.x += aClearanceValue.x * 2;
|
||||
shapesize.y += aClearanceValue.y * 2;
|
||||
|
||||
SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
|
||||
|
||||
int corner_radius = aPad->GetRoundRectCornerRadius( shapesize );
|
||||
TransformRoundChamferedRectToPolygon( polyList, PadShapePos, shapesize, aPad->GetOrientation(),
|
||||
corner_radius, aPad->GetChamferRectRatio(),
|
||||
aPad->GetChamferPositions(), 32 );
|
||||
|
||||
// Add the PAD polygon
|
||||
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits, *aPad );
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
{
|
||||
SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
|
||||
|
@ -575,6 +594,7 @@ void CINFO3D_VISU::createNewPad( const D_PAD* aPad,
|
|||
case PAD_SHAPE_CIRCLE:
|
||||
case PAD_SHAPE_OVAL:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
createNewPadWithClearance( aPad, aDstContainer, aInflateValue );
|
||||
break;
|
||||
|
|
|
@ -52,6 +52,7 @@ void CINFO3D_VISU::buildPadShapePolygon( const D_PAD* aPad,
|
|||
case PAD_SHAPE_CIRCLE:
|
||||
case PAD_SHAPE_OVAL:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
{
|
||||
// We are using TransformShapeWithClearanceToPolygon to build the shape.
|
||||
// Currently, this method uses only the same inflate value for X and Y dirs.
|
||||
|
|
|
@ -207,24 +207,19 @@ void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
|
|||
aCenters[ii] += aPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function TransformRoundRectToPolygon
|
||||
* convert a rectangle with rounded corners to a polygon
|
||||
* Convert arcs to multiple straight lines
|
||||
* @param aCornerBuffer = a buffer to store the polygon
|
||||
* @param aPosition = the coordinate of the center of the rectangle
|
||||
* @param aSize = the size of the rectangle
|
||||
* @param aCornerRadius = radius of rounded corners
|
||||
* @param aRotation = rotation in 0.1 degrees of the rectangle
|
||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||
*/
|
||||
void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||
|
||||
void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||
const wxPoint& aPosition, const wxSize& aSize,
|
||||
double aRotation, int aCornerRadius,
|
||||
double aChamferRatio, int aChamferCorners,
|
||||
int aCircleToSegmentsCount )
|
||||
{
|
||||
// Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
|
||||
// or in actual position/orientation for round rect only
|
||||
wxPoint corners[4];
|
||||
GetRoundRectCornerCenters( corners, aCornerRadius, aPosition, aSize, aRotation );
|
||||
GetRoundRectCornerCenters( corners, aCornerRadius,
|
||||
aChamferCorners ? wxPoint( 0, 0 ) : aPosition,
|
||||
aSize, aChamferCorners ? 0.0 : aRotation );
|
||||
|
||||
SHAPE_POLY_SET outline;
|
||||
outline.NewOutline();
|
||||
|
@ -234,6 +229,68 @@ void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
|
||||
outline.Inflate( aCornerRadius, aCircleToSegmentsCount );
|
||||
|
||||
if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
|
||||
{
|
||||
// Add the outline:
|
||||
aCornerBuffer.Append( outline );
|
||||
return;
|
||||
}
|
||||
|
||||
// Now we have the round rect outline, in position 0,0 orientation 0.0.
|
||||
// Chamfer the corner(s).
|
||||
int chamfer_value = aChamferRatio * std::min( aSize.x, aSize.y );
|
||||
|
||||
SHAPE_POLY_SET chamfered_corner; // corner shape for the current corner to chamfer
|
||||
|
||||
int corner_id[4] =
|
||||
{
|
||||
RECT_CHAMFER_TOP_LEFT, RECT_CHAMFER_TOP_RIGHT,
|
||||
RECT_CHAMFER_BOTTOM_LEFT, RECT_CHAMFER_BOTTOM_RIGHT
|
||||
};
|
||||
// Depending on the corner position, signX[] and signY[] give the sign of chamfer
|
||||
// coordinates relative to the corner position
|
||||
// The first corner is the top left corner, then top right, bottom left and bottom right
|
||||
int signX[4] = {1, -1, 1,-1 };
|
||||
int signY[4] = {1, 1, -1,-1 };
|
||||
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
if( (corner_id[ii] & aChamferCorners) == 0 )
|
||||
continue;
|
||||
|
||||
VECTOR2I corner_pos( -signX[ii]*aSize.x/2, -signY[ii]*aSize.y/2 );
|
||||
|
||||
if( aCornerRadius )
|
||||
{
|
||||
// We recreate a rectangular area covering the full rounded corner (max size = aSize/2)
|
||||
// to rebuild the corner before chamfering, to be sure the rounded corner shape does not
|
||||
// overlap the chamfered corner shape:
|
||||
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.Move( corner_pos );
|
||||
outline.BooleanAdd( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
}
|
||||
|
||||
// Now chamfer this corner
|
||||
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.Move( corner_pos );
|
||||
outline.BooleanSubtract( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
}
|
||||
|
||||
// Rotate and move the outline:
|
||||
if( aRotation != 0.0 )
|
||||
outline.Rotate( DECIDEG2RAD( -aRotation ), VECTOR2I( 0, 0 ) );
|
||||
|
||||
outline.Move( VECTOR2I( aPosition ) );
|
||||
|
||||
// Add the outline:
|
||||
aCornerBuffer.Append( outline );
|
||||
}
|
||||
|
|
|
@ -44,8 +44,11 @@ blind
|
|||
blind_buried_vias_allowed
|
||||
bold
|
||||
bottom
|
||||
bottom_left
|
||||
bottom_right
|
||||
center
|
||||
chamfer
|
||||
chamfer_ratio
|
||||
circle
|
||||
clearance
|
||||
comment
|
||||
|
@ -176,6 +179,8 @@ thermal_gap
|
|||
thermal_bridge_width
|
||||
thickness
|
||||
top
|
||||
top_left
|
||||
top_right
|
||||
trace_width
|
||||
tracks
|
||||
trace_min
|
||||
|
|
|
@ -747,8 +747,8 @@ void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize
|
|||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
const int segmentToCircleCount = 64;
|
||||
TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
|
||||
aCornerRadius, segmentToCircleCount );
|
||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
|
||||
aCornerRadius, 0.0, 0, segmentToCircleCount );
|
||||
|
||||
// TransformRoundRectToPolygon creates only one convex polygon
|
||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
||||
|
|
|
@ -842,8 +842,8 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
|
|||
// TODO: use Aperture macro and flash it
|
||||
SHAPE_POLY_SET outline;
|
||||
const int segmentToCircleCount = 64;
|
||||
TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
|
||||
aCornerRadius, segmentToCircleCount );
|
||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
|
||||
aCornerRadius, 0.0, 0, segmentToCircleCount );
|
||||
|
||||
if( aTraceMode != FILLED )
|
||||
outline.Inflate( -GetCurrentLineWidth()/2, 16 );
|
||||
|
|
|
@ -642,8 +642,8 @@ void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSiz
|
|||
aCornerRadius = std::min( aCornerRadius, std::min( size.x, size.y ) /2 );
|
||||
}
|
||||
|
||||
TransformRoundRectToPolygon( outline, aPadPos, size, aOrient,
|
||||
aCornerRadius, segmentToCircleCount );
|
||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
|
||||
aCornerRadius, 0.0, 0, segmentToCircleCount );
|
||||
|
||||
// TransformRoundRectToPolygon creates only one convex polygon
|
||||
std::vector< wxPoint > cornerList;
|
||||
|
|
|
@ -201,8 +201,8 @@ void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
|
|||
|
||||
SHAPE_POLY_SET outline;
|
||||
const int segmentToCircleCount = 64;
|
||||
TransformRoundRectToPolygon( outline, aPadPos, size, aOrient,
|
||||
aCornerRadius, segmentToCircleCount );
|
||||
TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient,
|
||||
aCornerRadius, 0.0, 0, segmentToCircleCount );
|
||||
|
||||
std::vector< wxPoint > cornerList;
|
||||
cornerList.reserve( segmentToCircleCount + 5 );
|
||||
|
|
|
@ -36,6 +36,21 @@
|
|||
#include <macros.h>
|
||||
|
||||
#include <geometry/shape_poly_set.h>
|
||||
|
||||
// The chamfer positions of chamfered rect shape.
|
||||
// the position is relative to a pad with orientation = 0
|
||||
// we can have 1 to 4 chamfered corners (0 corner = roundrect)
|
||||
// The position list is the OR of corner to chamfer
|
||||
enum RECT_CHAMFER_POSITIONS
|
||||
{
|
||||
RECT_NO_CHAMFER = 0,
|
||||
RECT_CHAMFER_TOP_LEFT = 1,
|
||||
RECT_CHAMFER_TOP_RIGHT = 2,
|
||||
RECT_CHAMFER_BOTTOM_LEFT = 4,
|
||||
RECT_CHAMFER_BOTTOM_RIGHT = 8,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function TransformCircleToPolygon
|
||||
* convert a circle to a polygon, using multiple straight lines
|
||||
|
@ -86,20 +101,29 @@ void TransformOvalClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
|
||||
const wxPoint& aPosition, const wxSize& aSize, double aRotation );
|
||||
|
||||
|
||||
/**
|
||||
* Function TransformRoundRectToPolygon
|
||||
* convert a rectangle with rounded corners to a polygon
|
||||
* Convert arcs to multiple straight lines
|
||||
* convert a rectangle with rounded corners and/or chamfered corners to a polygon
|
||||
* Convert rounded corners arcs to multiple straight lines
|
||||
* @param aCornerBuffer = a buffer to store the polygon
|
||||
* @param aPosition = the coordinate of the center of the rectangle
|
||||
* @param aSize = the size of the rectangle
|
||||
* @param aCornerRadius = radius of rounded corners
|
||||
* @param aCornerRadius = radius of rounded corners (can be 0)
|
||||
* @param aRotation = rotation in 0.1 degrees of the rectangle
|
||||
* @param aChamferRatio = ratio between smaller rect size and chamfer value
|
||||
* @param aChamferCorners = identifier of the corners to chamfer:
|
||||
* 0 = no chamfer
|
||||
* 1 = TOP_LEFT
|
||||
* 2 = TOP_RIGHT
|
||||
* 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
|
||||
*/
|
||||
void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||
void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||
const wxPoint& aPosition, const wxSize& aSize,
|
||||
double aRotation, int aCornerRadius,
|
||||
double aChamferRatio, int aChamferCorners,
|
||||
int aCircleToSegmentsCount );
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,7 @@ enum PAD_SHAPE_T
|
|||
PAD_SHAPE_OVAL,
|
||||
PAD_SHAPE_TRAPEZOID,
|
||||
PAD_SHAPE_ROUNDRECT,
|
||||
PAD_SHAPE_CHAMFERED_RECT, // Rectangle with a champered corner ( and with rounded other corners)
|
||||
PAD_SHAPE_CUSTOM // A shape defined by user, using a set of basic shapes
|
||||
// (thick segments, circles, arcs, polygons
|
||||
};
|
||||
|
|
|
@ -767,18 +767,22 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
int pad_radius = GetRoundRectCornerRadius();
|
||||
int clearance = int( aClearanceValue * aCorrectionFactor );
|
||||
int rounding_radius = pad_radius + clearance;
|
||||
int rounding_radius = GetRoundRectCornerRadius() + clearance;
|
||||
wxSize shapesize( m_Size );
|
||||
shapesize.x += clearance*2;
|
||||
shapesize.y += clearance*2;
|
||||
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
||||
|
||||
TransformRoundRectToPolygon( outline, padShapePos, shapesize, angle,
|
||||
rounding_radius, aCircleToSegmentsCount );
|
||||
TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle,
|
||||
rounding_radius,
|
||||
doChamfer ? GetChamferRectRatio() : 0.0,
|
||||
doChamfer ? GetChamferPositions() : 0,
|
||||
aCircleToSegmentsCount );
|
||||
|
||||
aCornerBuffer.Append( outline );
|
||||
}
|
||||
|
@ -819,6 +823,7 @@ void D_PAD::BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
case PAD_SHAPE_CIRCLE:
|
||||
case PAD_SHAPE_OVAL:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
{
|
||||
// We are using TransformShapeWithClearanceToPolygon to build the shape.
|
||||
// Currently, this method uses only the same inflate value for X and Y dirs.
|
||||
|
@ -1172,7 +1177,8 @@ void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_ROUNDRECT: // thermal shape is the same for round rect and rect.
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT: // thermal shape is the same for rectangular shapes.
|
||||
case PAD_SHAPE_RECT:
|
||||
{
|
||||
/* we create 4 copper holes and put them in position 1, 2, 3 and 4
|
||||
|
|
|
@ -78,11 +78,14 @@ D_PAD::D_PAD( MODULE* parent ) :
|
|||
m_LocalSolderPasteMargin = 0;
|
||||
m_LocalSolderPasteMarginRatio = 0.0;
|
||||
// Parameters for round rect only:
|
||||
m_padRoundRectRadiusScale = 0.25; // from IPC-7351C standard
|
||||
m_padRoundRectRadiusScale = 0.25; // from IPC-7351C standard
|
||||
// Parameters for chamfered rect only:
|
||||
m_padChamferRectScale = 0.2; // Size of chamfer: ratio of smallest of X,Y size
|
||||
m_chamferPositions = RECT_NO_CHAMFER; // No chamfered corner
|
||||
|
||||
m_ZoneConnection = PAD_ZONE_CONN_INHERITED; // Use parent setting by default
|
||||
m_ThermalWidth = 0; // Use parent setting by default
|
||||
m_ThermalGap = 0; // Use parent setting by default
|
||||
m_ZoneConnection = PAD_ZONE_CONN_INHERITED; // Use parent setting by default
|
||||
m_ThermalWidth = 0; // Use parent setting by default
|
||||
m_ThermalGap = 0; // Use parent setting by default
|
||||
|
||||
m_customShapeClearanceArea = CUST_PAD_SHAPE_IN_ZONE_OUTLINE;
|
||||
|
||||
|
@ -169,6 +172,14 @@ int D_PAD::boundingRadius() const
|
|||
radius += 1 + KiROUND( EuclideanNorm( wxSize( x - radius, y - radius )));
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
radius = GetRoundRectCornerRadius();
|
||||
x = m_Size.x >> 1;
|
||||
y = m_Size.y >> 1;
|
||||
radius += 1 + KiROUND( EuclideanNorm( wxSize( x - radius, y - radius )));
|
||||
// TODO: modify radius if the chamfer is smaller than corner radius
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
radius = 0;
|
||||
|
||||
|
@ -293,6 +304,7 @@ const EDA_RECT D_PAD::GetBoundingBox() const
|
|||
|
||||
case PAD_SHAPE_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
// Use two opposite corners and track their rotation
|
||||
// (use symmetry for other points)
|
||||
quadrant1.x = m_Size.x/2;
|
||||
|
@ -919,17 +931,23 @@ bool D_PAD::HitTest( const wxPoint& aPosition ) const
|
|||
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
{
|
||||
{
|
||||
// Check for hit in polygon
|
||||
SHAPE_POLY_SET outline;
|
||||
const int segmentToCircleCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
|
||||
TransformRoundRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
|
||||
GetRoundRectCornerRadius(), segmentToCircleCount );
|
||||
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
||||
|
||||
TransformRoundChamferedRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
|
||||
GetRoundRectCornerRadius(),
|
||||
doChamfer ? GetChamferRectRatio() : 0.0,
|
||||
doChamfer ? GetChamferPositions() : 0,
|
||||
segmentToCircleCount );
|
||||
|
||||
const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
|
||||
return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
|
@ -978,6 +996,7 @@ bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) con
|
|||
return arect.IntersectsCircle( GetPosition(), GetBoundingRadius() );
|
||||
|
||||
case PAD_SHAPE_RECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT: // TODO use a finer shape analysis
|
||||
shapeRect.SetOrigin( shapePos );
|
||||
shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 );
|
||||
return arect.Intersects( shapeRect, m_Orient );
|
||||
|
@ -1082,8 +1101,6 @@ bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) con
|
|||
* b) Test intersection of vertical rect
|
||||
* c) Test intersection of each corner
|
||||
*/
|
||||
|
||||
|
||||
r = GetRoundRectCornerRadius();
|
||||
|
||||
/* Test A - intersection of horizontal rect */
|
||||
|
@ -1224,6 +1241,9 @@ wxString D_PAD::ShowPadShape() const
|
|||
case PAD_SHAPE_ROUNDRECT:
|
||||
return _( "Roundrect" );
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
return _( "Chamferedrect" );
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
return _( "CustomShape" );
|
||||
|
||||
|
|
|
@ -658,6 +658,48 @@ public:
|
|||
m_padRoundRectRadiusScale = std::min( aRadiusScale, 0.5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* has meaning only for chamfered rect pads
|
||||
* @return the ratio between the smaller Y or Y size and the radius
|
||||
* of the rounded corners.
|
||||
* Cannot be > 0.5
|
||||
*/
|
||||
double GetChamferRectRatio() const
|
||||
{
|
||||
return m_padChamferRectScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* has meaning only for chamfered rect pads
|
||||
* Set the ratio between the smaller Y or Y size and the radius
|
||||
* of the rounded corners.
|
||||
* Cannot be < 0.5 and obviously must be > 0
|
||||
*/
|
||||
void SetChamferRectRatio( double aChamferScale )
|
||||
{
|
||||
if( aChamferScale < 0.0 )
|
||||
aChamferScale = 0.0;
|
||||
|
||||
m_padChamferRectScale = std::min( aChamferScale, 0.5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* has meaning only for chamfered rect pads
|
||||
* @return the position of the chamfer for a 0 orientation
|
||||
*/
|
||||
int GetChamferPositions() const { return m_chamferPositions; }
|
||||
|
||||
/**
|
||||
* has meaning only for chamfered rect pads
|
||||
* set the position of the chamfer for a 0 orientation, one of
|
||||
* PAD_CHAMFER_TOP_LEFT, PAD_CHAMFER_TOP_RIGHT,
|
||||
* PAD_CHAMFER_BOTTOM_LEFT, PAD_CHAMFER_BOTTOM_RIGHT
|
||||
*/
|
||||
void SetChamferPositions( int aChamferPositions )
|
||||
{
|
||||
m_chamferPositions = aChamferPositions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetSubRatsnest
|
||||
* @return int - the netcode
|
||||
|
@ -835,6 +877,9 @@ private: // Private variable members:
|
|||
|
||||
double m_padRoundRectRadiusScale; ///< scaling factor from smallest m_Size coord
|
||||
///< to corner radius, default 0.25
|
||||
double m_padChamferRectScale; ///< scaling factor from smallest m_Size coord
|
||||
///< to chamfer value, default 0.25
|
||||
int m_chamferPositions; ///< the positions of the chamfered position for a 0 orientation
|
||||
|
||||
PAD_SHAPE_T m_anchorPadShape; ///< for custom shaped pads: shape of pad anchor,
|
||||
///< PAD_SHAPE_RECT, PAD_SHAPE_CIRCLE
|
||||
|
|
|
@ -43,9 +43,13 @@
|
|||
#include <pcb_painter.h>
|
||||
#include <widgets/net_selector.h>
|
||||
|
||||
#include <dialog_pad_properties.h>
|
||||
|
||||
#include <dialog_pad_properties.h>
|
||||
#include <html_messagebox.h>
|
||||
|
||||
#include <convert_basic_shapes_to_polygon.h> // for enum RECT_CHAMFER_POSITIONS definition
|
||||
|
||||
|
||||
// list of pad shapes, ordered like the pad shape wxChoice in dialog.
|
||||
static PAD_SHAPE_T code_shape[] =
|
||||
|
@ -55,6 +59,7 @@ static PAD_SHAPE_T code_shape[] =
|
|||
PAD_SHAPE_RECT,
|
||||
PAD_SHAPE_TRAPEZOID,
|
||||
PAD_SHAPE_ROUNDRECT,
|
||||
PAD_SHAPE_CHAMFERED_RECT,
|
||||
PAD_SHAPE_CUSTOM, // choice = CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR
|
||||
PAD_SHAPE_CUSTOM // choice = PAD_SHAPE_CUSTOM_RECT_ANCHOR
|
||||
};
|
||||
|
@ -68,6 +73,7 @@ enum CODE_CHOICE
|
|||
CHOICE_SHAPE_RECT,
|
||||
CHOICE_SHAPE_TRAPEZOID,
|
||||
CHOICE_SHAPE_ROUNDRECT,
|
||||
CHOICE_SHAPE_CHAMFERED_RECT,
|
||||
CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR,
|
||||
CHOICE_SHAPE_CUSTOM_RECT_ANCHOR
|
||||
};
|
||||
|
@ -452,11 +458,15 @@ void DIALOG_PAD_PROPERTIES::updateRoundRectCornerValues()
|
|||
{
|
||||
// Note: use m_tcCornerSizeRatio->ChangeValue() to avoid generating a wxEVT_TEXT event
|
||||
|
||||
if( m_dummyPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
||||
if( m_dummyPad->GetShape() == PAD_SHAPE_ROUNDRECT ||
|
||||
m_dummyPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT )
|
||||
{
|
||||
auto ratio = wxString::Format( "%.1f", m_dummyPad->GetRoundRectRadiusRatio() * 100 );
|
||||
m_tcCornerSizeRatio->ChangeValue( ratio );
|
||||
m_cornerRadius.SetValue( m_dummyPad->GetRoundRectCornerRadius() );
|
||||
|
||||
ratio = wxString::Format( "%.1f", m_dummyPad->GetChamferRectRatio() * 100 );
|
||||
m_tcChamferRatio->ChangeValue( ratio );
|
||||
}
|
||||
else if( m_dummyPad->GetShape() == PAD_SHAPE_RECT )
|
||||
{
|
||||
|
@ -473,7 +483,8 @@ void DIALOG_PAD_PROPERTIES::updateRoundRectCornerValues()
|
|||
|
||||
void DIALOG_PAD_PROPERTIES::onCornerRadiusChange( wxCommandEvent& event )
|
||||
{
|
||||
if( m_dummyPad->GetShape() != PAD_SHAPE_ROUNDRECT )
|
||||
if( m_dummyPad->GetShape() != PAD_SHAPE_ROUNDRECT &&
|
||||
m_dummyPad->GetShape() != PAD_SHAPE_CHAMFERED_RECT )
|
||||
return;
|
||||
|
||||
wxString value = m_tcCornerRadius->GetValue();
|
||||
|
@ -499,27 +510,55 @@ void DIALOG_PAD_PROPERTIES::onCornerRadiusChange( wxCommandEvent& event )
|
|||
|
||||
void DIALOG_PAD_PROPERTIES::onCornerSizePercentChange( wxCommandEvent& event )
|
||||
{
|
||||
if( m_dummyPad->GetShape() != PAD_SHAPE_ROUNDRECT )
|
||||
if( m_dummyPad->GetShape() != PAD_SHAPE_ROUNDRECT &&
|
||||
m_dummyPad->GetShape() != PAD_SHAPE_CHAMFERED_RECT )
|
||||
return;
|
||||
|
||||
wxString value = m_tcCornerSizeRatio->GetValue();
|
||||
double rrRadiusRatioPercent;
|
||||
double ratioPercent;
|
||||
|
||||
if( value.ToDouble( &rrRadiusRatioPercent ) )
|
||||
bool asChanged = false;
|
||||
|
||||
if( value.ToDouble( &ratioPercent ) )
|
||||
{
|
||||
// Clamp rrRadiusRatioPercent to acceptable value (0.0 to 50.0)
|
||||
if( rrRadiusRatioPercent < 0.0 )
|
||||
// Clamp ratioPercent to acceptable value (0.0 to 50.0)
|
||||
if( ratioPercent < 0.0 )
|
||||
{
|
||||
rrRadiusRatioPercent = 0.0;
|
||||
ratioPercent = 0.0;
|
||||
m_tcCornerSizeRatio->ChangeValue( "0.0" );
|
||||
}
|
||||
|
||||
if( rrRadiusRatioPercent > 50.0 )
|
||||
if( ratioPercent > 50.0 )
|
||||
{
|
||||
rrRadiusRatioPercent = 0.5;
|
||||
ratioPercent = 0.5;
|
||||
m_tcCornerSizeRatio->ChangeValue( "50.0" );
|
||||
}
|
||||
|
||||
asChanged = true;
|
||||
}
|
||||
|
||||
value = m_tcChamferRatio->GetValue();
|
||||
|
||||
if( value.ToDouble( &ratioPercent ) )
|
||||
{
|
||||
// Clamp ratioPercent to acceptable value (0.0 to 50.0)
|
||||
if( ratioPercent < 0.0 )
|
||||
{
|
||||
ratioPercent = 0.0;
|
||||
m_tcChamferRatio->ChangeValue( "0.0" );
|
||||
}
|
||||
|
||||
if( ratioPercent > 50.0 )
|
||||
{
|
||||
ratioPercent = 0.5;
|
||||
m_tcChamferRatio->ChangeValue( "50.0" );
|
||||
}
|
||||
|
||||
asChanged = true;
|
||||
}
|
||||
|
||||
if( asChanged )
|
||||
{
|
||||
transferDataToPad( m_dummyPad );
|
||||
m_cornerRadius.ChangeValue( m_dummyPad->GetRoundRectCornerRadius() );
|
||||
redraw();
|
||||
|
@ -705,6 +744,7 @@ void DIALOG_PAD_PROPERTIES::initValues()
|
|||
case PAD_SHAPE_RECT: m_PadShape->SetSelection( CHOICE_SHAPE_RECT ); break;
|
||||
case PAD_SHAPE_TRAPEZOID: m_PadShape->SetSelection( CHOICE_SHAPE_TRAPEZOID ); break;
|
||||
case PAD_SHAPE_ROUNDRECT: m_PadShape->SetSelection( CHOICE_SHAPE_ROUNDRECT ); break;
|
||||
case PAD_SHAPE_CHAMFERED_RECT: m_PadShape->SetSelection( CHOICE_SHAPE_CHAMFERED_RECT ); break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
if( m_dummyPad->GetAnchorPadShape() == PAD_SHAPE_RECT )
|
||||
|
@ -714,6 +754,12 @@ void DIALOG_PAD_PROPERTIES::initValues()
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
m_cbTopLeft->SetValue( (m_dummyPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT) );
|
||||
m_cbTopRight->SetValue( (m_dummyPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT) );
|
||||
m_cbBottomLeft->SetValue( (m_dummyPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT) );
|
||||
m_cbBottomRight->SetValue( (m_dummyPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_RIGHT) );
|
||||
|
||||
enablePrimitivePage( PAD_SHAPE_CUSTOM == m_dummyPad->GetShape() );
|
||||
|
||||
// Type of pad selection
|
||||
|
@ -866,6 +912,7 @@ void DIALOG_PAD_PROPERTIES::onChangePadMode( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
|
||||
|
||||
void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
|
||||
{
|
||||
bool is_custom = false;
|
||||
|
@ -909,6 +956,7 @@ void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
|
|||
break;
|
||||
|
||||
case CHOICE_SHAPE_ROUNDRECT:
|
||||
case CHOICE_SHAPE_CHAMFERED_RECT:
|
||||
m_trapDelta.Enable( false );
|
||||
m_trapAxisLabel->Enable( false );
|
||||
m_trapAxisCtrl->Enable( false );
|
||||
|
@ -934,11 +982,20 @@ void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
|
|||
|
||||
enablePrimitivePage( is_custom );
|
||||
|
||||
// A few widgets are enabled only for rounded rect pads:
|
||||
m_staticTextCornerSizeRatio->Enable( m_PadShape->GetSelection() == CHOICE_SHAPE_ROUNDRECT );
|
||||
m_tcCornerSizeRatio->Enable( m_PadShape->GetSelection() == CHOICE_SHAPE_ROUNDRECT );
|
||||
m_staticTextCornerSizeRatioUnit->Enable( m_PadShape->GetSelection() == CHOICE_SHAPE_ROUNDRECT );
|
||||
m_cornerRadius.Enable( m_PadShape->GetSelection() == CHOICE_SHAPE_ROUNDRECT );
|
||||
// A few widgets are enabled only for rounded rect and chamfered pads:
|
||||
bool chamfered_rect_enable = m_PadShape->GetSelection() == CHOICE_SHAPE_CHAMFERED_RECT;
|
||||
bool round_rect_enable = m_PadShape->GetSelection() == CHOICE_SHAPE_ROUNDRECT ||
|
||||
chamfered_rect_enable;
|
||||
m_staticTextCornerSizeRatio->Enable( round_rect_enable );
|
||||
m_tcCornerSizeRatio->Enable( round_rect_enable );
|
||||
m_staticTextCornerSizeRatioUnit->Enable( round_rect_enable );
|
||||
m_cornerRadius.Enable( round_rect_enable );
|
||||
|
||||
m_cbTopLeft->Enable( chamfered_rect_enable );
|
||||
m_cbTopRight->Enable( chamfered_rect_enable );
|
||||
m_cbBottomLeft->Enable( chamfered_rect_enable );
|
||||
m_cbBottomRight->Enable( chamfered_rect_enable );
|
||||
m_tcChamferRatio->Enable( chamfered_rect_enable );
|
||||
|
||||
// PAD_SHAPE_CUSTOM type has constraints for zone connection and thermal shape:
|
||||
// only not connected or solid connection is allowed to avoid destroying the shape.
|
||||
|
@ -1223,7 +1280,8 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
}
|
||||
|
||||
|
||||
if( m_dummyPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
||||
if( m_dummyPad->GetShape() == PAD_SHAPE_ROUNDRECT ||
|
||||
m_dummyPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT )
|
||||
{
|
||||
wxString value = m_tcCornerSizeRatio->GetValue();
|
||||
double rrRadiusRatioPercent;
|
||||
|
@ -1494,6 +1552,8 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
|
|||
m_currentPad->SetThermalWidth( m_padMaster->GetThermalWidth() );
|
||||
m_currentPad->SetThermalGap( m_padMaster->GetThermalGap() );
|
||||
m_currentPad->SetRoundRectRadiusRatio( m_padMaster->GetRoundRectRadiusRatio() );
|
||||
m_currentPad->SetChamferRectRatio( m_padMaster->GetChamferRectRatio() );
|
||||
m_currentPad->SetChamferPositions( m_padMaster->GetChamferPositions() );
|
||||
|
||||
if( m_currentPad->GetShape() == PAD_SHAPE_CUSTOM )
|
||||
{
|
||||
|
@ -1664,6 +1724,22 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
|
|||
aPad->SetName( m_PadNumCtrl->GetValue() );
|
||||
aPad->SetNetCode( m_PadNetSelector->GetSelectedNetcode() );
|
||||
|
||||
int chamfers = 0;
|
||||
|
||||
if( m_cbTopLeft->GetValue() )
|
||||
chamfers |= RECT_CHAMFER_TOP_LEFT;
|
||||
|
||||
if( m_cbTopRight->GetValue() )
|
||||
chamfers |= RECT_CHAMFER_TOP_RIGHT;
|
||||
|
||||
if( m_cbBottomLeft->GetValue() )
|
||||
chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
|
||||
|
||||
if( m_cbBottomRight->GetValue() )
|
||||
chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
|
||||
|
||||
aPad->SetChamferPositions( chamfers );
|
||||
|
||||
// Clear some values, according to the pad type and shape
|
||||
switch( aPad->GetShape() )
|
||||
{
|
||||
|
@ -1684,6 +1760,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
|
|||
break;
|
||||
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
aPad->SetDelta( wxSize( 0, 0 ) );
|
||||
break;
|
||||
|
||||
|
@ -1737,13 +1814,18 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
|
|||
break;
|
||||
}
|
||||
|
||||
if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
||||
if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT || aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT )
|
||||
{
|
||||
wxString value = m_tcCornerSizeRatio->GetValue();
|
||||
double rrRadiusRatioPercent;
|
||||
double ratioPercent;
|
||||
|
||||
if( value.ToDouble( &rrRadiusRatioPercent ) )
|
||||
aPad->SetRoundRectRadiusRatio( rrRadiusRatioPercent / 100.0 );
|
||||
if( value.ToDouble( &ratioPercent ) )
|
||||
aPad->SetRoundRectRadiusRatio( ratioPercent / 100.0 );
|
||||
|
||||
value = m_tcChamferRatio->GetValue();
|
||||
|
||||
if( value.ToDouble( &ratioPercent ) )
|
||||
aPad->SetChamferRectRatio( ratioPercent / 100.0 );
|
||||
}
|
||||
|
||||
LSET padLayerMask;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,11 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Dec 30 2017)
|
||||
// C++ code generated with wxFormBuilder (version Dec 1 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DIALOG_PAD_PROPERTIES_BASE_H__
|
||||
#define __DIALOG_PAD_PROPERTIES_BASE_H__
|
||||
#pragma once
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
@ -25,12 +24,12 @@ class WX_GRID;
|
|||
#include <widgets/net_selector.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/statbmp.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/simplebook.h>
|
||||
|
@ -53,20 +52,20 @@ class WX_GRID;
|
|||
class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
wxID_DIALOG_EDIT_PAD = 1000,
|
||||
wxID_PADNUMCTRL
|
||||
};
|
||||
|
||||
|
||||
wxNotebook* m_notebook;
|
||||
wxPanel* m_panelGeneral;
|
||||
wxStaticText* m_PadNumText;
|
||||
wxTextCtrl* m_PadNumCtrl;
|
||||
wxStaticText* m_PadNameText;
|
||||
NET_SELECTOR* m_PadNetSelector;
|
||||
NET_SELECTOR* m_PadNetSelector;
|
||||
wxStaticText* m_staticText44;
|
||||
wxChoice* m_PadType;
|
||||
wxStaticText* m_staticText45;
|
||||
|
@ -106,6 +105,14 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
wxStaticText* m_cornerRadiusLabel;
|
||||
wxTextCtrl* m_tcCornerRadius;
|
||||
wxStaticText* m_cornerRadiusUnits;
|
||||
wxStaticText* m_staticTextChamferRatio;
|
||||
TEXT_CTRL_EVAL* m_tcChamferRatio;
|
||||
wxStaticText* m_staticTextChamferRatioUnit;
|
||||
wxStaticText* m_staticTextChamferCorner;
|
||||
wxCheckBox* m_cbTopLeft;
|
||||
wxCheckBox* m_cbTopRight;
|
||||
wxCheckBox* m_cbBottomLeft;
|
||||
wxCheckBox* m_cbBottomRight;
|
||||
wxStaticText* m_holeShapeLabel;
|
||||
wxChoice* m_holeShapeCtrl;
|
||||
wxStaticText* m_staticText51;
|
||||
|
@ -185,7 +192,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
|
||||
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
|
@ -208,13 +215,13 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
virtual void OnPaintShowPanel( wxPaintEvent& event ) { event.Skip(); }
|
||||
virtual void onChangePadMode( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
|
||||
DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~DIALOG_PAD_PROPERTIES_BASE();
|
||||
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -223,24 +230,24 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticTextPosStart;
|
||||
wxStaticText* m_startXLabel;
|
||||
wxTextCtrl* m_startXCtrl;
|
||||
TEXT_CTRL_EVAL* m_startXCtrl;
|
||||
wxStaticText* m_startXUnits;
|
||||
wxStaticText* m_startYLabel;
|
||||
wxTextCtrl* m_startYCtrl;
|
||||
TEXT_CTRL_EVAL* m_startYCtrl;
|
||||
wxStaticText* m_startYUnits;
|
||||
wxStaticText* m_staticTextPosEnd;
|
||||
wxStaticText* m_endXLabel;
|
||||
wxTextCtrl* m_endXCtrl;
|
||||
TEXT_CTRL_EVAL* m_endXCtrl;
|
||||
wxStaticText* m_endXUnits;
|
||||
wxStaticText* m_endYLabel;
|
||||
wxTextCtrl* m_endYCtrl;
|
||||
TEXT_CTRL_EVAL* m_endYCtrl;
|
||||
wxStaticText* m_endYUnits;
|
||||
wxStaticText* m_radiusLabel;
|
||||
wxTextCtrl* m_radiusCtrl;
|
||||
TEXT_CTRL_EVAL* m_radiusCtrl;
|
||||
wxStaticText* m_radiusUnits;
|
||||
wxStaticText* m_thicknessLabel;
|
||||
wxTextCtrl* m_thicknessCtrl;
|
||||
|
@ -250,12 +257,12 @@ class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
|
||||
DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE();
|
||||
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -264,17 +271,17 @@ class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE : public DIALOG_SHIM
|
|||
class DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticTextMove;
|
||||
wxStaticText* m_xLabel;
|
||||
wxTextCtrl* m_xCtrl;
|
||||
TEXT_CTRL_EVAL* m_xCtrl;
|
||||
wxStaticText* m_xUnits;
|
||||
wxStaticText* m_yLabel;
|
||||
wxTextCtrl* m_yCtrl;
|
||||
TEXT_CTRL_EVAL* m_yCtrl;
|
||||
wxStaticText* m_yUnits;
|
||||
wxStaticText* m_rotationLabel;
|
||||
wxTextCtrl* m_rotationCtrl;
|
||||
TEXT_CTRL_EVAL* m_rotationCtrl;
|
||||
wxStaticText* m_rotationUnits;
|
||||
wxStaticText* m_scaleLabel;
|
||||
TEXT_CTRL_EVAL* m_scaleCtrl;
|
||||
|
@ -284,12 +291,12 @@ class DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE : public DIALOG_SHIM
|
|||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pad Custom Shape Geometry Transform"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
|
||||
DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pad Custom Shape Geometry Transform"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE();
|
||||
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -298,13 +305,13 @@ class DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE : public DIALOG_SHIM
|
|||
class DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
protected:
|
||||
WX_GRID* m_gridCornersList;
|
||||
wxBitmapButton* m_addButton;
|
||||
wxBitmapButton* m_deleteButton;
|
||||
wxStaticText* m_thicknessLabel;
|
||||
wxTextCtrl* m_thicknessCtrl;
|
||||
TEXT_CTRL_EVAL* m_thicknessCtrl;
|
||||
wxStaticText* m_thicknessUnits;
|
||||
wxPanel* m_panelPoly;
|
||||
wxStaticBitmap* m_warningIcon;
|
||||
|
@ -315,7 +322,7 @@ class DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE : public DIALOG_SHIM
|
|||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void onGridSelect( wxGridRangeSelectEvent& event ) { event.Skip(); }
|
||||
virtual void onCellSelect( wxGridEvent& event ) { event.Skip(); }
|
||||
|
@ -323,13 +330,12 @@ class DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE : public DIALOG_SHIM
|
|||
virtual void OnButtonDelete( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onPaintPolyPanel( wxPaintEvent& event ) { event.Skip(); }
|
||||
virtual void onPolyPanelResize( wxSizeEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Basic Shape Polygon"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
|
||||
DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Basic Shape Polygon"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //__DIALOG_PAD_PROPERTIES_BASE_H__
|
||||
|
|
|
@ -898,7 +898,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
// priority is aRefPad = ROUND then OVAL then RECT/ROUNDRECT then other
|
||||
if( aRefPad->GetShape() != aPad->GetShape() && aRefPad->GetShape() != PAD_SHAPE_CIRCLE )
|
||||
{
|
||||
// pad ref shape is here oval, rect, roundrect, trapezoid or custom
|
||||
// pad ref shape is here oval, rect, roundrect, chamfered rect, trapezoid or custom
|
||||
switch( aPad->GetShape() )
|
||||
{
|
||||
case PAD_SHAPE_CIRCLE:
|
||||
|
@ -916,6 +916,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
break;
|
||||
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
break;
|
||||
}
|
||||
|
@ -962,6 +963,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_RECT:
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
// pad_angle = pad orient relative to the aRefPad orient
|
||||
|
@ -975,6 +977,17 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
GetRoundRectCornerCenters( polyref, padRadius, wxPoint( 0, 0 ),
|
||||
aRefPad->GetSize(), aRefPad->GetOrientation() );
|
||||
}
|
||||
else if( aRefPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT )
|
||||
{
|
||||
// The reference pad can be rotated. calculate the rotated
|
||||
// coordinates ( note, the ref pad position is the origin of
|
||||
// coordinates for this drc test)
|
||||
int padRadius = aRefPad->GetRoundRectCornerRadius();
|
||||
TransformRoundChamferedRectToPolygon( polysetref, wxPoint( 0, 0 ), aRefPad->GetSize(),
|
||||
aRefPad->GetOrientation(),
|
||||
padRadius, aRefPad->GetChamferRectRatio(),
|
||||
aRefPad->GetChamferPositions(), 64 );
|
||||
}
|
||||
else if( aRefPad->GetShape() == PAD_SHAPE_CUSTOM )
|
||||
{
|
||||
polysetref.Append( aRefPad->GetCustomShapeAsPolygon() );
|
||||
|
@ -996,6 +1009,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
{
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_RECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
||||
|
@ -1005,6 +1019,17 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
GetRoundRectCornerCenters( polycompare, padRadius, relativePadPos,
|
||||
aPad->GetSize(), aPad->GetOrientation() );
|
||||
}
|
||||
else if( aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT )
|
||||
{
|
||||
// The reference pad can be rotated. calculate the rotated
|
||||
// coordinates ( note, the ref pad position is the origin of
|
||||
// coordinates for this drc test)
|
||||
int padRadius = aPad->GetRoundRectCornerRadius();
|
||||
TransformRoundChamferedRectToPolygon( polysetcompare, relativePadPos, aPad->GetSize(),
|
||||
aPad->GetOrientation(),
|
||||
padRadius, aPad->GetChamferRectRatio(),
|
||||
aPad->GetChamferPositions(), 64 );
|
||||
}
|
||||
else if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
|
||||
{
|
||||
polysetcompare.Append( aPad->GetCustomShapeAsPolygon() );
|
||||
|
@ -1375,6 +1400,36 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
|
||||
const SHAPE_LINE_CHAIN& refpoly = polyset.COutline( 0 );
|
||||
|
||||
if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ),
|
||||
refpoly.PointCount(),
|
||||
wxPoint( 0, 0 ), wxPoint(m_segmLength,0),
|
||||
distToLine ) )
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
{
|
||||
SHAPE_POLY_SET polyset;
|
||||
// The pad can be rotated. calculate the coordinates
|
||||
// relatives to the segment being tested
|
||||
// Note, the pad position relative to the segment origin
|
||||
// is m_padToTestPos
|
||||
int padRadius = aPad->GetRoundRectCornerRadius();
|
||||
TransformRoundChamferedRectToPolygon( polyset, m_padToTestPos, aPad->GetSize(),
|
||||
aPad->GetOrientation(),
|
||||
padRadius, aPad->GetChamferRectRatio(),
|
||||
aPad->GetChamferPositions(), 64 );
|
||||
// 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
|
||||
// only the lenght and orientation of the segment
|
||||
// therefore all coordinates of the pad to test must be rotated by
|
||||
// m_segmAngle (they are already relative to the segment origin)
|
||||
polyset.Rotate( DECIDEG2RAD( -m_segmAngle ), VECTOR2I( 0, 0 ) );
|
||||
|
||||
const SHAPE_LINE_CHAIN& refpoly = polyset.COutline( 0 );
|
||||
|
||||
if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ),
|
||||
refpoly.PointCount(),
|
||||
wxPoint( 0, 0 ), wxPoint(m_segmLength,0),
|
||||
|
|
|
@ -1116,14 +1116,15 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P
|
|||
break;
|
||||
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
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() );
|
||||
TransformRoundRectToPolygon( polySet, wxPoint( 0, 0 ), aPad->GetSize(),
|
||||
0.0, corner_radius, segmentToCircleCount );
|
||||
TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), aPad->GetSize(),
|
||||
0.0, corner_radius, 0.0, 0, segmentToCircleCount );
|
||||
std::vector< wxRealPoint > cornerList;
|
||||
// TransformRoundRectToPolygon creates only one convex polygon
|
||||
// TransformRoundChamferedRectToPolygon creates only one convex polygon
|
||||
SHAPE_LINE_CHAIN poly( polySet.Outline( 0 ) );
|
||||
|
||||
for( int ii = 0; ii < poly.PointCount(); ++ii )
|
||||
|
@ -1170,7 +1171,7 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P
|
|||
pad_dy = 0;
|
||||
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
{
|
||||
{
|
||||
double coord[8] =
|
||||
{
|
||||
-pad_w + pad_dy, -pad_h - pad_dx,
|
||||
|
@ -1209,10 +1210,7 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P
|
|||
throw( std::runtime_error( aTinLayer->GetError() ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <boost/ptr_container/ptr_map.hpp>
|
||||
#include <memory.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <convert_basic_shapes_to_polygon.h> // for enum RECT_CHAMFER_POSITIONS definition
|
||||
|
||||
using namespace PCB_KEYS_T;
|
||||
|
||||
|
@ -1248,12 +1249,13 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
|
|||
|
||||
switch( aPad->GetShape() )
|
||||
{
|
||||
case PAD_SHAPE_CIRCLE: shape = "circle"; break;
|
||||
case PAD_SHAPE_RECT: shape = "rect"; break;
|
||||
case PAD_SHAPE_OVAL: shape = "oval"; break;
|
||||
case PAD_SHAPE_TRAPEZOID: shape = "trapezoid"; break;
|
||||
case PAD_SHAPE_ROUNDRECT: shape = "roundrect"; break;
|
||||
case PAD_SHAPE_CUSTOM: shape = "custom"; break;
|
||||
case PAD_SHAPE_CIRCLE: shape = "circle"; break;
|
||||
case PAD_SHAPE_RECT: shape = "rect"; break;
|
||||
case PAD_SHAPE_OVAL: shape = "oval"; break;
|
||||
case PAD_SHAPE_TRAPEZOID: shape = "trapezoid"; break;
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT: shape = "roundrect"; break;
|
||||
case PAD_SHAPE_CUSTOM: shape = "custom"; break;
|
||||
|
||||
default:
|
||||
THROW_IO_ERROR( wxString::Format( _( "unknown pad type: %d"), aPad->GetShape() ) );
|
||||
|
@ -1311,13 +1313,38 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
|
|||
|
||||
formatLayers( aPad->GetLayerSet() );
|
||||
|
||||
// Output the radius ratio for rounded rect pads
|
||||
if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
||||
// Output the radius ratio for rounded and chamfered rect pads
|
||||
if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT || aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT)
|
||||
{
|
||||
m_out->Print( 0, " (roundrect_rratio %s)",
|
||||
Double2Str( aPad->GetRoundRectRadiusRatio() ).c_str() );
|
||||
}
|
||||
|
||||
// Output the chamfer corners for chamfered rect pads
|
||||
if( aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT)
|
||||
{
|
||||
m_out->Print( 0, "\n" );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(chamfer_ratio %s)",
|
||||
Double2Str( aPad->GetChamferRectRatio() ).c_str() );
|
||||
|
||||
m_out->Print( 0, " (chamfer" );
|
||||
|
||||
if( ( aPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT ) )
|
||||
m_out->Print( 0, " top_left" );
|
||||
|
||||
if( ( aPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT ) )
|
||||
m_out->Print( 0, " top_right" );
|
||||
|
||||
if( ( aPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT ) )
|
||||
m_out->Print( 0, " bottom_left" );
|
||||
|
||||
if( ( aPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_RIGHT ) )
|
||||
m_out->Print( 0, " bottom_right" );
|
||||
|
||||
m_out->Print( 0, ")" );
|
||||
}
|
||||
|
||||
std::string output;
|
||||
|
||||
// Unconnected pad is default net so don't save it.
|
||||
|
|
|
@ -341,6 +341,7 @@ void D_PAD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDraw_mode,
|
|||
|
||||
void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
|
||||
{
|
||||
#define SEGCOUNT 32 // number of segments to approximate a circle
|
||||
wxPoint coord[12];
|
||||
double angle = m_Orient;
|
||||
int seg_width;
|
||||
|
@ -436,42 +437,29 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
|
|||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
{
|
||||
{
|
||||
// Use solder[Paste/Mask]size or pad size to build pad shape to draw
|
||||
wxSize size( GetSize() );
|
||||
size += aDrawInfo.m_Mask_margin * 2;
|
||||
int corner_radius = GetRoundRectCornerRadius( size );
|
||||
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
||||
|
||||
SHAPE_POLY_SET outline;
|
||||
TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
|
||||
corner_radius, GetChamferRectRatio(),
|
||||
doChamfer ? GetChamferPositions() : 0,
|
||||
SEGCOUNT );
|
||||
|
||||
// Draw the polygon: Inflate creates only one convex polygon
|
||||
SHAPE_POLY_SET outline;
|
||||
bool filled = aDrawInfo.m_ShowPadFilled;
|
||||
|
||||
if( filled )
|
||||
{
|
||||
wxPoint centers[4];
|
||||
GetRoundRectCornerCenters( centers, corner_radius, shape_pos,
|
||||
size, GetOrientation() );
|
||||
GRClosedPoly( aClipBox, aDC, 4, centers, true, corner_radius*2,
|
||||
aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
}
|
||||
else
|
||||
{
|
||||
TransformRoundRectToPolygon( outline, shape_pos, size, GetOrientation(),
|
||||
corner_radius, 64 );
|
||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
||||
|
||||
if( outline.OutlineCount() > 0 )
|
||||
{
|
||||
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
|
||||
|
||||
if( poly.PointCount() > 0 )
|
||||
{
|
||||
GRClosedPoly( aClipBox, aDC, poly.PointCount(),
|
||||
(wxPoint*)&poly.Point( 0 ), aDrawInfo.m_ShowPadFilled, 0,
|
||||
aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
}
|
||||
}
|
||||
}
|
||||
GRClosedPoly( aClipBox, aDC, poly.PointCount(),
|
||||
(wxPoint*)&poly.Point( 0 ), filled, 0,
|
||||
aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
|
||||
if( aDrawInfo.m_PadClearance )
|
||||
{
|
||||
|
@ -481,27 +469,23 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
|
|||
size.y += aDrawInfo.m_PadClearance * 2;
|
||||
corner_radius = GetRoundRectCornerRadius() + aDrawInfo.m_PadClearance;
|
||||
|
||||
TransformRoundRectToPolygon( outline, shape_pos, size, GetOrientation(),
|
||||
corner_radius, ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF );
|
||||
TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
|
||||
corner_radius, GetChamferRectRatio(),
|
||||
doChamfer ? GetChamferPositions() : 0,
|
||||
SEGCOUNT );
|
||||
|
||||
if( outline.OutlineCount() > 0 )
|
||||
{
|
||||
// Draw the polygon: Inflate creates only one convex polygon
|
||||
SHAPE_LINE_CHAIN& clearance_poly = outline.Outline( 0 );
|
||||
// Draw the polygon: Inflate creates only one convex polygon
|
||||
SHAPE_LINE_CHAIN& clearance_poly = outline.Outline( 0 );
|
||||
|
||||
if( clearance_poly.PointCount() > 0 )
|
||||
{
|
||||
GRClosedPoly( aClipBox, aDC, clearance_poly.PointCount(),
|
||||
(wxPoint*)&clearance_poly.Point( 0 ), false, 0,
|
||||
aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
}
|
||||
}
|
||||
GRClosedPoly( aClipBox, aDC, clearance_poly.PointCount(),
|
||||
(wxPoint*)&clearance_poly.Point( 0 ), false, 0,
|
||||
aDrawInfo.m_Color, aDrawInfo.m_Color );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
{
|
||||
{
|
||||
// The full shape has 2 items
|
||||
// 1- The anchor pad: a round or rect pad located at pad position
|
||||
// 2- The custom complex shape
|
||||
|
@ -586,10 +570,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the pad hole
|
||||
|
|
|
@ -816,13 +816,17 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
|
|||
break;
|
||||
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
{
|
||||
SHAPE_POLY_SET polySet;
|
||||
wxSize prsize( size.x * 2, size.y * 2 );
|
||||
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 );
|
||||
TransformRoundRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
|
||||
0.0, corner_radius, segmentToCircleCount );
|
||||
bool doChamfer = shape == PAD_SHAPE_CHAMFERED_RECT;
|
||||
|
||||
TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
|
||||
0.0, corner_radius, aPad->GetChamferRectRatio(),
|
||||
doChamfer ? aPad->GetChamferPositions() : 0, segmentToCircleCount );
|
||||
m_gal->DrawPolygon( polySet );
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <pcb_plot_params.h>
|
||||
#include <zones.h>
|
||||
#include <pcb_parser.h>
|
||||
#include <convert_basic_shapes_to_polygon.h> // for RECT_CHAMFER_POSITIONS definition
|
||||
|
||||
using namespace PCB_KEYS_T;
|
||||
|
||||
|
@ -2455,6 +2456,8 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
|
|||
break;
|
||||
|
||||
case T_roundrect:
|
||||
// Note: the shape can be PAD_SHAPE_ROUNDRECT or PAD_SHAPE_CHAMFERED_RECT
|
||||
// (if champfer parameters are found later in pad descr.)
|
||||
pad->SetShape( PAD_SHAPE_ROUNDRECT );
|
||||
break;
|
||||
|
||||
|
@ -2636,6 +2639,56 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_chamfer_ratio:
|
||||
pad->SetChamferRectRatio( parseDouble( "chamfer ratio" ) );
|
||||
|
||||
if( pad->GetChamferRectRatio() > 0 )
|
||||
pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_chamfer:
|
||||
{
|
||||
int chamfers = 0;
|
||||
bool end_list = false;
|
||||
|
||||
while( !end_list )
|
||||
{
|
||||
token = NextTok();
|
||||
switch( token )
|
||||
{
|
||||
case T_top_left:
|
||||
chamfers |= RECT_CHAMFER_TOP_LEFT;
|
||||
break;
|
||||
|
||||
case T_top_right:
|
||||
chamfers |= RECT_CHAMFER_TOP_RIGHT;
|
||||
break;
|
||||
|
||||
case T_bottom_left:
|
||||
chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
|
||||
break;
|
||||
|
||||
case T_bottom_right:
|
||||
chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
|
||||
break;
|
||||
|
||||
case T_RIGHT:
|
||||
pad->SetChamferPositions( chamfers );
|
||||
end_list = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "chamfer_top_left chamfer_top_right chamfer_bottom_left or chamfer_bottom_right" );
|
||||
}
|
||||
}
|
||||
|
||||
if( pad->GetChamferPositions() != RECT_NO_CHAMFER )
|
||||
pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
|
||||
}
|
||||
break;
|
||||
|
||||
case T_options:
|
||||
parseD_PAD_option( pad.get() );
|
||||
break;
|
||||
|
|
|
@ -443,6 +443,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
case PAD_SHAPE_TRAPEZOID:
|
||||
case PAD_SHAPE_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
pad->SetSize( padPlotsSize );
|
||||
itemplotter.PlotPad( pad, color, plotMode );
|
||||
break;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2018 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
|
||||
|
@ -45,6 +45,7 @@
|
|||
#include <class_drawsegment.h>
|
||||
#include <class_pcb_target.h>
|
||||
#include <class_dimension.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
|
||||
#include <pcbnew.h>
|
||||
#include <pcbplot.h>
|
||||
|
@ -186,6 +187,23 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPl
|
|||
aPad->GetOrientation(), aPlotMode, &gbr_metadata );
|
||||
break;
|
||||
|
||||
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 );
|
||||
|
||||
if( polygons.OutlineCount() == 0 )
|
||||
break;
|
||||
|
||||
int min_dim = std::min( aPad->GetSize().x, aPad->GetSize().y ) /2;
|
||||
m_plotter->FlashPadCustom( shape_pos,wxSize( min_dim, min_dim ), &polygons, aPlotMode, &gbr_metadata );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
{
|
||||
SHAPE_POLY_SET polygons;
|
||||
|
|
|
@ -612,6 +612,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
|
|||
break;
|
||||
}
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
|
@ -624,9 +625,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
|
|||
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
|
||||
|
||||
for( int ii = 0; ii < poly.PointCount(); ++ii )
|
||||
{
|
||||
shape->Append( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
|
||||
}
|
||||
shape->Append( poly.Point( ii ) );
|
||||
|
||||
solid->SetShape( shape );
|
||||
}
|
||||
|
@ -708,6 +707,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
|
|||
break;
|
||||
}
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
|
|
|
@ -323,7 +323,6 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
|||
|
||||
switch( aPad->GetShape() )
|
||||
{
|
||||
default:
|
||||
case PAD_SHAPE_CIRCLE:
|
||||
{
|
||||
double diameter = scale( aPad->GetSize().x );
|
||||
|
@ -491,6 +490,7 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
|||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
case PAD_SHAPE_ROUNDRECT:
|
||||
{
|
||||
// Export the shape as as polygon, round rect does not exist as primitive
|
||||
|
@ -511,8 +511,13 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
|||
psize.x += extra_clearance*2;
|
||||
psize.y += extra_clearance*2;
|
||||
rradius += extra_clearance;
|
||||
TransformRoundRectToPolygon( cornerBuffer, wxPoint(0,0), psize,
|
||||
0, rradius, circleToSegmentsCount );
|
||||
bool doChamfer = aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
||||
|
||||
TransformRoundChamferedRectToPolygon( cornerBuffer, wxPoint(0,0), psize,
|
||||
0, rradius,
|
||||
aPad->GetChamferRectRatio(),
|
||||
doChamfer ? aPad->GetChamferPositions() : 0,
|
||||
circleToSegmentsCount );
|
||||
SHAPE_LINE_CHAIN& polygonal_shape = cornerBuffer.Outline( 0 );
|
||||
|
||||
for( int ndx=0; ndx < reportedLayers; ++ndx )
|
||||
|
|
Loading…
Reference in New Issue