kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #39227
Re: [RFC] New pad primitive shape: Chamfered roundrectangle
Hi All,
Attached my latest version of chamfered round rectangle pads.
It includes proposals I received from previous tests.
Of course for the 6.0 version.
Cheers,
--
Jean-Pierre CHARRAS
From 7419c1e2db7b02fabe6c098c6bd701f51d860f6c Mon Sep 17 00:00:00 2001
From: jean-pierre charras <jp.charras@xxxxxxxxxx>
Date: Wed, 29 Aug 2018 09:13:07 +0200
Subject: [PATCH 1/2] 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.
---
.../3d_canvas/create_3Dgraphic_brd_items.cpp | 20 +
3d-viewer/3d_canvas/create_layer_poly.cpp | 1 +
common/convert_basic_shapes_to_polygon.cpp | 71 ++
common/pcb.keywords | 6 +
include/convert_basic_shapes_to_polygon.h | 24 +
include/pad_shapes.h | 1 +
...board_items_to_polygon_shape_transform.cpp | 25 +-
pcbnew/class_pad.cpp | 40 +-
pcbnew/class_pad.h | 57 ++
pcbnew/dialogs/dialog_pad_properties.cpp | 115 ++-
pcbnew/dialogs/dialog_pad_properties_base.cpp | 67 +-
pcbnew/dialogs/dialog_pad_properties_base.fbp | 901 ++++++++++++++++--
pcbnew/dialogs/dialog_pad_properties_base.h | 15 +-
pcbnew/drc_clearance_test_functions.cpp | 57 +-
pcbnew/kicad_plugin.cpp | 41 +-
pcbnew/pad_draw_functions.cpp | 55 ++
pcbnew/pcb_painter.cpp | 13 +
pcbnew/pcb_parser.cpp | 49 +-
pcbnew/plot_board_layers.cpp | 1 +
pcbnew/plot_brditems_plotter.cpp | 20 +-
pcbnew/router/pns_kicad_iface.cpp | 6 +-
21 files changed, 1456 insertions(+), 129 deletions(-)
diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
index 8051a17db..202686190 100644
--- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
+++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
@@ -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 );
+ TransformChamferedRectToPolygon( 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;
diff --git a/3d-viewer/3d_canvas/create_layer_poly.cpp b/3d-viewer/3d_canvas/create_layer_poly.cpp
index 28630fd4c..f4add3f54 100644
--- a/3d-viewer/3d_canvas/create_layer_poly.cpp
+++ b/3d-viewer/3d_canvas/create_layer_poly.cpp
@@ -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.
diff --git a/common/convert_basic_shapes_to_polygon.cpp b/common/convert_basic_shapes_to_polygon.cpp
index cf68cb228..2fd3664c2 100644
--- a/common/convert_basic_shapes_to_polygon.cpp
+++ b/common/convert_basic_shapes_to_polygon.cpp
@@ -239,6 +239,77 @@ void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
}
+void TransformChamferedRectToPolygon( 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
+ wxPoint corners[4];
+ GetRoundRectCornerCenters( corners, aCornerRadius, wxPoint( 0, 0 ), aSize, 0.0 );
+
+ SHAPE_POLY_SET outline;
+ outline.NewOutline();
+
+ for( int ii = 0; ii < 4; ++ii )
+ outline.Append( corners[ii].x, corners[ii].y );
+
+ outline.Inflate( aCornerRadius, aCircleToSegmentsCount );
+
+ // Now we have the round rect outline, chamfer the TOP_LEFT corner
+ // for other corners, the shape will be just mirrored or rotated
+ 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] = {1, 2, 4, 8 };
+ // 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 );
+
+ // We create 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 );
+}
+
+
/**
* Function TransformRoundedEndsSegmentToPolygon
* convert a segment with rounded ends to a polygon
diff --git a/common/pcb.keywords b/common/pcb.keywords
index 1998f9ab5..7dabffd44 100644
--- a/common/pcb.keywords
+++ b/common/pcb.keywords
@@ -44,8 +44,12 @@ blind
blind_buried_vias_allowed
bold
bottom
+bottom_left
+bottom_right
center
chamfer
+chamfered_rect
+chamfer_ratio
circle
clearance
comment
@@ -176,6 +180,8 @@ thermal_gap
thermal_bridge_width
thickness
top
+top_left
+top_right
trace_width
tracks
trace_min
diff --git a/include/convert_basic_shapes_to_polygon.h b/include/convert_basic_shapes_to_polygon.h
index eac92db8d..461f4e35f 100644
--- a/include/convert_basic_shapes_to_polygon.h
+++ b/include/convert_basic_shapes_to_polygon.h
@@ -102,6 +102,30 @@ void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
double aRotation, int aCornerRadius,
int aCircleToSegmentsCount );
+/**
+ * Function TransformChamferedRectToPolygon
+ * 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 (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:
+ * 1 = TOP_LEFT
+ * 2 = TOP_RIGHT
+ * 4 = BOTTOM_LEFT
+ * 8 = BOTTOM_RIGHT
+ * One ca have more than one chamfered corner by ORing the corner identifers
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ */
+void TransformChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ const wxPoint& aPosition, const wxSize& aSize,
+ double aRotation, int aCornerRadius,
+ double aChamferRatio, int aChamferCorners,
+ int aCircleToSegmentsCount );
+
/**
* Function TransformRoundedEndsSegmentToPolygon
* convert a segment with rounded ends to a polygon
diff --git a/include/pad_shapes.h b/include/pad_shapes.h
index fb77b50fb..8878b3646 100644
--- a/include/pad_shapes.h
+++ b/include/pad_shapes.h
@@ -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
};
diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp
index 78ec4a5f5..c547d79b0 100644
--- a/pcbnew/board_items_to_polygon_shape_transform.cpp
+++ b/pcbnew/board_items_to_polygon_shape_transform.cpp
@@ -770,9 +770,8 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
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;
@@ -784,6 +783,24 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
}
break;
+ case PAD_SHAPE_CHAMFERED_RECT:
+ {
+ SHAPE_POLY_SET outline;
+ int clearance = int( aClearanceValue * aCorrectionFactor );
+ int rounding_radius = GetRoundRectCornerRadius() + clearance;
+ wxSize shapesize( m_Size );
+ shapesize.x += clearance*2;
+ shapesize.y += clearance*2;
+
+ TransformChamferedRectToPolygon( outline, padShapePos, shapesize, angle,
+ rounding_radius, GetChamferRectRatio(),
+ GetChamferPositions(),
+ aCircleToSegmentsCount );
+
+ aCornerBuffer.Append( outline );
+ }
+ break;
+
case PAD_SHAPE_CUSTOM:
{
int clearance = KiROUND( aClearanceValue * aCorrectionFactor );
@@ -819,6 +836,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.
@@ -1171,7 +1189,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
diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp
index e343db491..4e570ebf5 100644
--- a/pcbnew/class_pad.cpp
+++ b/pcbnew/class_pad.cpp
@@ -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 =.15; // Size of chamfer in percent of smallest of X,Y size
+ m_chamferPositions = PAD_CHAMFER_TOP_LEFT;
- 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;
@@ -932,6 +944,20 @@ bool D_PAD::HitTest( const wxPoint& aPosition ) const
}
break;
+ case PAD_SHAPE_CHAMFERED_RECT:
+ {
+ // Check for hit in polygon
+ SHAPE_POLY_SET outline;
+ const int segmentToCircleCount = 32;
+ TransformChamferedRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
+ GetRoundRectCornerRadius(), GetChamferRectRatio(),
+ GetChamferPositions(), segmentToCircleCount );
+
+ const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
+ return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
+ }
+ break;
+
case PAD_SHAPE_CUSTOM:
// Check for hit in polygon
RotatePoint( &delta, -m_Orient );
@@ -978,6 +1004,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 +1109,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 +1249,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" );
diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h
index 1f5f5cae6..11d23d71f 100644
--- a/pcbnew/class_pad.h
+++ b/pcbnew/class_pad.h
@@ -46,6 +46,18 @@ enum CUST_PAD_SHAPE_IN_ZONE
CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL
};
+// The chamfer positions of chamfered rect pad 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 PAD_CHAMFER_POSITIONS
+{
+ PAD_CHAMFER_TOP_LEFT = 1,
+ PAD_CHAMFER_TOP_RIGHT = 2,
+ PAD_CHAMFER_BOTTOM_LEFT = 4,
+ PAD_CHAMFER_BOTTOM_RIGHT = 8,
+};
+
class LINE_READER;
class EDA_3D_CANVAS;
class EDA_DRAW_PANEL;
@@ -658,6 +670,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 +889,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
diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp
index 9ca1cd746..51c34281d 100644
--- a/pcbnew/dialogs/dialog_pad_properties.cpp
+++ b/pcbnew/dialogs/dialog_pad_properties.cpp
@@ -55,6 +55,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 +69,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
};
@@ -450,11 +452,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 )
{
@@ -497,27 +503,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();
@@ -703,6 +737,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 )
@@ -712,6 +747,12 @@ void DIALOG_PAD_PROPERTIES::initValues()
break;
}
+
+ m_cbTopLeft->SetValue( (m_dummyPad->GetChamferPositions() & PAD_CHAMFER_TOP_LEFT) );
+ m_cbTopRight->SetValue( (m_dummyPad->GetChamferPositions() & PAD_CHAMFER_TOP_RIGHT) );
+ m_cbBottomLeft->SetValue( (m_dummyPad->GetChamferPositions() & PAD_CHAMFER_BOTTOM_LEFT) );
+ m_cbBottomRight->SetValue( (m_dummyPad->GetChamferPositions() & PAD_CHAMFER_BOTTOM_RIGHT) );
+
enablePrimitivePage( PAD_SHAPE_CUSTOM == m_dummyPad->GetShape() );
// Type of pad selection
@@ -864,6 +905,7 @@ void DIALOG_PAD_PROPERTIES::onChangePadMode( wxCommandEvent& event )
}
+
void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
{
bool is_custom = false;
@@ -907,6 +949,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 );
@@ -932,11 +975,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.
@@ -1221,7 +1273,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;
@@ -1492,6 +1545,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 )
{
@@ -1662,6 +1717,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 |= PAD_CHAMFER_TOP_LEFT;
+
+ if( m_cbTopRight->GetValue() )
+ chamfers |= PAD_CHAMFER_TOP_RIGHT;
+
+ if( m_cbBottomLeft->GetValue() )
+ chamfers |= PAD_CHAMFER_BOTTOM_LEFT;
+
+ if( m_cbBottomRight->GetValue() )
+ chamfers |= PAD_CHAMFER_BOTTOM_RIGHT;
+
+ aPad->SetChamferPositions( chamfers );
+
// Clear some values, according to the pad type and shape
switch( aPad->GetShape() )
{
@@ -1682,6 +1753,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;
@@ -1735,13 +1807,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( &ratioPercent ) )
+ aPad->SetRoundRectRadiusRatio( ratioPercent / 100.0 );
+
+ value = m_tcChamferRatio->GetValue();
- if( value.ToDouble( &rrRadiusRatioPercent ) )
- aPad->SetRoundRectRadiusRatio( rrRadiusRatioPercent / 100.0 );
+ if( value.ToDouble( &ratioPercent ) )
+ aPad->SetChamferRectRatio( ratioPercent / 100.0 );
}
LSET padLayerMask;
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.cpp b/pcbnew/dialogs/dialog_pad_properties_base.cpp
index de05d4f03..92408ec53 100644
--- a/pcbnew/dialogs/dialog_pad_properties_base.cpp
+++ b/pcbnew/dialogs/dialog_pad_properties_base.cpp
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Apr 19 2018)
+// C++ code generated with wxFormBuilder (version Jul 11 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -75,7 +75,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_staticText45->Wrap( -1 );
fgSizerShapeType->Add( m_staticText45, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 3 );
- wxString m_PadShapeChoices[] = { _("Circular"), _("Oval"), _("Rectangular"), _("Trapezoidal"), _("Rounded Rectangle"), _("Custom (Circ. Anchor)"), _("Custom (Rect. Anchor)") };
+ wxString m_PadShapeChoices[] = { _("Circular"), _("Oval"), _("Rectangular"), _("Trapezoidal"), _("Rounded Rectangle"), _("Chamfered Rectangle"), _("Custom (Circ. Anchor)"), _("Custom (Rect. Anchor)") };
int m_PadShapeNChoices = sizeof( m_PadShapeChoices ) / sizeof( wxString );
m_PadShape = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_PadShapeNChoices, m_PadShapeChoices, 0 );
m_PadShape->SetSelection( 0 );
@@ -219,17 +219,56 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_cornerRadiusLabel->Wrap( -1 );
m_cornerRadiusLabel->SetToolTip( _("Corner radius.\nCan be no more than half pad width.\nThe width is the smaller value between size X and size Y.\nNote: IPC norm gives a max value = 0.25mm.") );
- fgSizerShapeType->Add( m_cornerRadiusLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 3 );
+ fgSizerShapeType->Add( m_cornerRadiusLabel, 0, wxRIGHT|wxLEFT, 3 );
- m_tcCornerRadius = new TEXT_CTRL_EVAL( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_tcCornerRadius->SetToolTip( _("Corner radius.\nCan be no more than half pad width.\nThe width is the smaller value between size X and size Y\nNote: IPC norm gives a max value = 0.25mm") );
+ m_cornerRadiusValue = new wxStaticText( m_panelGeneral, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_cornerRadiusValue->Wrap( -1 );
+ m_cornerRadiusValue->SetToolTip( _("Corner radius.\nCan be no more than half pad width.\nThe width is the smaller value between size X and size Y\nNote: IPC norm gives a max value = 0.25mm") );
- fgSizerShapeType->Add( m_tcCornerRadius, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 3 );
+ fgSizerShapeType->Add( m_cornerRadiusValue, 0, wxRIGHT|wxLEFT, 3 );
m_cornerRadiusUnits = new wxStaticText( m_panelGeneral, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_cornerRadiusUnits->Wrap( -1 );
fgSizerShapeType->Add( m_cornerRadiusUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
+ m_staticTextChamferRatio = new wxStaticText( m_panelGeneral, wxID_ANY, _("Chamfer size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextChamferRatio->Wrap( -1 );
+ m_staticTextChamferRatio->SetToolTip( _("Chamfer size in percent of the pad width.\nThe width is the smaller value between size X and size Y.\nThe max value is 50 percent.") );
+
+ fgSizerShapeType->Add( m_staticTextChamferRatio, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ m_tcChamferRatio = new TEXT_CTRL_EVAL( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerShapeType->Add( m_tcChamferRatio, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextChamferRatioUnit = new wxStaticText( m_panelGeneral, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextChamferRatioUnit->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticTextChamferRatioUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextChamferCorner = new wxStaticText( m_panelGeneral, wxID_ANY, _("Chamfered corner:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextChamferCorner->Wrap( -1 );
+ m_staticTextChamferCorner->SetToolTip( _("Chamfered corners. The position is relative to a pad orientation 0 degree.") );
+
+ fgSizerShapeType->Add( m_staticTextChamferCorner, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerChamferedCorners;
+ bSizerChamferedCorners = new wxBoxSizer( wxVERTICAL );
+
+ m_cbTopLeft = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Top left"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_cbTopLeft->SetValue(true);
+ bSizerChamferedCorners->Add( m_cbTopLeft, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_cbTopRight = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Top right"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerChamferedCorners->Add( m_cbTopRight, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_cbBottomLeft = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Bottom left"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerChamferedCorners->Add( m_cbBottomLeft, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_cbBottomRight = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Bottom right"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerChamferedCorners->Add( m_cbBottomRight, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ fgSizerShapeType->Add( bSizerChamferedCorners, 0, wxEXPAND, 5 );
+
m_LeftBoxSizer->Add( fgSizerShapeType, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
@@ -724,7 +763,11 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_trapDeltaCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_trapAxisCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_tcCornerSizeRatio->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerSizePercentChange ), NULL, this );
- m_tcCornerRadius->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerRadiusChange ), NULL, this );
+ m_tcChamferRatio->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerSizePercentChange ), NULL, this );
+ m_cbTopLeft->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_cbTopRight->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_cbBottomLeft->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_cbBottomRight->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_holeShapeCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnDrillShapeSelected ), NULL, this );
m_holeXCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_holeYCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
@@ -772,7 +815,11 @@ DIALOG_PAD_PROPERTIES_BASE::~DIALOG_PAD_PROPERTIES_BASE()
m_trapDeltaCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_trapAxisCtrl->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_tcCornerSizeRatio->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerSizePercentChange ), NULL, this );
- m_tcCornerRadius->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerRadiusChange ), NULL, this );
+ m_tcChamferRatio->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerSizePercentChange ), NULL, this );
+ m_cbTopLeft->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_cbTopRight->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_cbBottomLeft->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_cbBottomRight->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_holeShapeCtrl->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnDrillShapeSelected ), NULL, this );
m_holeXCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_holeYCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
@@ -1115,7 +1162,7 @@ DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE::DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( wxWi
wxBoxSizer* bSizerRightButts;
bSizerRightButts = new wxBoxSizer( wxHORIZONTAL );
- m_addButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
+ m_addButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
m_addButton->SetMinSize( wxSize( 30,30 ) );
bSizerRightButts->Add( m_addButton, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
@@ -1123,7 +1170,7 @@ DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE::DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( wxWi
bSizerRightButts->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
- m_deleteButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
+ m_deleteButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
m_deleteButton->SetMinSize( wxSize( 30,30 ) );
bSizerRightButts->Add( m_deleteButton, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.fbp b/pcbnew/dialogs/dialog_pad_properties_base.fbp
index d259443ce..96cc215c6 100644
--- a/pcbnew/dialogs/dialog_pad_properties_base.fbp
+++ b/pcbnew/dialogs/dialog_pad_properties_base.fbp
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
- <FileVersion major="1" minor="13" />
+ <FileVersion major="1" minor="14" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@@ -1017,7 +1017,7 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
- <property name="choices">"Circular" "Oval" "Rectangular" "Trapezoidal" "Rounded Rectangle" "Custom (Circ. Anchor)" "Custom (Rect. Anchor)"</property>
+ <property name="choices">"Circular" "Oval" "Rectangular" "Trapezoidal" "Rounded Rectangle" "Chamfered Rectangle" "Custom (Circ. Anchor)" "Custom (Rect. Anchor)"</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
@@ -4104,7 +4104,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">3</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@@ -4193,11 +4193,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">3</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
+ <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -4225,15 +4225,16 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
+ <property name="label">dummy</property>
+ <property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
- <property name="maxlength">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
- <property name="name">m_tcCornerRadius</property>
+ <property name="name">m_cornerRadiusValue</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@@ -4244,17 +4245,13 @@
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
- <property name="subclass">TEXT_CTRL_EVAL; widgets/text_ctrl_eval.h; forward_declare</property>
+ <property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Corner radius.
Can be no more than half pad width.
The width is the smaller value between size X and size Y
Note: IPC norm gives a max value = 0.25mm</property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
+ <property name="wrap">-1</property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
@@ -4284,10 +4281,6 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
- <event name="OnText">onCornerRadiusChange</event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
@@ -4382,6 +4375,768 @@
<event name="OnUpdateUI"></event>
</object>
</object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Chamfer size:</property>
+ <property name="markup">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextChamferRatio</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Chamfer size in percent of the pad width.
The width is the smaller value between size X and size Y.
The max value is 50 percent.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnAux1DClick"></event>
+ <event name="OnAux1Down"></event>
+ <event name="OnAux1Up"></event>
+ <event name="OnAux2DClick"></event>
+ <event name="OnAux2Down"></event>
+ <event name="OnAux2Up"></event>
+ <event name="OnChar"></event>
+ <event name="OnCharHook"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_tcChamferRatio</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">TEXT_CTRL_EVAL; widgets/text_ctrl_eval.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnAux1DClick"></event>
+ <event name="OnAux1Down"></event>
+ <event name="OnAux1Up"></event>
+ <event name="OnAux2DClick"></event>
+ <event name="OnAux2Down"></event>
+ <event name="OnAux2Up"></event>
+ <event name="OnChar"></event>
+ <event name="OnCharHook"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">onCornerSizePercentChange</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">%</property>
+ <property name="markup">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextChamferRatioUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnAux1DClick"></event>
+ <event name="OnAux1Down"></event>
+ <event name="OnAux1Up"></event>
+ <event name="OnAux2DClick"></event>
+ <event name="OnAux2Down"></event>
+ <event name="OnAux2Up"></event>
+ <event name="OnChar"></event>
+ <event name="OnCharHook"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Chamfered corner:</property>
+ <property name="markup">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextChamferCorner</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Chamfered corners. The position is relative to a pad orientation 0 degree.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnAux1DClick"></event>
+ <event name="OnAux1Down"></event>
+ <event name="OnAux1Up"></event>
+ <event name="OnAux2DClick"></event>
+ <event name="OnAux2Down"></event>
+ <event name="OnAux2Up"></event>
+ <event name="OnChar"></event>
+ <event name="OnCharHook"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerChamferedCorners</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Top left</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbTopLeft</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; forward_declare</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnAux1DClick"></event>
+ <event name="OnAux1Down"></event>
+ <event name="OnAux1Up"></event>
+ <event name="OnAux2DClick"></event>
+ <event name="OnAux2Down"></event>
+ <event name="OnAux2Up"></event>
+ <event name="OnChar"></event>
+ <event name="OnCharHook"></event>
+ <event name="OnCheckBox">OnValuesChanged</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Top right</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbTopRight</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; forward_declare</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnAux1DClick"></event>
+ <event name="OnAux1Down"></event>
+ <event name="OnAux1Up"></event>
+ <event name="OnAux2DClick"></event>
+ <event name="OnAux2Down"></event>
+ <event name="OnAux2Up"></event>
+ <event name="OnChar"></event>
+ <event name="OnCharHook"></event>
+ <event name="OnCheckBox">OnValuesChanged</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Bottom left</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbBottomLeft</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; forward_declare</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnAux1DClick"></event>
+ <event name="OnAux1Down"></event>
+ <event name="OnAux1Up"></event>
+ <event name="OnAux2DClick"></event>
+ <event name="OnAux2Down"></event>
+ <event name="OnAux2Up"></event>
+ <event name="OnChar"></event>
+ <event name="OnCharHook"></event>
+ <event name="OnCheckBox">OnValuesChanged</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Bottom right</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbBottomRight</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; forward_declare</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnAux1DClick"></event>
+ <event name="OnAux1Down"></event>
+ <event name="OnAux1Up"></event>
+ <event name="OnAux2DClick"></event>
+ <event name="OnAux2Down"></event>
+ <event name="OnAux2Up"></event>
+ <event name="OnChar"></event>
+ <event name="OnCharHook"></event>
+ <event name="OnCheckBox">OnValuesChanged</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
</object>
</object>
</object>
@@ -4390,7 +5145,7 @@
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizer10</property>
<property name="orient">wxVERTICAL</property>
@@ -5250,11 +6005,11 @@
</object>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
<property name="proportion">1</property>
- <object class="wxStaticBoxSizer" expanded="1">
+ <object class="wxStaticBoxSizer" expanded="0">
<property name="id">wxID_ANY</property>
<property name="label"></property>
<property name="minimum_size">-1,-1</property>
@@ -5453,11 +6208,11 @@
</object>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizer11</property>
<property name="orient">wxHORIZONTAL</property>
@@ -6797,7 +7552,7 @@
<property name="bitmap"></property>
<property name="label">Local Clearance and Settings</property>
<property name="select">0</property>
- <object class="wxPanel" expanded="1">
+ <object class="wxPanel" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -6878,25 +7633,25 @@
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerPanelClearance</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerClearance</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxStaticBoxSizer" expanded="1">
+ <object class="wxStaticBoxSizer" expanded="0">
<property name="id">wxID_ANY</property>
<property name="label">Clearances</property>
<property name="minimum_size"></property>
@@ -6996,11 +7751,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">10</property>
<property name="flag">wxTOP|wxRIGHT</property>
<property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
+ <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -7087,11 +7842,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">10</property>
<property name="flag">wxBOTTOM|wxRIGHT</property>
<property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
+ <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -7178,11 +7933,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxFlexGridSizer" expanded="1">
+ <object class="wxFlexGridSizer" expanded="0">
<property name="cols">3</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">1</property>
@@ -8316,11 +9071,11 @@
</object>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT</property>
<property name="proportion">1</property>
- <object class="wxSimplebook" expanded="1">
+ <object class="wxSimplebook" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -8403,10 +9158,10 @@
<event name="OnSimplebookPageChanging"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI">OnUpdateUINonCopperWarning</event>
- <object class="simplebookpage" expanded="1">
+ <object class="simplebookpage" expanded="0">
<property name="label">a page</property>
<property name="select">0</property>
- <object class="wxPanel" expanded="1">
+ <object class="wxPanel" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -8487,16 +9242,16 @@
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bNoteSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">15</property>
<property name="flag">wxTOP|wxRIGHT</property>
<property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
+ <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -8586,10 +9341,10 @@
</object>
</object>
</object>
- <object class="simplebookpage" expanded="1">
+ <object class="simplebookpage" expanded="0">
<property name="label">a page</property>
<property name="select">0</property>
- <object class="wxPanel" expanded="1">
+ <object class="wxPanel" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -8670,16 +9425,16 @@
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size">-1,50</property>
<property name="name">bWarningSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
- <object class="wxStaticBitmap" expanded="1">
+ <object class="wxStaticBitmap" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -8763,11 +9518,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
+ <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -8861,11 +9616,11 @@
</object>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxStaticBoxSizer" expanded="1">
+ <object class="wxStaticBoxSizer" expanded="0">
<property name="id">wxID_ANY</property>
<property name="label">Connection to Copper Zones</property>
<property name="minimum_size"></property>
@@ -8874,11 +9629,11 @@
<property name="parent">1</property>
<property name="permission">protected</property>
<event name="OnUpdateUI"></event>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxFlexGridSizer" expanded="1">
+ <object class="wxFlexGridSizer" expanded="0">
<property name="cols">3</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">1</property>
@@ -9770,11 +10525,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
- <object class="wxChoice" expanded="1">
+ <object class="wxChoice" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -10064,7 +10819,7 @@
<property name="bitmap"></property>
<property name="label">Custom Shape Primitives</property>
<property name="select">0</property>
- <object class="wxPanel" expanded="1">
+ <object class="wxPanel" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -10145,7 +10900,7 @@
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">m_bSizerPanelPrimitives</property>
<property name="orient">wxVERTICAL</property>
@@ -10444,20 +11199,20 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerButtons</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerButtonsUpper</property>
<property name="orient">wxHORIZONTAL</property>
@@ -11676,16 +12431,16 @@
<event name="OnShow"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizermain</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">1</property>
- <object class="wxFlexGridSizer" expanded="1">
+ <object class="wxFlexGridSizer" expanded="0">
<property name="cols">7</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">2,4</property>
@@ -15533,25 +16288,25 @@
<event name="OnShow"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerUpper</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bLeftSizer</property>
<property name="orient">wxVERTICAL</property>
@@ -15706,11 +16461,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
+ <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerRightButts</property>
<property name="orient">wxHORIZONTAL</property>
@@ -15818,11 +16573,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="1">
+ <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
- <object class="spacer" expanded="1">
+ <object class="spacer" expanded="0">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.h b/pcbnew/dialogs/dialog_pad_properties_base.h
index 58e08d9c7..b71f962ba 100644
--- a/pcbnew/dialogs/dialog_pad_properties_base.h
+++ b/pcbnew/dialogs/dialog_pad_properties_base.h
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Apr 19 2018)
+// C++ code generated with wxFormBuilder (version Jul 11 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -25,12 +25,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>
@@ -104,8 +104,16 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
TEXT_CTRL_EVAL* m_tcCornerSizeRatio;
wxStaticText* m_staticTextCornerSizeRatioUnit;
wxStaticText* m_cornerRadiusLabel;
- TEXT_CTRL_EVAL* m_tcCornerRadius;
+ wxStaticText* m_cornerRadiusValue;
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;
@@ -195,7 +203,6 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
virtual void PadOrientEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSetLayers( wxCommandEvent& event ) { event.Skip(); }
virtual void onCornerSizePercentChange( wxCommandEvent& event ) { event.Skip(); }
- virtual void onCornerRadiusChange( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDrillShapeSelected( wxCommandEvent& event ) { event.Skip(); }
virtual void OnUpdateUINonCopperWarning( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onPrimitiveDClick( wxMouseEvent& event ) { event.Skip(); }
diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp
index d6273ecbd..a7581a569 100644
--- a/pcbnew/drc_clearance_test_functions.cpp
+++ b/pcbnew/drc_clearance_test_functions.cpp
@@ -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();
+ TransformChamferedRectToPolygon( 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();
+ TransformChamferedRectToPolygon( 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();
+ TransformChamferedRectToPolygon( 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),
diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp
index df0ec7a15..779db49fe 100644
--- a/pcbnew/kicad_plugin.cpp
+++ b/pcbnew/kicad_plugin.cpp
@@ -1248,12 +1248,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_ROUNDRECT: shape = "roundrect"; break;
+ case PAD_SHAPE_CHAMFERED_RECT: shape = "chamfered_rect"; break;
+ case PAD_SHAPE_CUSTOM: shape = "custom"; break;
default:
THROW_IO_ERROR( wxString::Format( _( "unknown pad type: %d"), aPad->GetShape() ) );
@@ -1311,13 +1312,37 @@ 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, " (chamfer_ratio %s)",
+ Double2Str( aPad->GetChamferRectRatio() ).c_str() );
+
+ m_out->Print( 0, "\n" );
+ m_out->Print( aNestLevel+1, " (chamfer" );
+
+ if( ( aPad->GetChamferPositions() & PAD_CHAMFER_TOP_LEFT ) )
+ m_out->Print( 0, " top_left" );
+
+ if( ( aPad->GetChamferPositions() & PAD_CHAMFER_TOP_RIGHT ) )
+ m_out->Print( 0, " top_right" );
+
+ if( ( aPad->GetChamferPositions() & PAD_CHAMFER_BOTTOM_LEFT ) )
+ m_out->Print( 0, " bottom_left" );
+
+ if( ( aPad->GetChamferPositions() & PAD_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.
diff --git a/pcbnew/pad_draw_functions.cpp b/pcbnew/pad_draw_functions.cpp
index 5a0b5ffd4..2bd5bcdf1 100644
--- a/pcbnew/pad_draw_functions.cpp
+++ b/pcbnew/pad_draw_functions.cpp
@@ -500,6 +500,61 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
}
break;
+
+ case PAD_SHAPE_CHAMFERED_RECT:
+ {
+ // 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 );
+
+ // Draw the polygon:
+ SHAPE_POLY_SET outline;
+ TransformChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
+ corner_radius, GetChamferRectRatio(),
+ GetChamferPositions(), 64 );
+ bool filled = aDrawInfo.m_ShowPadFilled;
+
+ if( outline.OutlineCount() > 0 )
+ {
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+
+ if( poly.PointCount() > 0 )
+ {
+ GRClosedPoly( aClipBox, aDC, poly.PointCount(),
+ (wxPoint*)&poly.Point( 0 ), filled, 0,
+ aDrawInfo.m_Color, aDrawInfo.m_Color );
+ }
+ }
+
+ if( aDrawInfo.m_PadClearance )
+ {
+ outline.RemoveAllContours();
+ size = GetSize();
+ size.x += aDrawInfo.m_PadClearance * 2;
+ size.y += aDrawInfo.m_PadClearance * 2;
+ corner_radius = GetRoundRectCornerRadius() + aDrawInfo.m_PadClearance;
+
+ TransformChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
+ corner_radius, GetChamferRectRatio(),
+ GetChamferPositions(), 32 );
+
+ if( outline.OutlineCount() > 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 );
+ }
+ }
+ }
+ }
+ break;
+
case PAD_SHAPE_CUSTOM:
{
// The full shape has 2 items
diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp
index 8814249e7..8403874cd 100644
--- a/pcbnew/pcb_painter.cpp
+++ b/pcbnew/pcb_painter.cpp
@@ -834,6 +834,19 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
break;
}
+ case PAD_SHAPE_CHAMFERED_RECT:
+ {
+ SHAPE_POLY_SET polySet;
+ wxSize prsize( size.x * 2, size.y * 2 ); // size is the half pad area size)
+ const int segmentToCircleCount = 64;
+ const int corner_radius = aPad->GetRoundRectCornerRadius( prsize );
+ TransformChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
+ 0.0, corner_radius, aPad->GetChamferRectRatio(),
+ aPad->GetChamferPositions(), segmentToCircleCount );
+ m_gal->DrawPolygon( polySet );
+ break;
+ }
+
case PAD_SHAPE_CUSTOM:
{ // Draw the complex custom shape
diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp
index 408a78132..929b034f4 100644
--- a/pcbnew/pcb_parser.cpp
+++ b/pcbnew/pcb_parser.cpp
@@ -2458,12 +2458,16 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
pad->SetShape( PAD_SHAPE_ROUNDRECT );
break;
+ case T_chamfered_rect:
+ pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
+ break;
+
case T_custom:
pad->SetShape( PAD_SHAPE_CUSTOM );
break;
default:
- Expecting( "circle, rectangle, roundrect, oval, trapezoid or custom" );
+ Expecting( "circle, rectangle, roundrect, oval, trapezoid, chamfered_rect or custom" );
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
@@ -2636,6 +2640,49 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
NeedRIGHT();
break;
+ case T_chamfer_ratio:
+ pad->SetChamferRectRatio( parseDouble( "chamfer ratio" ) );
+ NeedRIGHT();
+ break;
+
+ case T_chamfer:
+ {
+ int chamfers = 0;
+ bool end_list = false;
+
+ while( !end_list )
+ {
+ token = NextTok();
+ switch( token )
+ {
+ case T_top_left:
+ chamfers |= PAD_CHAMFER_TOP_LEFT;
+ break;
+
+ case T_top_right:
+ chamfers |= PAD_CHAMFER_TOP_RIGHT;
+ break;
+
+ case T_bottom_left:
+ chamfers |= PAD_CHAMFER_BOTTOM_LEFT;
+ break;
+
+ case T_bottom_right:
+ chamfers |= PAD_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" );
+ }
+ }
+ }
+ break;
+
case T_options:
parseD_PAD_option( pad.get() );
break;
diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp
index 166c91319..3f7455184 100644
--- a/pcbnew/plot_board_layers.cpp
+++ b/pcbnew/plot_board_layers.cpp
@@ -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;
diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp
index d26218647..8fabf7ba2 100644
--- a/pcbnew/plot_brditems_plotter.cpp
+++ b/pcbnew/plot_brditems_plotter.cpp
@@ -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() );
+ TransformChamferedRectToPolygon( 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;
diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp
index 20c2c6f19..65caf70a9 100644
--- a/pcbnew/router/pns_kicad_iface.cpp
+++ b/pcbnew/router/pns_kicad_iface.cpp
@@ -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;
--
2.17.0.windows.1
From 0416dd795eefc480b8577fd412d788e63d6e7934 Mon Sep 17 00:00:00 2001
From: jean-pierre charras <jp.charras@xxxxxxxxxx>
Date: Wed, 5 Sep 2018 15:24:12 +0200
Subject: [PATCH 2/2] Pcbnew file format: remove chamfered_rect and use only
roundrect for pad shape with round rect and/or chamfered rect. * These 2
shapes have same parameters in file, therefore no need to use 2 different
keywords. * Merge TransformRoundRectToPolygon() and
TransformChamferedRectToPolygon() to TransformRoundChamferedRectToPolygon() *
Some draw and plot sections of code using these 2 function are merged,
because they are similar.
---
.../3d_canvas/create_3Dgraphic_brd_items.cpp | 2 +-
common/convert_basic_shapes_to_polygon.cpp | 82 +++++-------
common/pcb.keywords | 1 -
common/plotters/DXF_plotter.cpp | 4 +-
common/plotters/GERBER_plotter.cpp | 4 +-
common/plotters/HPGL_plotter.cpp | 4 +-
common/plotters/PS_plotter.cpp | 4 +-
include/convert_basic_shapes_to_polygon.h | 40 +++---
...board_items_to_polygon_shape_transform.cpp | 27 +---
pcbnew/class_pad.cpp | 30 ++---
pcbnew/class_pad.h | 12 --
pcbnew/dialogs/dialog_pad_properties.cpp | 23 ++--
pcbnew/dialogs/dialog_pad_properties_base.cpp | 13 +-
pcbnew/dialogs/dialog_pad_properties_base.fbp | 29 +++--
pcbnew/dialogs/dialog_pad_properties_base.h | 3 +-
pcbnew/drc_clearance_test_functions.cpp | 6 +-
pcbnew/exporters/export_vrml.cpp | 14 +-
pcbnew/kicad_plugin.cpp | 18 +--
pcbnew/pad_draw_functions.cpp | 122 ++++--------------
pcbnew/pcb_painter.cpp | 17 +--
pcbnew/pcb_parser.cpp | 24 ++--
pcbnew/plot_brditems_plotter.cpp | 2 +-
.../specctra_export.cpp | 11 +-
23 files changed, 192 insertions(+), 300 deletions(-)
diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
index 202686190..3818043fb 100644
--- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
+++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
@@ -500,7 +500,7 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
int corner_radius = aPad->GetRoundRectCornerRadius( shapesize );
- TransformChamferedRectToPolygon( polyList, PadShapePos, shapesize, aPad->GetOrientation(),
+ TransformRoundChamferedRectToPolygon( polyList, PadShapePos, shapesize, aPad->GetOrientation(),
corner_radius, aPad->GetChamferRectRatio(),
aPad->GetChamferPositions(), 32 );
diff --git a/common/convert_basic_shapes_to_polygon.cpp b/common/convert_basic_shapes_to_polygon.cpp
index 2fd3664c2..fd65e5e45 100644
--- a/common/convert_basic_shapes_to_polygon.cpp
+++ b/common/convert_basic_shapes_to_polygon.cpp
@@ -207,47 +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,
- const wxPoint& aPosition, const wxSize& aSize,
- double aRotation, int aCornerRadius,
- int aCircleToSegmentsCount )
-{
- wxPoint corners[4];
- GetRoundRectCornerCenters( corners, aCornerRadius, aPosition, aSize, aRotation );
-
- SHAPE_POLY_SET outline;
- outline.NewOutline();
-
- for( int ii = 0; ii < 4; ++ii )
- outline.Append( corners[ii].x, corners[ii].y );
- outline.Inflate( aCornerRadius, aCircleToSegmentsCount );
-
- // Add the outline:
- aCornerBuffer.Append( outline );
-}
-
-
-void TransformChamferedRectToPolygon( 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
+ // 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, wxPoint( 0, 0 ), aSize, 0.0 );
+ GetRoundRectCornerCenters( corners, aCornerRadius,
+ aChamferCorners ? wxPoint( 0, 0 ) : aPosition,
+ aSize, aChamferCorners ? 0.0 : aRotation );
SHAPE_POLY_SET outline;
outline.NewOutline();
@@ -257,13 +229,24 @@ void TransformChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
outline.Inflate( aCornerRadius, aCircleToSegmentsCount );
- // Now we have the round rect outline, chamfer the TOP_LEFT corner
- // for other corners, the shape will be just mirrored or rotated
+ 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] = {1, 2, 4, 8 };
+ 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
@@ -277,17 +260,20 @@ void TransformChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
VECTOR2I corner_pos( -signX[ii]*aSize.x/2, -signY[ii]*aSize.y/2 );
- // We create 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 );
+ 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();
diff --git a/common/pcb.keywords b/common/pcb.keywords
index 7dabffd44..8f312cc9a 100644
--- a/common/pcb.keywords
+++ b/common/pcb.keywords
@@ -48,7 +48,6 @@ bottom_left
bottom_right
center
chamfer
-chamfered_rect
chamfer_ratio
circle
clearance
diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp
index 5def33435..f7e5cad46 100644
--- a/common/plotters/DXF_plotter.cpp
+++ b/common/plotters/DXF_plotter.cpp
@@ -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 );
diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp
index 2d0314116..08f0402dc 100644
--- a/common/plotters/GERBER_plotter.cpp
+++ b/common/plotters/GERBER_plotter.cpp
@@ -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 );
diff --git a/common/plotters/HPGL_plotter.cpp b/common/plotters/HPGL_plotter.cpp
index 3213292ca..0e2d194fe 100644
--- a/common/plotters/HPGL_plotter.cpp
+++ b/common/plotters/HPGL_plotter.cpp
@@ -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;
diff --git a/common/plotters/PS_plotter.cpp b/common/plotters/PS_plotter.cpp
index 8e62faf29..5c9301125 100644
--- a/common/plotters/PS_plotter.cpp
+++ b/common/plotters/PS_plotter.cpp
@@ -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 );
diff --git a/include/convert_basic_shapes_to_polygon.h b/include/convert_basic_shapes_to_polygon.h
index 461f4e35f..2755a0a43 100644
--- a/include/convert_basic_shapes_to_polygon.h
+++ b/include/convert_basic_shapes_to_polygon.h
@@ -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,26 +101,10 @@ 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
- * @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,
- const wxPoint& aPosition, const wxSize& aSize,
- double aRotation, int aCornerRadius,
- int aCircleToSegmentsCount );
/**
- * Function TransformChamferedRectToPolygon
- * 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
@@ -113,14 +112,15 @@ void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
* @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 ca 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
*/
-void TransformChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
const wxPoint& aPosition, const wxSize& aSize,
double aRotation, int aCornerRadius,
double aChamferRatio, int aChamferCorners,
diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp
index c547d79b0..cac4bf076 100644
--- a/pcbnew/board_items_to_polygon_shape_transform.cpp
+++ b/pcbnew/board_items_to_polygon_shape_transform.cpp
@@ -767,23 +767,8 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
}
break;
- case PAD_SHAPE_ROUNDRECT:
- {
- SHAPE_POLY_SET outline;
- int clearance = int( aClearanceValue * aCorrectionFactor );
- int rounding_radius = GetRoundRectCornerRadius() + clearance;
- wxSize shapesize( m_Size );
- shapesize.x += clearance*2;
- shapesize.y += clearance*2;
-
- TransformRoundRectToPolygon( outline, padShapePos, shapesize, angle,
- rounding_radius, aCircleToSegmentsCount );
-
- aCornerBuffer.Append( outline );
- }
- break;
-
case PAD_SHAPE_CHAMFERED_RECT:
+ case PAD_SHAPE_ROUNDRECT:
{
SHAPE_POLY_SET outline;
int clearance = int( aClearanceValue * aCorrectionFactor );
@@ -791,11 +776,13 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxSize shapesize( m_Size );
shapesize.x += clearance*2;
shapesize.y += clearance*2;
+ bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
- TransformChamferedRectToPolygon( outline, padShapePos, shapesize, angle,
- rounding_radius, GetChamferRectRatio(),
- GetChamferPositions(),
- aCircleToSegmentsCount );
+ TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle,
+ rounding_radius,
+ doChamfer ? GetChamferRectRatio() : 0.0,
+ doChamfer ? GetChamferPositions() : 0,
+ aCircleToSegmentsCount );
aCornerBuffer.Append( outline );
}
diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp
index 4e570ebf5..6f14a281b 100644
--- a/pcbnew/class_pad.cpp
+++ b/pcbnew/class_pad.cpp
@@ -80,8 +80,8 @@ D_PAD::D_PAD( MODULE* parent ) :
// Parameters for round rect only:
m_padRoundRectRadiusScale = 0.25; // from IPC-7351C standard
// Parameters for chamfered rect only:
- m_padChamferRectScale =.15; // Size of chamfer in percent of smallest of X,Y size
- m_chamferPositions = PAD_CHAMFER_TOP_LEFT;
+ 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
@@ -931,31 +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 );
-
- const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
- return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
- }
- break;
+ bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
- case PAD_SHAPE_CHAMFERED_RECT:
- {
- // Check for hit in polygon
- SHAPE_POLY_SET outline;
- const int segmentToCircleCount = 32;
- TransformChamferedRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
- GetRoundRectCornerRadius(), GetChamferRectRatio(),
- GetChamferPositions(), segmentToCircleCount );
+ 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:
diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h
index 11d23d71f..e829a6636 100644
--- a/pcbnew/class_pad.h
+++ b/pcbnew/class_pad.h
@@ -46,18 +46,6 @@ enum CUST_PAD_SHAPE_IN_ZONE
CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL
};
-// The chamfer positions of chamfered rect pad 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 PAD_CHAMFER_POSITIONS
-{
- PAD_CHAMFER_TOP_LEFT = 1,
- PAD_CHAMFER_TOP_RIGHT = 2,
- PAD_CHAMFER_BOTTOM_LEFT = 4,
- PAD_CHAMFER_BOTTOM_RIGHT = 8,
-};
-
class LINE_READER;
class EDA_3D_CANVAS;
class EDA_DRAW_PANEL;
diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp
index 51c34281d..3ebf4ef4b 100644
--- a/pcbnew/dialogs/dialog_pad_properties.cpp
+++ b/pcbnew/dialogs/dialog_pad_properties.cpp
@@ -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[] =
@@ -477,7 +481,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();
@@ -748,10 +753,10 @@ void DIALOG_PAD_PROPERTIES::initValues()
}
- m_cbTopLeft->SetValue( (m_dummyPad->GetChamferPositions() & PAD_CHAMFER_TOP_LEFT) );
- m_cbTopRight->SetValue( (m_dummyPad->GetChamferPositions() & PAD_CHAMFER_TOP_RIGHT) );
- m_cbBottomLeft->SetValue( (m_dummyPad->GetChamferPositions() & PAD_CHAMFER_BOTTOM_LEFT) );
- m_cbBottomRight->SetValue( (m_dummyPad->GetChamferPositions() & PAD_CHAMFER_BOTTOM_RIGHT) );
+ 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() );
@@ -1720,16 +1725,16 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
int chamfers = 0;
if( m_cbTopLeft->GetValue() )
- chamfers |= PAD_CHAMFER_TOP_LEFT;
+ chamfers |= RECT_CHAMFER_TOP_LEFT;
if( m_cbTopRight->GetValue() )
- chamfers |= PAD_CHAMFER_TOP_RIGHT;
+ chamfers |= RECT_CHAMFER_TOP_RIGHT;
if( m_cbBottomLeft->GetValue() )
- chamfers |= PAD_CHAMFER_BOTTOM_LEFT;
+ chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
if( m_cbBottomRight->GetValue() )
- chamfers |= PAD_CHAMFER_BOTTOM_RIGHT;
+ chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
aPad->SetChamferPositions( chamfers );
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.cpp b/pcbnew/dialogs/dialog_pad_properties_base.cpp
index 92408ec53..3440f01a8 100644
--- a/pcbnew/dialogs/dialog_pad_properties_base.cpp
+++ b/pcbnew/dialogs/dialog_pad_properties_base.cpp
@@ -219,13 +219,10 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_cornerRadiusLabel->Wrap( -1 );
m_cornerRadiusLabel->SetToolTip( _("Corner radius.\nCan be no more than half pad width.\nThe width is the smaller value between size X and size Y.\nNote: IPC norm gives a max value = 0.25mm.") );
- fgSizerShapeType->Add( m_cornerRadiusLabel, 0, wxRIGHT|wxLEFT, 3 );
+ fgSizerShapeType->Add( m_cornerRadiusLabel, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 3 );
- m_cornerRadiusValue = new wxStaticText( m_panelGeneral, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 );
- m_cornerRadiusValue->Wrap( -1 );
- m_cornerRadiusValue->SetToolTip( _("Corner radius.\nCan be no more than half pad width.\nThe width is the smaller value between size X and size Y\nNote: IPC norm gives a max value = 0.25mm") );
-
- fgSizerShapeType->Add( m_cornerRadiusValue, 0, wxRIGHT|wxLEFT, 3 );
+ m_tcCornerRadius = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerShapeType->Add( m_tcCornerRadius, 0, wxALL|wxEXPAND, 3 );
m_cornerRadiusUnits = new wxStaticText( m_panelGeneral, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_cornerRadiusUnits->Wrap( -1 );
@@ -238,7 +235,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
fgSizerShapeType->Add( m_staticTextChamferRatio, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_tcChamferRatio = new TEXT_CTRL_EVAL( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- fgSizerShapeType->Add( m_tcChamferRatio, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+ fgSizerShapeType->Add( m_tcChamferRatio, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 3 );
m_staticTextChamferRatioUnit = new wxStaticText( m_panelGeneral, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextChamferRatioUnit->Wrap( -1 );
@@ -763,6 +760,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_trapDeltaCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_trapAxisCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_tcCornerSizeRatio->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerSizePercentChange ), NULL, this );
+ m_tcCornerRadius->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerRadiusChange ), NULL, this );
m_tcChamferRatio->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerSizePercentChange ), NULL, this );
m_cbTopLeft->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_cbTopRight->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
@@ -815,6 +813,7 @@ DIALOG_PAD_PROPERTIES_BASE::~DIALOG_PAD_PROPERTIES_BASE()
m_trapDeltaCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_trapAxisCtrl->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_tcCornerSizeRatio->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerSizePercentChange ), NULL, this );
+ m_tcCornerRadius->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerRadiusChange ), NULL, this );
m_tcChamferRatio->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::onCornerSizePercentChange ), NULL, this );
m_cbTopLeft->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_cbTopRight->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.fbp b/pcbnew/dialogs/dialog_pad_properties_base.fbp
index 96cc215c6..a73dbc598 100644
--- a/pcbnew/dialogs/dialog_pad_properties_base.fbp
+++ b/pcbnew/dialogs/dialog_pad_properties_base.fbp
@@ -4104,7 +4104,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">3</property>
- <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@@ -4193,11 +4193,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
- <object class="sizeritem" expanded="0">
+ <object class="sizeritem" expanded="1">
<property name="border">3</property>
- <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxStaticText" expanded="0">
+ <object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@@ -4225,16 +4225,15 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
- <property name="label">dummy</property>
- <property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
+ <property name="maxlength"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
- <property name="name">m_cornerRadiusValue</property>
+ <property name="name">m_tcCornerRadius</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@@ -4245,13 +4244,17 @@
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
- <property name="subclass"></property>
+ <property name="subclass">; forward_declare</property>
<property name="toolbar_pane">0</property>
- <property name="tooltip">Corner radius.
Can be no more than half pad width.
The width is the smaller value between size X and size Y
Note: IPC norm gives a max value = 0.25mm</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
- <property name="wrap">-1</property>
<event name="OnAux1DClick"></event>
<event name="OnAux1Down"></event>
<event name="OnAux1Up"></event>
@@ -4281,6 +4284,10 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
+ <event name="OnText">onCornerRadiusChange</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
@@ -4467,7 +4474,7 @@
</object>
</object>
<object class="sizeritem" expanded="1">
- <property name="border">5</property>
+ <property name="border">3</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1">
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.h b/pcbnew/dialogs/dialog_pad_properties_base.h
index b71f962ba..eee6a4b1c 100644
--- a/pcbnew/dialogs/dialog_pad_properties_base.h
+++ b/pcbnew/dialogs/dialog_pad_properties_base.h
@@ -104,7 +104,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
TEXT_CTRL_EVAL* m_tcCornerSizeRatio;
wxStaticText* m_staticTextCornerSizeRatioUnit;
wxStaticText* m_cornerRadiusLabel;
- wxStaticText* m_cornerRadiusValue;
+ wxTextCtrl* m_tcCornerRadius;
wxStaticText* m_cornerRadiusUnits;
wxStaticText* m_staticTextChamferRatio;
TEXT_CTRL_EVAL* m_tcChamferRatio;
@@ -203,6 +203,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
virtual void PadOrientEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSetLayers( wxCommandEvent& event ) { event.Skip(); }
virtual void onCornerSizePercentChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void onCornerRadiusChange( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDrillShapeSelected( wxCommandEvent& event ) { event.Skip(); }
virtual void OnUpdateUINonCopperWarning( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onPrimitiveDClick( wxMouseEvent& event ) { event.Skip(); }
diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp
index a7581a569..296963c6f 100644
--- a/pcbnew/drc_clearance_test_functions.cpp
+++ b/pcbnew/drc_clearance_test_functions.cpp
@@ -983,7 +983,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
// coordinates ( note, the ref pad position is the origin of
// coordinates for this drc test)
int padRadius = aRefPad->GetRoundRectCornerRadius();
- TransformChamferedRectToPolygon( polysetref, wxPoint( 0, 0 ), aRefPad->GetSize(),
+ TransformRoundChamferedRectToPolygon( polysetref, wxPoint( 0, 0 ), aRefPad->GetSize(),
aRefPad->GetOrientation(),
padRadius, aRefPad->GetChamferRectRatio(),
aRefPad->GetChamferPositions(), 64 );
@@ -1025,7 +1025,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
// coordinates ( note, the ref pad position is the origin of
// coordinates for this drc test)
int padRadius = aPad->GetRoundRectCornerRadius();
- TransformChamferedRectToPolygon( polysetcompare, relativePadPos, aPad->GetSize(),
+ TransformRoundChamferedRectToPolygon( polysetcompare, relativePadPos, aPad->GetSize(),
aPad->GetOrientation(),
padRadius, aPad->GetChamferRectRatio(),
aPad->GetChamferPositions(), 64 );
@@ -1416,7 +1416,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
// Note, the pad position relative to the segment origin
// is m_padToTestPos
int padRadius = aPad->GetRoundRectCornerRadius();
- TransformChamferedRectToPolygon( polyset, m_padToTestPos, aPad->GetSize(),
+ TransformRoundChamferedRectToPolygon( polyset, m_padToTestPos, aPad->GetSize(),
aPad->GetOrientation(),
padRadius, aPad->GetChamferRectRatio(),
aPad->GetChamferPositions(), 64 );
diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp
index 3503a5d6d..66cac34d7 100644
--- a/pcbnew/exporters/export_vrml.cpp
+++ b/pcbnew/exporters/export_vrml.cpp
@@ -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;
+ }
}
}
diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp
index 779db49fe..ee88dfa08 100644
--- a/pcbnew/kicad_plugin.cpp
+++ b/pcbnew/kicad_plugin.cpp
@@ -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;
@@ -1252,8 +1253,8 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
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_CHAMFERED_RECT: shape = "chamfered_rect"; break;
case PAD_SHAPE_CUSTOM: shape = "custom"; break;
default:
@@ -1322,22 +1323,23 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
// Output the chamfer corners for chamfered rect pads
if( aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT)
{
- m_out->Print( 0, " (chamfer_ratio %s)",
+ m_out->Print( 0, "\n" );
+
+ m_out->Print( aNestLevel+1, "(chamfer_ratio %s)",
Double2Str( aPad->GetChamferRectRatio() ).c_str() );
- m_out->Print( 0, "\n" );
- m_out->Print( aNestLevel+1, " (chamfer" );
+ m_out->Print( 0, " (chamfer" );
- if( ( aPad->GetChamferPositions() & PAD_CHAMFER_TOP_LEFT ) )
+ if( ( aPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT ) )
m_out->Print( 0, " top_left" );
- if( ( aPad->GetChamferPositions() & PAD_CHAMFER_TOP_RIGHT ) )
+ if( ( aPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT ) )
m_out->Print( 0, " top_right" );
- if( ( aPad->GetChamferPositions() & PAD_CHAMFER_BOTTOM_LEFT ) )
+ if( ( aPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT ) )
m_out->Print( 0, " bottom_left" );
- if( ( aPad->GetChamferPositions() & PAD_CHAMFER_BOTTOM_RIGHT ) )
+ if( ( aPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_RIGHT ) )
m_out->Print( 0, " bottom_right" );
m_out->Print( 0, ")" );
diff --git a/pcbnew/pad_draw_functions.cpp b/pcbnew/pad_draw_functions.cpp
index 2bd5bcdf1..bdbe42d57 100644
--- a/pcbnew/pad_draw_functions.cpp
+++ b/pcbnew/pad_draw_functions.cpp
@@ -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;
- // Draw the polygon: Inflate creates only one convex polygon
SHAPE_POLY_SET outline;
- bool filled = aDrawInfo.m_ShowPadFilled;
+ TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
+ corner_radius, GetChamferRectRatio(),
+ doChamfer ? GetChamferPositions() : 0,
+ SEGCOUNT );
- 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 );
+ // Draw the polygon: Inflate creates only one convex polygon
+ bool filled = aDrawInfo.m_ShowPadFilled;
- if( outline.OutlineCount() > 0 )
- {
- SHAPE_LINE_CHAIN& poly = outline.Outline( 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,82 +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 );
-
- if( outline.OutlineCount() > 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 );
- }
- }
- }
- }
- break;
-
-
- case PAD_SHAPE_CHAMFERED_RECT:
- {
- // 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 );
-
- // Draw the polygon:
- SHAPE_POLY_SET outline;
- TransformChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
+ TransformRoundChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
corner_radius, GetChamferRectRatio(),
- GetChamferPositions(), 64 );
- bool filled = aDrawInfo.m_ShowPadFilled;
+ doChamfer ? GetChamferPositions() : 0,
+ SEGCOUNT );
- if( outline.OutlineCount() > 0 )
- {
- SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+ // Draw the polygon: Inflate creates only one convex polygon
+ SHAPE_LINE_CHAIN& clearance_poly = outline.Outline( 0 );
- if( poly.PointCount() > 0 )
- {
- GRClosedPoly( aClipBox, aDC, poly.PointCount(),
- (wxPoint*)&poly.Point( 0 ), filled, 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 );
}
-
- if( aDrawInfo.m_PadClearance )
- {
- outline.RemoveAllContours();
- size = GetSize();
- size.x += aDrawInfo.m_PadClearance * 2;
- size.y += aDrawInfo.m_PadClearance * 2;
- corner_radius = GetRoundRectCornerRadius() + aDrawInfo.m_PadClearance;
-
- TransformChamferedRectToPolygon( outline, shape_pos, size, GetOrientation(),
- corner_radius, GetChamferRectRatio(),
- GetChamferPositions(), 32 );
-
- if( outline.OutlineCount() > 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 );
- }
- }
}
- }
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
@@ -641,10 +570,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
}
}
break;
- }
-
- default:
- break;
+ }
}
// Draw the pad hole
diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp
index 8403874cd..9892c8d34 100644
--- a/pcbnew/pcb_painter.cpp
+++ b/pcbnew/pcb_painter.cpp
@@ -823,26 +823,17 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
break;
case PAD_SHAPE_ROUNDRECT:
- {
- SHAPE_POLY_SET polySet;
- wxSize prsize( size.x * 2, size.y * 2 );
- const int segmentToCircleCount = 64;
- const int corner_radius = aPad->GetRoundRectCornerRadius( prsize );
- TransformRoundRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
- 0.0, corner_radius, segmentToCircleCount );
- m_gal->DrawPolygon( polySet );
- break;
- }
-
case PAD_SHAPE_CHAMFERED_RECT:
{
SHAPE_POLY_SET polySet;
wxSize prsize( size.x * 2, size.y * 2 ); // size is the half pad area size)
const int segmentToCircleCount = 64;
const int corner_radius = aPad->GetRoundRectCornerRadius( prsize );
- TransformChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
+ bool doChamfer = shape == PAD_SHAPE_CHAMFERED_RECT;
+
+ TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), prsize,
0.0, corner_radius, aPad->GetChamferRectRatio(),
- aPad->GetChamferPositions(), segmentToCircleCount );
+ doChamfer ? aPad->GetChamferPositions() : 0, segmentToCircleCount );
m_gal->DrawPolygon( polySet );
break;
}
diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp
index 929b034f4..608b8e193 100644
--- a/pcbnew/pcb_parser.cpp
+++ b/pcbnew/pcb_parser.cpp
@@ -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,19 +2456,17 @@ 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;
- case T_chamfered_rect:
- pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
- break;
-
case T_custom:
pad->SetShape( PAD_SHAPE_CUSTOM );
break;
default:
- Expecting( "circle, rectangle, roundrect, oval, trapezoid, chamfered_rect or custom" );
+ Expecting( "circle, rectangle, roundrect, oval, trapezoid or custom" );
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
@@ -2642,6 +2641,10 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
case T_chamfer_ratio:
pad->SetChamferRectRatio( parseDouble( "chamfer ratio" ) );
+
+ if( pad->GetChamferRectRatio() > 0 )
+ pad->SetShape( PAD_SHAPE_CHAMFERED_RECT );
+
NeedRIGHT();
break;
@@ -2656,19 +2659,19 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
switch( token )
{
case T_top_left:
- chamfers |= PAD_CHAMFER_TOP_LEFT;
+ chamfers |= RECT_CHAMFER_TOP_LEFT;
break;
case T_top_right:
- chamfers |= PAD_CHAMFER_TOP_RIGHT;
+ chamfers |= RECT_CHAMFER_TOP_RIGHT;
break;
case T_bottom_left:
- chamfers |= PAD_CHAMFER_BOTTOM_LEFT;
+ chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
break;
case T_bottom_right:
- chamfers |= PAD_CHAMFER_BOTTOM_RIGHT;
+ chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
break;
case T_RIGHT:
@@ -2680,6 +2683,9 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent )
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;
diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp
index 8fabf7ba2..469febcb0 100644
--- a/pcbnew/plot_brditems_plotter.cpp
+++ b/pcbnew/plot_brditems_plotter.cpp
@@ -192,7 +192,7 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPl
SHAPE_POLY_SET polygons;
const int segmentToCircleCount = 64;
const int corner_radius = aPad->GetRoundRectCornerRadius( aPad->GetSize() );
- TransformChamferedRectToPolygon( polygons, shape_pos, aPad->GetSize(),
+ TransformRoundChamferedRectToPolygon( polygons, shape_pos, aPad->GetSize(),
aPad->GetOrientation(), corner_radius, aPad->GetChamferRectRatio(),
aPad->GetChamferPositions(), segmentToCircleCount );
diff --git a/pcbnew/specctra_import_export/specctra_export.cpp b/pcbnew/specctra_import_export/specctra_export.cpp
index 1b5ea27a8..54ea174b8 100644
--- a/pcbnew/specctra_import_export/specctra_export.cpp
+++ b/pcbnew/specctra_import_export/specctra_export.cpp
@@ -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 )
--
2.17.0.windows.1
References