kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #22797
Re: [PATCH] new feature: adding rounded rect pads
Le 20/01/2016 20:03, Clemens Koller a écrit :
> Hello, Jean-Pierre and Mathias!
>
> Thank you a lot for this feature, which I need to move
> on with migrating my work over to Kicad.
> I can and will take care of testing this on Linux.
> Unfortunately, I am quite busy till next monday...
>
> On which bzr/git tag is your patch supposed to apply?
BZR 6501
>
> Then Heads-Up:
> I just realized that my editor complains that the patch
> contains non-UTF-8 characters. (ISO-8859-14 seems to work
> somehow) What source-code encoding do we ideally want to use?
OK I see the issue: patch was created from a French Window version.
In comments added by the BZR utility I used, some non ASCII letters
where used.
Here is the same version in English (only ASCII codes) I hope.
>
> Regards,
>
> Clemens
>
>
> On 2016-01-20 19:41, jp charras wrote:
>> Gentlemen,
>>
>> Attached a patch which adds rounded rectangle pads to Pcbnew.
>>
>> I *need testers* especially to test the DRC (but test also print and plot).
>> In order to support this new shape, the DRC code was widely modified and
>> cleaned.
>> Therefore bugs can happen, not only with rounded rect pads, but with
>> other pads.
>>
>> Please, use this patch *only for tests*: the .kicad_pcb file format is
>> not compatible with the current Pcbnew version if Rounded Rect pads are
>> stored in file, and this new file format to support them is not yet
>> fully defined.
>>
>> Thanks to Mathias Grimmberger. His patch helped me to start this work.
>>
>> Thanks.
>>
>>
>>
>> _______________________________________________
>> Mailing list: https://launchpad.net/~kicad-developers
>> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
>> Unsubscribe : https://launchpad.net/~kicad-developers
>> More help : https://help.launchpad.net/ListHelp
>>
>
> _______________________________________________
> Mailing list: https://launchpad.net/~kicad-developers
> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~kicad-developers
> More help : https://help.launchpad.net/ListHelp
>
--
Jean-Pierre CHARRAS
=== modified file 'common/common_plotDXF_functions.cpp'
--- common/common_plotDXF_functions.cpp 2015-12-15 20:21:25 +0000
+++ common/common_plotDXF_functions.cpp 2016-01-15 09:41:03 +0000
@@ -5,7 +5,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ * Copyright (C) 2016 KiCad Developers, see CHANGELOG.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
@@ -617,6 +617,25 @@
FinishTo( wxPoint( ox, oy ) );
}
+void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode )
+{
+ SHAPE_POLY_SET outline;
+ const int segmentToCircleCount = 64;
+ TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
+ aCornerRadius, segmentToCircleCount );
+
+ // TransformRoundRectToPolygon creates only one convex polygon
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+
+ MoveTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) );
+
+ for( int ii = 1; ii < poly.PointCount(); ++ii )
+ LineTo( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
+
+ FinishTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) );
+}
/**
* DXF trapezoidal pad: only sketch mode is supported
=== modified file 'common/common_plotGERBER_functions.cpp'
--- common/common_plotGERBER_functions.cpp 2015-06-26 13:41:56 +0000
+++ common/common_plotGERBER_functions.cpp 2016-01-15 09:44:51 +0000
@@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2016 KiCad Developers, see CHANGELOG.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
@@ -36,6 +36,7 @@
#include <plot_common.h>
#include <macros.h>
#include <kicad_string.h>
+#include <convert_basic_shapes_to_polygon.h>
#include <build_version.h>
@@ -479,8 +480,9 @@
if( trace_mode == FILLED )
{
- /* XXX to do: use an aperture macro to declare the rotated pad */
- /* The pad is reduced to an oval with dy > dx */
+ // TODO: use an aperture macro to declare the rotated pad
+ //
+ // The pad is reduced to an segment with dy > dx
delta = size.y - size.x;
x0 = 0;
y0 = -delta / 2;
@@ -559,12 +561,39 @@
}
}
+void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode )
+
+{
+ // Currently, a Pad RoundRect is plotted as polygon.
+ // TODO: use Aperture macro and flash it
+ SHAPE_POLY_SET outline;
+ const int segmentToCircleCount = 64;
+ TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
+ aCornerRadius, segmentToCircleCount );
+
+ std::vector< wxPoint > cornerList;
+ cornerList.reserve( segmentToCircleCount + 5 );
+ // TransformRoundRectToPolygon creates only one convex polygon
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+
+ for( int ii = 0; ii < poly.PointCount(); ++ii )
+ cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
+
+ // Close polygon
+ cornerList.push_back( cornerList[0] );
+
+ PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL );
+}
void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
{
- // XXX to do: use an aperture macro to declare the pad
+ // Currently, a Pad Trapezoid is plotted as polygon.
+ // TODO: use Aperture macro and flash it
+
// polygon corners list
std::vector< wxPoint > cornerList;
=== modified file 'common/common_plotHPGL_functions.cpp'
--- common/common_plotHPGL_functions.cpp 2015-06-26 13:41:56 +0000
+++ common/common_plotHPGL_functions.cpp 2016-01-15 09:40:29 +0000
@@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2016 KiCad Developers, see CHANGELOG.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
@@ -197,6 +197,7 @@
#include <plot_common.h>
#include <macros.h>
#include <kicad_string.h>
+#include <convert_basic_shapes_to_polygon.h>
// HPGL scale factor (1 PLU = 1/40mm = 25 micrometers)
static const double PLUsPERDECIMIL = 0.102041;
@@ -633,6 +634,34 @@
}
}
+void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode )
+{
+ SHAPE_POLY_SET outline;
+ const int segmentToCircleCount = 32;
+ TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
+ aCornerRadius, segmentToCircleCount );
+
+ std::vector< wxPoint > cornerList;
+ cornerList.reserve( segmentToCircleCount + 4 );
+ // TransformRoundRectToPolygon creates only one convex polygon
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+
+ if( 0 /*aTrace_Mode == FILLED*/ )
+ {
+ // TODO:
+ }
+ else
+ {
+ MoveTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) );
+
+ for( int ii = 1; ii < poly.PointCount(); ++ii )
+ LineTo( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
+
+ FinishTo(wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) );
+ }
+}
void HPGL_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
=== modified file 'common/common_plotPS_functions.cpp'
--- common/common_plotPS_functions.cpp 2015-06-26 13:41:56 +0000
+++ common/common_plotPS_functions.cpp 2016-01-15 09:40:54 +0000
@@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2016 KiCad Developers, see CHANGELOG.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
@@ -35,6 +35,7 @@
#include <plot_common.h>
#include <macros.h>
#include <kicad_string.h>
+#include <convert_basic_shapes_to_polygon.h>
/* Forward declaration of the font width metrics
(yes extern! this is the way to forward declare variables */
@@ -188,6 +189,42 @@
GetCurrentLineWidth() );
}
+void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode )
+{
+ wxSize size( aSize );
+
+ if( aTraceMode == FILLED )
+ SetCurrentLineWidth( 0 );
+ else
+ {
+ SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
+ size.x -= GetCurrentLineWidth();
+ size.y -= GetCurrentLineWidth();
+ aCornerRadius -= GetCurrentLineWidth()/2;
+ }
+
+
+ SHAPE_POLY_SET outline;
+ const int segmentToCircleCount = 64;
+ TransformRoundRectToPolygon( outline, aPadPos, size, aOrient,
+ aCornerRadius, segmentToCircleCount );
+
+ std::vector< wxPoint > cornerList;
+ cornerList.reserve( segmentToCircleCount + 5 );
+ // TransformRoundRectToPolygon creates only one convex polygon
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+
+ for( int ii = 0; ii < poly.PointCount(); ++ii )
+ cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
+
+ // Close polygon
+ cornerList.push_back( cornerList[0] );
+
+ PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL,
+ GetCurrentLineWidth() );
+}
void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode )
=== modified file 'common/convert_basic_shapes_to_polygon.cpp'
--- common/convert_basic_shapes_to_polygon.cpp 2015-07-27 19:45:57 +0000
+++ common/convert_basic_shapes_to_polygon.cpp 2016-01-17 16:26:21 +0000
@@ -64,6 +64,71 @@
}
}
+/* Returns the centers of the rounded corners of a rect.
+ */
+void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
+ const wxPoint& aPosition, const wxSize& aSize, double aRotation )
+{
+ wxSize size( aSize/2 );
+
+ size.x -= aRadius;
+ size.y -= aRadius;
+
+ aCenters[0].x = -size.x;
+ aCenters[0].y = size.y;
+
+ aCenters[1].x = size.x;
+ aCenters[1].y = size.y;
+
+ aCenters[2].x = size.x;
+ aCenters[2].y = -size.y;
+
+ aCenters[3].x = -size.x;
+ aCenters[3].y = -size.y;
+
+ // Rotate the polygon
+ if( aRotation )
+ {
+ for( int ii = 0; ii < 4; ii++ )
+ RotatePoint( &aCenters[ii], aRotation );
+ }
+
+ // move the polygon to the position
+ for( int ii = 0; ii < 4; ii++ )
+ 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 aRadius = 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 );
+}
+
/**
* Function TransformRoundedEndsSegmentToPolygon
=== modified file 'common/pcb.keywords'
--- common/pcb.keywords 2013-09-17 00:52:08 +0000
+++ common/pcb.keywords 2016-01-12 13:19:27 +0000
@@ -142,6 +142,7 @@
reference
right
rotate
+roundrect
scale
segment
segment_width
=== modified file 'include/convert_basic_shapes_to_polygon.h'
--- include/convert_basic_shapes_to_polygon.h 2016-01-12 16:33:33 +0000
+++ include/convert_basic_shapes_to_polygon.h 2016-01-17 16:13:53 +0000
@@ -51,6 +51,34 @@
int aCircleToSegmentsCount );
/**
+ * Helper function GetRoundRectCornerCenters
+ * Has meaning only for rounded rect
+ * Returns the centers of the rounded corners.
+ * @param aPosition = position of the round rect
+ * @param aSize = size of the of the round rect.
+ * @param aRotation = rotation of the of the round rect
+ * @param aCenters a buffer to store the 4 coordinates.
+ */
+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 TransformRoundedEndsSegmentToPolygon
* convert a segment with rounded ends to a polygon
* Convert arcs to multiple straight lines
=== modified file 'include/pad_shapes.h'
--- include/pad_shapes.h 2016-01-12 16:33:33 +0000
+++ include/pad_shapes.h 2016-01-13 07:54:46 +0000
@@ -37,7 +37,8 @@
PAD_SHAPE_OVAL,
PAD_OVAL = PAD_SHAPE_OVAL,
PAD_SHAPE_TRAPEZOID,
- PAD_TRAPEZOID = PAD_SHAPE_TRAPEZOID
+ PAD_TRAPEZOID = PAD_SHAPE_TRAPEZOID,
+ PAD_SHAPE_ROUNDRECT
};
/**
=== modified file 'include/plot_common.h'
--- include/plot_common.h 2015-05-21 09:04:47 +0000
+++ include/plot_common.h 2016-01-14 15:08:00 +0000
@@ -280,6 +280,18 @@
virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode ) = 0;
+ /**
+ * virtual function FlashPadRoundRect
+ * @param aPadPos Position of the shape (center of the rectangle
+ * @param aSize = size of rouded rect
+ * @param cornerRadius Radius of the rounded corners
+ * @param aOrient The rotation of the shape
+ * @param aTraceMode FILLED or SKETCH
+ */
+ virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode ) = 0;
+
/** virtual function FlashPadTrapez
* flash a trapezoidal pad
* @param aPadPos = the position of the shape
@@ -534,6 +546,9 @@
EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
+ virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
@@ -586,6 +601,9 @@
EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
+ virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
@@ -942,14 +960,25 @@
EDA_DRAW_MODE_T trace_mode );
/**
- * Filled rect flashes are handled as aperture in the 90 degree positions only
+ * Filled rect flashes are handled as aperture in the 0 90 180 or 270 degree orientation only
+ * and as polygon for other orientations
+ * TODO: always use flashed shapes (aperture macros)
*/
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
/**
+ * Roundrect pad at the moment are not handled as aperture, since
+ * they require aperture macros
+ * TODO: always use flashed shapes (aperture macros)
+ */
+ virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode );
+ /**
* Trapezoidal pad at the moment are *never* handled as aperture, since
* they require aperture macros
+ * TODO: always use flashed shapes (aperture macros)
*/
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
@@ -1069,6 +1098,9 @@
EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
+ virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
+ int aCornerRadius, double aOrient,
+ EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
=== modified file 'pcbnew/board_items_to_polygon_shape_transform.cpp'
--- pcbnew/board_items_to_polygon_shape_transform.cpp 2015-12-15 20:21:25 +0000
+++ pcbnew/board_items_to_polygon_shape_transform.cpp 2016-01-15 16:12:02 +0000
@@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2009-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2009-2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2016 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
@@ -552,7 +552,7 @@
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
*/
-void D_PAD:: TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor ) const
@@ -561,14 +561,14 @@
int dx = (m_Size.x / 2) + aClearanceValue;
int dy = (m_Size.y / 2) + aClearanceValue;
- wxPoint PadShapePos = ShapePos(); /* Note: for pad having a shape offset,
+ wxPoint padShapePos = ShapePos(); /* Note: for pad having a shape offset,
* the pad position is NOT the shape position */
switch( GetShape() )
{
case PAD_SHAPE_CIRCLE:
dx = KiROUND( dx * aCorrectionFactor );
- TransformCircleToPolygon( aCornerBuffer, PadShapePos, dx,
+ TransformCircleToPolygon( aCornerBuffer, padShapePos, dx,
aCircleToSegmentsCount );
break;
@@ -591,8 +591,8 @@
}
RotatePoint( &shape_offset, angle );
- wxPoint start = PadShapePos - shape_offset;
- wxPoint end = PadShapePos + shape_offset;
+ wxPoint start = padShapePos - shape_offset;
+ wxPoint end = padShapePos + shape_offset;
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, start, end,
aCircleToSegmentsCount, width );
}
@@ -605,18 +605,33 @@
BuildPadPolygon( corners, wxSize( 0, 0 ), angle );
SHAPE_POLY_SET outline;
-
outline.NewOutline();
for( int ii = 0; ii < 4; ii++ )
{
- corners[ii] += PadShapePos;
+ corners[ii] += padShapePos;
outline.Append( corners[ii].x, corners[ii].y );
}
- double rounding_radius = aClearanceValue * aCorrectionFactor;
-
- outline.Inflate( (int) rounding_radius, aCircleToSegmentsCount );
+ int rounding_radius = int( aClearanceValue * aCorrectionFactor );
+ outline.Inflate( rounding_radius, aCircleToSegmentsCount );
+
+ aCornerBuffer.Append( outline );
+ }
+ break;
+
+ case PAD_SHAPE_ROUNDRECT:
+ {
+ SHAPE_POLY_SET outline;
+ int pad_radius = GetRoundRectCornerRadius();
+ int clearance = int( aClearanceValue * aCorrectionFactor );
+ int rounding_radius = pad_radius + clearance;
+ wxSize shapesize( m_Size );
+ shapesize.x += clearance*2;
+ shapesize.y += clearance*2;
+
+ TransformRoundRectToPolygon( outline, padShapePos, shapesize, angle,
+ rounding_radius, aCircleToSegmentsCount );
aCornerBuffer.Append( outline );
}
@@ -636,12 +651,13 @@
double aCorrectionFactor ) const
{
wxPoint corners[4];
- wxPoint PadShapePos = ShapePos(); /* Note: for pad having a shape offset,
- * the pad position is NOT the shape position */
+ wxPoint padShapePos = ShapePos(); /* Note: for pad having a shape offset,
+ * the pad position is NOT the shape position */
switch( GetShape() )
{
case PAD_SHAPE_CIRCLE:
case PAD_SHAPE_OVAL:
+ case PAD_SHAPE_ROUNDRECT:
TransformShapeWithClearanceToPolygon( aCornerBuffer, aInflateValue.x,
aSegmentsPerCircle, aCorrectionFactor );
break;
@@ -653,7 +669,7 @@
BuildPadPolygon( corners, aInflateValue, m_Orient );
for( int ii = 0; ii < 4; ii++ )
{
- corners[ii] += PadShapePos; // Shift origin to position
+ corners[ii] += padShapePos; // Shift origin to position
aCornerBuffer.Append( corners[ii].x, corners[ii].y );
}
@@ -734,7 +750,7 @@
double aThermalRot )
{
wxPoint corner, corner_end;
- wxPoint PadShapePos = aPad.ShapePos(); // Note: for pad having a shape offset,
+ wxPoint padShapePos = aPad.ShapePos(); // Note: for pad having a shape offset,
// the pad position is NOT the shape position
wxSize copper_thickness;
@@ -836,7 +852,7 @@
{
corner = corners_buffer[ii];
RotatePoint( &corner, th_angle + angle_pad ); // Rotate by segment angle and pad orientation
- corner += PadShapePos;
+ corner += padShapePos;
aCornerBuffer.Append( corner.x, corner.y );
}
@@ -940,7 +956,7 @@
{
wxPoint cpos = corners_buffer[ic];
RotatePoint( &cpos, angle );
- cpos += PadShapePos;
+ cpos += padShapePos;
aCornerBuffer.Append( cpos.x, cpos.y );
}
@@ -966,7 +982,7 @@
{
wxPoint cpos = corners_buffer[ic];
RotatePoint( &cpos, angle );
- cpos += PadShapePos;
+ cpos += padShapePos;
aCornerBuffer.Append( cpos.x, cpos.y );
}
@@ -975,7 +991,8 @@
}
break;
- case PAD_SHAPE_RECT: // draw 4 Holes
+ case PAD_SHAPE_ROUNDRECT: // thermal shape is the same for round rect and rect.
+ case PAD_SHAPE_RECT:
{
/* we create 4 copper holes and put them in position 1, 2, 3 and 4
* here is the area of the rectangular pad + its thermal gap
@@ -1039,7 +1056,7 @@
{
wxPoint cpos = corners_buffer[ic];
RotatePoint( &cpos, angle ); // Rotate according to module orientation
- cpos += PadShapePos; // Shift origin to position
+ cpos += padShapePos; // Shift origin to position
aCornerBuffer.Append( cpos.x, cpos.y );
}
@@ -1063,7 +1080,7 @@
{
wxPoint cpos = corners_buffer[ic];
RotatePoint( &cpos, angle );
- cpos += PadShapePos;
+ cpos += padShapePos;
aCornerBuffer.Append( cpos.x, cpos.y );
}
@@ -1110,7 +1127,7 @@
{
wxPoint cpos = stubBuffer[ii];
RotatePoint( &cpos, aPad.GetOrientation() );
- cpos += PadShapePos;
+ cpos += padShapePos;
stub.Append( cpos.x, cpos.y );
}
@@ -1132,7 +1149,7 @@
{
wxPoint cpos = stubBuffer[ii];
RotatePoint( &cpos, aPad.GetOrientation() );
- cpos += PadShapePos;
+ cpos += padShapePos;
stub.Append( cpos.x, cpos.y );
}
=== modified file 'pcbnew/class_pad.cpp'
--- pcbnew/class_pad.cpp 2015-12-27 15:51:13 +0000
+++ pcbnew/class_pad.cpp 2016-01-17 15:36:38 +0000
@@ -48,6 +48,7 @@
#include <polygon_test_point_inside.h>
#include <convert_from_iu.h>
#include <boost/foreach.hpp>
+#include <convert_basic_shapes_to_polygon.h>
int D_PAD::m_PadSketchModePenSize = 0; // Pen size used to draw pads in sketch mode
@@ -74,6 +75,10 @@
m_LocalSolderMaskMargin = 0;
m_LocalSolderPasteMargin = 0;
m_LocalSolderPasteMarginRatio = 0.0;
+ // Parameters for round rect only:
+ m_padRoundRectRadiusScale = 0.25; // from IPC-7351C standard
+ m_padRoundRectRadiusMax = Millimeter2iu( 0.25 ); // from IPC-7351C standard
+
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
@@ -110,8 +115,6 @@
LSET D_PAD::UnplatedHoleMask()
{
- // was #define PAD_ATTRIB_HOLE_NOT_PLATED_DEFAULT_LAYERS ALL_CU_LAYERS |
- // SILKSCREEN_LAYER_FRONT | SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT
static LSET saved = LSET::AllCuMask() | LSET( 3, F_SilkS, B_Mask, F_Mask );
return saved;
}
@@ -142,6 +145,13 @@
radius = 1 + KiROUND( hypot( x, y ) / 2 );
break;
+ case PAD_SHAPE_ROUNDRECT:
+ radius = GetRoundRectCornerRadius();
+ x = m_Size.x >> 1;
+ y = m_Size.y >> 1;
+ radius += 1 + KiROUND( EuclideanNorm( wxSize( x - radius, y - radius )));
+ break;
+
default:
radius = 0;
}
@@ -150,6 +160,23 @@
}
+int D_PAD::GetRoundRectCornerRadius( const wxSize& aSize ) const
+{
+ // radius of rounded corners, usually 25% of shorter pad edge for now
+ int r = aSize.x > aSize.y ? aSize.y : aSize.x;
+ r = int( r * m_padRoundRectRadiusScale );
+
+ // but not more than usually 0.25 mm
+
+ if ( r > m_padRoundRectRadiusMax )
+ {
+ r = m_padRoundRectRadiusMax;
+ }
+
+ return r;
+}
+
+
const EDA_RECT D_PAD::GetBoundingBox() const
{
EDA_RECT area;
@@ -180,6 +207,7 @@
break;
case PAD_SHAPE_RECT:
+ case PAD_SHAPE_ROUNDRECT:
//Use two corners and track their rotation
// (utilise symmetry to avoid four points)
quadrant1.x = m_Size.x/2;
@@ -768,6 +796,19 @@
return true;
break;
+
+ case PAD_SHAPE_ROUNDRECT:
+ {
+ // Check for hit in polygon
+ SHAPE_POLY_SET outline;
+ const int segmentToCircleCount = 32;
+ TransformRoundRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,
+ GetRoundRectCornerRadius(), segmentToCircleCount );
+
+ SHAPE_LINE_CHAIN &poly = outline.Outline( 0 );
+ return TestPointInsidePolygon( (wxPoint*)&poly.Point(0), poly.PointCount(), delta );
+ }
+ break;
}
return false;
@@ -854,6 +895,9 @@
case PAD_SHAPE_TRAPEZOID:
return _( "Trap" );
+ case PAD_SHAPE_ROUNDRECT:
+ return _( "Roundrect" );
+
default:
return wxT( "???" );
}
=== modified file 'pcbnew/class_pad.h'
--- pcbnew/class_pad.h 2015-11-13 11:32:42 +0000
+++ pcbnew/class_pad.h 2016-01-20 17:03:51 +0000
@@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@xxxxxxxxxxxxxxxxxx
- * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2016 Jean-Pierre Charras, jaen-pierre.charras@xxxxxxxxxxxxxxxxxx
+ * Copyright (C) 1992-2016 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
@@ -324,6 +324,27 @@
void BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, double aRotation ) const;
/**
+ * Function GetRoundRectCornerRadius
+ * Has meaning only for rounded rect pads
+ * @return The radius of the rounded corners for this pad.
+ */
+ int GetRoundRectCornerRadius() const
+ {
+ return GetRoundRectCornerRadius( m_Size );
+ }
+
+ /**
+ * Helper function GetRoundRectCornerRadius
+ * Has meaning only for rounded rect pads
+ * Returns the radius of the rounded corners of a rectangle
+ * size aSize, using others setting of the pad
+ * @param aSize = size of the of the round rect. Usually the pad size
+ * but can be the size of the pad on solder mask or solder paste
+ * @return The radius of the rounded corners for this pad size.
+ */
+ int GetRoundRectCornerRadius( const wxSize& aSize ) const;
+
+ /**
* Function BuildPadShapePolygon
* Build the Corner list of the polygonal shape,
* depending on shape, extra size (clearance ...) pad and orientation
@@ -340,7 +361,7 @@
* @param aSegmentsPerCircle = number of segments to approximate a circle
* (used for round and oblong shapes only (16 to 32 is a good value)
* @param aCorrectionFactor = the correction to apply to circles radius to keep
- * the pad size when the circle is approximated by segments
+ * the pad size/clearance when the arcs are approximated by segments
*/
void BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
wxSize aInflateValue, int aSegmentsPerCircle,
@@ -531,7 +552,7 @@
wxPoint m_Pos; ///< pad Position on board
- PAD_SHAPE_T m_padShape; ///< Shape: PAD_CIRCLE, PAD_RECT, PAD_OVAL, PAD_TRAPEZOID
+ PAD_SHAPE_T m_padShape; ///< Shape: PAD_CIRCLE, PAD_RECT, PAD_OVAL, PAD_TRAPEZOID, PAD_ROUNDRECT
int m_SubRatsnest; ///< variable used in rats nest computations
@@ -545,6 +566,10 @@
PAD_DRILL_SHAPE_T m_drillShape; ///< PAD_DRILL_SHAPE_CIRCLE, PAD_DRILL_SHAPE_OBLONG
+ double m_padRoundRectRadiusScale; ///< scaling factor from smallest m_Size coord
+ ///< to corner radius, default 0.25
+ int m_padRoundRectRadiusMax; ///< max corner radius
+
/**
* m_Offset is useful only for oblong pads (it can be used for other
=== modified file 'pcbnew/class_pad_draw_functions.cpp'
--- pcbnew/class_pad_draw_functions.cpp 2016-01-17 15:59:24 +0000
+++ pcbnew/class_pad_draw_functions.cpp 2016-01-20 17:03:36 +0000
@@ -1,10 +1,10 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@xxxxxxxxxxxxxxx
+ * Copyright (C) 2016 Jean-Pierre Charras, jean-pierre.charras@xxxxxxxxxxxxxxx
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@xxxxxxxxxxx>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
- * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2016 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
@@ -40,6 +40,8 @@
#include <pcbnew_id.h> // ID_TRACK_BUTT
#include <pcbnew.h>
#include <class_board.h>
+#include <convert_basic_shapes_to_polygon.h>
+
/* uncomment this line to show this pad with its specfic size and color
@@ -315,7 +317,7 @@
void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
{
- wxPoint coord[4];
+ wxPoint coord[12];
double angle = m_Orient;
int seg_width;
@@ -392,12 +394,67 @@
if( aDrawInfo.m_PadClearance )
{
- BuildPadPolygon( coord, wxSize( aDrawInfo.m_PadClearance,
- aDrawInfo.m_PadClearance ), angle );
- for( int ii = 0; ii < 4; ii++ )
- coord[ii] += shape_pos;
-
- GRClosedPoly( aClipBox, aDC, 4, coord, 0, aDrawInfo.m_Color, aDrawInfo.m_Color );
+ #define SEGCOUNT 32 // number of segments to approximate a circle
+ SHAPE_POLY_SET outline;
+ TransformShapeWithClearanceToPolygon( outline, aDrawInfo.m_PadClearance, SEGCOUNT, 1.0 );
+
+ // Draw the polygon: Inflate creates only one convex polygon
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+
+ GRClosedPoly( aClipBox, aDC, poly.PointCount(),
+ (wxPoint*)&poly.Point( 0 ), false, 0,
+ aDrawInfo.m_Color, aDrawInfo.m_Color );
+ }
+ break;
+
+ 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 );
+
+ // Draw the polygon: Inflate creates only one convex polygon
+ SHAPE_POLY_SET outline;
+ bool filled = aDrawInfo.m_ShowPadFilled;
+
+ if( filled )
+ {
+ wxPoint centers[4];
+ GetRoundRectCornerCenters( centers, corner_radius, shape_pos,
+ size, GetOrientation() );
+ GRClosedPoly( aClipBox, aDC, 4, centers, true, corner_radius*2,
+ aDrawInfo.m_Color, aDrawInfo.m_Color );
+ }
+ else
+ {
+ TransformRoundRectToPolygon( outline, shape_pos, size, GetOrientation(),
+ corner_radius, 64 );
+
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+
+ GRClosedPoly( aClipBox, aDC, poly.PointCount(),
+ (wxPoint*)&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;
+
+ TransformRoundRectToPolygon( outline, shape_pos, size, GetOrientation(),
+ corner_radius, 32 );
+
+ // Draw the polygon: Inflate creates only one convex polygon
+ SHAPE_LINE_CHAIN& clearance_poly = outline.Outline( 0 );
+
+ GRClosedPoly( aClipBox, aDC, clearance_poly.PointCount(),
+ (wxPoint*)&clearance_poly.Point( 0 ), false, 0,
+ aDrawInfo.m_Color, aDrawInfo.m_Color );
+ }
}
break;
=== modified file 'pcbnew/dialogs/dialog_pad_properties.cpp'
--- pcbnew/dialogs/dialog_pad_properties.cpp 2015-12-27 15:51:13 +0000
+++ pcbnew/dialogs/dialog_pad_properties.cpp 2016-01-12 13:19:27 +0000
@@ -55,7 +55,8 @@
PAD_SHAPE_CIRCLE,
PAD_SHAPE_OVAL,
PAD_SHAPE_RECT,
- PAD_SHAPE_TRAPEZOID
+ PAD_SHAPE_TRAPEZOID,
+ PAD_SHAPE_ROUNDRECT
};
@@ -510,6 +511,10 @@
case PAD_SHAPE_TRAPEZOID:
m_PadShape->SetSelection( 3 );
break;
+
+ case PAD_SHAPE_ROUNDRECT:
+ m_PadShape->SetSelection( 4 );
+ break;
}
msg.Printf( wxT( "%g" ), angle );
@@ -590,6 +595,14 @@
m_ShapeOffset_X_Ctrl->Enable( true );
m_ShapeOffset_Y_Ctrl->Enable( true );
break;
+
+ case 4: // PAD_SHAPE_ROUNDRECT:
+ m_ShapeDelta_Ctrl->Enable( false );
+ m_trapDeltaDirChoice->Enable( false );
+ m_ShapeSize_Y_Ctrl->Enable( true );
+ m_ShapeOffset_X_Ctrl->Enable( true );
+ m_ShapeOffset_Y_Ctrl->Enable( true );
+ break;
}
transferDataToPad( m_dummyPad );
@@ -1136,6 +1149,10 @@
case PAD_SHAPE_TRAPEZOID:
break;
+ case PAD_SHAPE_ROUNDRECT:
+ aPad->SetDelta( wxSize( 0, 0 ) );
+ break;
+
default:
;
}
=== modified file 'pcbnew/dialogs/dialog_pad_properties_base.cpp'
--- pcbnew/dialogs/dialog_pad_properties_base.cpp 2015-09-11 23:13:54 +0000
+++ pcbnew/dialogs/dialog_pad_properties_base.cpp 2016-01-12 13:35:15 +0000
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// C++ code generated with wxFormBuilder (version Jan 1 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@@ -40,7 +40,6 @@
fgSizerPadType->Add( m_PadNumText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_PadNumCtrl = new wxTextCtrl( m_panelGeneral, wxID_PADNUMCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_PadNumCtrl->SetMaxLength( 0 );
fgSizerPadType->Add( m_PadNumCtrl, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
m_PadNameText = new wxStaticText( m_panelGeneral, wxID_ANY, _("Net name:"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -48,7 +47,6 @@
fgSizerPadType->Add( m_PadNameText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
m_PadNetNameCtrl = new wxTextCtrl( m_panelGeneral, wxID_PADNETNAMECTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_PadNetNameCtrl->SetMaxLength( 0 );
fgSizerPadType->Add( m_PadNetNameCtrl, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
m_staticText44 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Pad type:"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -65,7 +63,7 @@
m_staticText45->Wrap( -1 );
fgSizerPadType->Add( m_staticText45, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
- wxString m_PadShapeChoices[] = { _("Circular"), _("Oval"), _("Rectangular"), _("Trapezoidal") };
+ wxString m_PadShapeChoices[] = { _("Circular"), _("Oval"), _("Rectangular"), _("Trapezoidal"), _("Rounded Rectangle") };
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 );
@@ -85,7 +83,6 @@
fgSizerShapeType->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_PadPosition_X_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_PadPosition_X_Ctrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_PadPosition_X_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_PadPosX_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -97,7 +94,6 @@
fgSizerShapeType->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_PadPosition_Y_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_PadPosition_Y_Ctrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_PadPosition_Y_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_PadPosY_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -109,7 +105,6 @@
fgSizerShapeType->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_ShapeSize_X_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_ShapeSize_X_Ctrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_ShapeSize_X_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_PadShapeSizeX_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -121,7 +116,6 @@
fgSizerShapeType->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_ShapeSize_Y_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_ShapeSize_Y_Ctrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_ShapeSize_Y_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_PadShapeSizeY_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -147,7 +141,6 @@
fgSizerShapeType->Add( m_PadOrientText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_PadOrientCtrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_PadOrientCtrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_PadOrientCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_customOrientUnits = new wxStaticText( m_panelGeneral, wxID_ANY, _("0.1 deg"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -159,7 +152,6 @@
fgSizerShapeType->Add( m_staticText17, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_ShapeOffset_X_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_ShapeOffset_X_Ctrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_ShapeOffset_X_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_PadShapeOffsetX_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -171,7 +163,6 @@
fgSizerShapeType->Add( m_staticText19, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_ShapeOffset_Y_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_ShapeOffset_Y_Ctrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_ShapeOffset_Y_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_PadShapeOffsetY_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -185,7 +176,6 @@
fgSizerShapeType->Add( m_staticText38, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_LengthPadToDieCtrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_LengthPadToDieCtrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_LengthPadToDieCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_PadLengthDie_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -197,7 +187,6 @@
fgSizerShapeType->Add( m_staticText21, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 );
m_ShapeDelta_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_ShapeDelta_Ctrl->SetMaxLength( 0 );
fgSizerShapeType->Add( m_ShapeDelta_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_PadShapeDelta_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -230,19 +219,19 @@
fgSizer4->SetFlexibleDirection( wxBOTH );
fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
- m_staticTitleModuleRot = new wxStaticText( m_panelGeneral, wxID_ANY, _("Rotation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTitleModuleRot = new wxStaticText( sbSizeModuleInfo->GetStaticBox(), wxID_ANY, _("Rotation:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTitleModuleRot->Wrap( -1 );
fgSizer4->Add( m_staticTitleModuleRot, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
- m_staticModuleRotValue = new wxStaticText( m_panelGeneral, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticModuleRotValue = new wxStaticText( sbSizeModuleInfo->GetStaticBox(), wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticModuleRotValue->Wrap( -1 );
fgSizer4->Add( m_staticModuleRotValue, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
- m_staticTitleModuleSide = new wxStaticText( m_panelGeneral, wxID_ANY, _("Board side:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTitleModuleSide = new wxStaticText( sbSizeModuleInfo->GetStaticBox(), wxID_ANY, _("Board side:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTitleModuleSide->Wrap( -1 );
fgSizer4->Add( m_staticTitleModuleSide, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
- m_staticModuleSideValue = new wxStaticText( m_panelGeneral, wxID_ANY, _("Front side"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticModuleSideValue = new wxStaticText( sbSizeModuleInfo->GetStaticBox(), wxID_ANY, _("Front side"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticModuleSideValue->Wrap( -1 );
fgSizer4->Add( m_staticModuleSideValue, 0, wxALL|wxEXPAND, 5 );
@@ -267,41 +256,39 @@
fgSizerGeometry->SetFlexibleDirection( wxBOTH );
fgSizerGeometry->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
- m_staticText47 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Shape:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText47 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Shape:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText47->Wrap( -1 );
fgSizerGeometry->Add( m_staticText47, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
wxString m_DrillShapeCtrlChoices[] = { _("Circular hole"), _("Oval hole") };
int m_DrillShapeCtrlNChoices = sizeof( m_DrillShapeCtrlChoices ) / sizeof( wxString );
- m_DrillShapeCtrl = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DrillShapeCtrlNChoices, m_DrillShapeCtrlChoices, 0 );
+ m_DrillShapeCtrl = new wxChoice( sbSizer2->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DrillShapeCtrlNChoices, m_DrillShapeCtrlChoices, 0 );
m_DrillShapeCtrl->SetSelection( 0 );
fgSizerGeometry->Add( m_DrillShapeCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
- m_staticText51 = new wxStaticText( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText51 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_staticText51->Wrap( -1 );
fgSizerGeometry->Add( m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
- m_textPadDrillX = new wxStaticText( m_panelGeneral, wxID_ANY, _("Size X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPadDrillX = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Size X:"), wxDefaultPosition, wxDefaultSize, 0 );
m_textPadDrillX->Wrap( -1 );
fgSizerGeometry->Add( m_textPadDrillX, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
- m_PadDrill_X_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_PadDrill_X_Ctrl->SetMaxLength( 0 );
+ m_PadDrill_X_Ctrl = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerGeometry->Add( m_PadDrill_X_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
- m_PadDrill_X_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadDrill_X_Unit = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
m_PadDrill_X_Unit->Wrap( -1 );
fgSizerGeometry->Add( m_PadDrill_X_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
- m_textPadDrillY = new wxStaticText( m_panelGeneral, wxID_ANY, _("Size Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPadDrillY = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Size Y:"), wxDefaultPosition, wxDefaultSize, 0 );
m_textPadDrillY->Wrap( -1 );
fgSizerGeometry->Add( m_textPadDrillY, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
- m_PadDrill_Y_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_PadDrill_Y_Ctrl->SetMaxLength( 0 );
+ m_PadDrill_Y_Ctrl = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerGeometry->Add( m_PadDrill_Y_Ctrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
- m_PadDrill_Y_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadDrill_Y_Unit = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
m_PadDrill_Y_Unit->Wrap( -1 );
fgSizerGeometry->Add( m_PadDrill_Y_Unit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
@@ -317,13 +304,13 @@
wxBoxSizer* bSizer11;
bSizer11 = new wxBoxSizer( wxHORIZONTAL );
- m_staticText511 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Copper:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText511 = new wxStaticText( m_LayersSizer->GetStaticBox(), wxID_ANY, _("Copper:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText511->Wrap( -1 );
bSizer11->Add( m_staticText511, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
wxString m_rbCopperLayersSelChoices[] = { _("Front layer"), _("Back layer"), _("All copper layers"), _("None") };
int m_rbCopperLayersSelNChoices = sizeof( m_rbCopperLayersSelChoices ) / sizeof( wxString );
- m_rbCopperLayersSel = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_rbCopperLayersSelNChoices, m_rbCopperLayersSelChoices, 0 );
+ m_rbCopperLayersSel = new wxChoice( m_LayersSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_rbCopperLayersSelNChoices, m_rbCopperLayersSelChoices, 0 );
m_rbCopperLayersSel->SetSelection( 0 );
bSizer11->Add( m_rbCopperLayersSel, 1, wxALL|wxEXPAND, 5 );
@@ -331,39 +318,39 @@
m_LayersSizer->Add( bSizer11, 0, wxEXPAND, 5 );
wxStaticBoxSizer* sbSizerTechlayers;
- sbSizerTechlayers = new wxStaticBoxSizer( new wxStaticBox( m_panelGeneral, wxID_ANY, _("Technical Layers") ), wxVERTICAL );
+ sbSizerTechlayers = new wxStaticBoxSizer( new wxStaticBox( m_LayersSizer->GetStaticBox(), wxID_ANY, _("Technical Layers") ), wxVERTICAL );
- m_PadLayerAdhCmp = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Front adhesive"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerAdhCmp = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Front adhesive"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerAdhCmp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerAdhCu = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Back adhesive"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerAdhCu = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Back adhesive"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerAdhCu, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerPateCmp = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Front solder paste"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerPateCmp = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Front solder paste"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerPateCmp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerPateCu = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Back solder paste"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerPateCu = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Back solder paste"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerPateCu, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerSilkCmp = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Front silk screen"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerSilkCmp = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Front silk screen"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerSilkCmp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerSilkCu = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Back silk screen"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerSilkCu = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Back silk screen"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerSilkCu, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerMaskCmp = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Front solder mask"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerMaskCmp = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Front solder mask"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerMaskCmp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerMaskCu = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Back solder mask"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerMaskCu = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Back solder mask"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerMaskCu, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerDraft = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Drafting notes"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerDraft = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("Drafting notes"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerDraft, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerECO1 = new wxCheckBox( m_panelGeneral, wxID_ANY, _("E.C.O.1"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerECO1 = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("E.C.O.1"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerECO1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
- m_PadLayerECO2 = new wxCheckBox( m_panelGeneral, wxID_ANY, _("E.C.O.2"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLayerECO2 = new wxCheckBox( sbSizerTechlayers->GetStaticBox(), wxID_ANY, _("E.C.O.2"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerTechlayers->Add( m_PadLayerECO2, 0, wxALL, 5 );
@@ -396,59 +383,55 @@
fgClearancesGridSizer->SetFlexibleDirection( wxBOTH );
fgClearancesGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
- m_staticTextNetClearance = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Net pad clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextNetClearance = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Net pad clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextNetClearance->Wrap( -1 );
m_staticTextNetClearance->SetToolTip( _("This is the local net clearance for pad.\nIf 0, the footprint local value or the Netclass value is used") );
fgClearancesGridSizer->Add( m_staticTextNetClearance, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
- m_NetClearanceValueCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_NetClearanceValueCtrl->SetMaxLength( 0 );
+ m_NetClearanceValueCtrl = new wxTextCtrl( sbClearancesSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgClearancesGridSizer->Add( m_NetClearanceValueCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
- m_NetClearanceUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_NetClearanceUnits = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
m_NetClearanceUnits->Wrap( -1 );
fgClearancesGridSizer->Add( m_NetClearanceUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
- m_MaskClearanceTitle = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Solder mask clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskClearanceTitle = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Solder mask clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
m_MaskClearanceTitle->Wrap( -1 );
m_MaskClearanceTitle->SetToolTip( _("This is the local clearance between this pad and the solder mask\nIf 0, the footprint local value or the global value is used") );
fgClearancesGridSizer->Add( m_MaskClearanceTitle, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
- m_SolderMaskMarginCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_SolderMaskMarginCtrl->SetMaxLength( 0 );
+ m_SolderMaskMarginCtrl = new wxTextCtrl( sbClearancesSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgClearancesGridSizer->Add( m_SolderMaskMarginCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
- m_SolderMaskMarginUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginUnits = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
m_SolderMaskMarginUnits->Wrap( -1 );
fgClearancesGridSizer->Add( m_SolderMaskMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
- m_staticTextSolderPaste = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Solder paste clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSolderPaste = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Solder paste clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextSolderPaste->Wrap( -1 );
m_staticTextSolderPaste->SetToolTip( _("This is the local clearance between this pad and the solder paste.\nIf 0 the footprint value or the global value is used..\nThe final clearance value is the sum of this value and the clearance value ratio\nA negative value means a smaller mask size than pad size") );
fgClearancesGridSizer->Add( m_staticTextSolderPaste, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
- m_SolderPasteMarginCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_SolderPasteMarginCtrl->SetMaxLength( 0 );
+ m_SolderPasteMarginCtrl = new wxTextCtrl( sbClearancesSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgClearancesGridSizer->Add( m_SolderPasteMarginCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
- m_SolderPasteMarginUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginUnits = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
m_SolderPasteMarginUnits->Wrap( -1 );
fgClearancesGridSizer->Add( m_SolderPasteMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
- m_staticTextRatio = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Solder paste ratio clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRatio = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("Solder paste ratio clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextRatio->Wrap( -1 );
m_staticTextRatio->SetToolTip( _("This is the local clearance ratio in per cent between this pad and the solder paste.\nA value of 10 means the clearance value is 10 per cent of the pad size\nIf 0 the footprint value or the global value is used..\nThe final clearance value is the sum of this value and the clearance value\nA negative value means a smaller mask size than pad size.") );
fgClearancesGridSizer->Add( m_staticTextRatio, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
- m_SolderPasteMarginRatioCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_SolderPasteMarginRatioCtrl->SetMaxLength( 0 );
+ m_SolderPasteMarginRatioCtrl = new wxTextCtrl( sbClearancesSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgClearancesGridSizer->Add( m_SolderPasteMarginRatioCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
- m_SolderPasteRatioMarginUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteRatioMarginUnits = new wxStaticText( sbClearancesSizer->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_SolderPasteRatioMarginUnits->Wrap( -1 );
fgClearancesGridSizer->Add( m_SolderPasteRatioMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
@@ -467,41 +450,39 @@
fgSizer41->SetFlexibleDirection( wxBOTH );
fgSizer41->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
- m_staticText40 = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Pad connection:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText40 = new wxStaticText( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Pad connection:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText40->Wrap( -1 );
fgSizer41->Add( m_staticText40, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
wxString m_ZoneConnectionChoiceChoices[] = { _("From parent footprint"), _("Solid"), _("Thermal relief"), _("None") };
int m_ZoneConnectionChoiceNChoices = sizeof( m_ZoneConnectionChoiceChoices ) / sizeof( wxString );
- m_ZoneConnectionChoice = new wxChoice( m_localSettingsPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ZoneConnectionChoiceNChoices, m_ZoneConnectionChoiceChoices, 0 );
+ m_ZoneConnectionChoice = new wxChoice( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ZoneConnectionChoiceNChoices, m_ZoneConnectionChoiceChoices, 0 );
m_ZoneConnectionChoice->SetSelection( 0 );
fgSizer41->Add( m_ZoneConnectionChoice, 0, wxLEFT|wxTOP|wxEXPAND, 5 );
- m_staticText53 = new wxStaticText( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText53 = new wxStaticText( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_staticText53->Wrap( -1 );
fgSizer41->Add( m_staticText53, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
- m_staticText49 = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Thermal relief width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText49 = new wxStaticText( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Thermal relief width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText49->Wrap( -1 );
fgSizer41->Add( m_staticText49, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
- m_ThermalWidthCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_ThermalWidthCtrl->SetMaxLength( 0 );
+ m_ThermalWidthCtrl = new wxTextCtrl( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer41->Add( m_ThermalWidthCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
- m_ThermalWidthUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThermalWidthUnits = new wxStaticText( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
m_ThermalWidthUnits->Wrap( -1 );
fgSizer41->Add( m_ThermalWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
- m_staticText52 = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Thermal relief gap:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText52 = new wxStaticText( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Thermal relief gap:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText52->Wrap( -1 );
fgSizer41->Add( m_staticText52, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
- m_ThermalGapCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
- m_ThermalGapCtrl->SetMaxLength( 0 );
+ m_ThermalGapCtrl = new wxTextCtrl( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer41->Add( m_ThermalGapCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
- m_ThermalGapUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThermalGapUnits = new wxStaticText( sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
m_ThermalGapUnits->Wrap( -1 );
fgSizer41->Add( m_ThermalGapUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
=== modified file 'pcbnew/dialogs/dialog_pad_properties_base.fbp'
--- pcbnew/dialogs/dialog_pad_properties_base.fbp 2015-09-11 23:13:54 +0000
+++ pcbnew/dialogs/dialog_pad_properties_base.fbp 2016-01-12 13:19:27 +0000
@@ -912,7 +912,7 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
- <property name="choices">"Circular" "Oval" "Rectangular" "Trapezoidal"</property>
+ <property name="choices">"Circular" "Oval" "Rectangular" "Trapezoidal" "Rounded Rectangle"</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
=== modified file 'pcbnew/dialogs/dialog_pad_properties_base.h'
--- pcbnew/dialogs/dialog_pad_properties_base.h 2015-09-11 23:13:54 +0000
+++ pcbnew/dialogs/dialog_pad_properties_base.h 2016-01-12 13:35:15 +0000
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// C++ code generated with wxFormBuilder (version Jan 1 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
=== modified file 'pcbnew/drc_clearance_test_functions.cpp'
--- pcbnew/drc_clearance_test_functions.cpp 2016-01-09 21:07:52 +0000
+++ pcbnew/drc_clearance_test_functions.cpp 2016-01-20 16:37:18 +0000
@@ -45,41 +45,37 @@
#include <class_marker_pcb.h>
#include <math_for_graphics.h>
#include <polygon_test_point_inside.h>
-
-
-/* compare 2 trapezoids (can be rectangle) and return true if distance > aDist
+#include <convert_basic_shapes_to_polygon.h>
+
+
+/* compare 2 convex polygons and return true if distance > aDist
* i.e if for each edge of the first polygon distance from each edge of the other polygon
* is >= aDist
*/
-bool trapezoid2trapezoidDRC( wxPoint aTref[4], wxPoint aTcompare[4], int aDist )
+bool convex2convexDRC( wxPoint* aTref, int aTrefCount,
+ wxPoint* aTcompare, int aTcompareCount, int aDist )
{
/* Test if one polygon is contained in the other and thus the polygon overlap.
* This case is not covered by the following check if one polygond is
* completely contained in the other (because edges don't intersect)!
*/
- if( TestPointInsidePolygon( aTref, 4, aTcompare[0] ) )
- return false;
-
- if( TestPointInsidePolygon( aTcompare, 4, aTref[0] ) )
- return false;
-
- int ii, jj, kk, ll;
-
- for( ii = 0, jj = 3; ii<4; jj = ii, ii++ ) // for all edges in aTref
- {
- for( kk = 0, ll = 3; kk < 4; ll = kk, kk++ ) // for all edges in aTcompare
- {
+ if( TestPointInsidePolygon( aTref, aTrefCount, aTcompare[0] ) )
+ return false;
+
+ if( TestPointInsidePolygon( aTcompare, aTcompareCount, aTref[0] ) )
+ return false;
+
+ for( int ii = 0, jj = aTrefCount - 1; ii < aTrefCount; jj = ii, ii++ )
+ { // for all edges in aTref
+ for( int kk = 0, ll = aTcompareCount - 1; kk < aTcompareCount; ll = kk, kk++ )
+ { // for all edges in aTcompare
double d;
- int intersect = TestForIntersectionOfStraightLineSegments( aTref[ii].x,
- aTref[ii].y,
- aTref[jj].x,
- aTref[jj].y,
- aTcompare[kk].x,
- aTcompare[kk].y,
- aTcompare[ll].x,
- aTcompare[ll].y,
- NULL, NULL, &d );
- if( intersect || (d< aDist) )
+ int intersect = TestForIntersectionOfStraightLineSegments(
+ aTref[ii].x, aTref[ii].y, aTref[jj].x, aTref[jj].y,
+ aTcompare[kk].x, aTcompare[kk].y, aTcompare[ll].x, aTcompare[ll].y,
+ NULL, NULL, &d );
+
+ if( intersect || ( d< aDist ) )
return false;
}
}
@@ -87,7 +83,6 @@
return true;
}
-
/* compare a trapezoids (can be rectangle) and a segment and return true if distance > aDist
*/
bool trapezoid2segmentDRC( wxPoint aTref[4], wxPoint aSegStart, wxPoint aSegEnd, int aDist )
@@ -99,46 +94,39 @@
if( TestPointInsidePolygon( aTref, 4, aSegStart ) )
return false;
- int ii, jj;
-
- for( ii = 0, jj = 3; ii < 4; jj = ii, ii++ ) // for all edges in aTref
+ for( int ii = 0, jj = 3; ii < 4; jj = ii, ii++ ) // for all edges in aTref
{
double d;
- int intersect = TestForIntersectionOfStraightLineSegments( aTref[ii].x,
- aTref[ii].y,
- aTref[jj].x,
- aTref[jj].y,
- aSegStart.x,
- aSegStart.y,
- aSegEnd.x,
- aSegEnd.y,
- NULL, NULL, &d );
- if( intersect || (d< aDist) )
+ int intersect = TestForIntersectionOfStraightLineSegments(
+ aTref[ii].x, aTref[ii].y, aTref[jj].x, aTref[jj].y,
+ aSegStart.x, aSegStart.y, aSegEnd.x, aSegEnd.y,
+ NULL, NULL, &d );
+
+ if( intersect || ( d < aDist) )
return false;
}
return true;
}
-
-/* compare a trapezoid to a point and return true if distance > aDist
+/* compare a polygon to a point and return true if distance > aDist
* do not use this function for horizontal or vertical rectangles
* because there is a faster an easier way to compare the distance
*/
-bool trapezoid2pointDRC( wxPoint aTref[4], wxPoint aPcompare, int aDist )
+bool convex2pointDRC( wxPoint* aTref, int aTrefCount, wxPoint aPcompare, int aDist )
{
/* Test if aPcompare point is contained in the polygon.
* This case is not covered by the following check if this point is inside the polygon
*/
- if( TestPointInsidePolygon( aTref, 4, aPcompare ) )
+ if( TestPointInsidePolygon( aTref, aTrefCount, aPcompare ) )
{
return false;
}
// Test distance between aPcompare and each segment of the polygon:
- for( int ii = 0, jj = 3; ii < 4; jj = ii, ii++ ) // for all edge in polygon
+ for( int ii = 0, jj = aTrefCount - 1; ii < aTrefCount; jj = ii, ii++ ) // for all edge in polygon
{
- if( TestSegmentHit( aTref[ii], aTref[jj], aPcompare, aDist ) )
+ if( TestSegmentHit( aPcompare, aTref[ii], aTref[jj], aDist ) )
return false;
}
@@ -577,12 +565,13 @@
/* test DRC between 2 pads.
- * this function can be also used to test DRC between a pas and a hole,
- * because a hole is like a round pad.
+ * this function can be also used to test DRC between a pad and a hole,
+ * because a hole is like a round or oval pad.
*/
bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
{
int dist;
+ double pad_angle;
// Get the clearance between the 2 pads. this is the min distance between aRefPad and aPad
int dist_min = aRefPad->GetClearance( aPad );
@@ -607,10 +596,12 @@
swap_pads = false;
// swap pads to make comparisons easier
- // priority is aRefPad = ROUND then OVAL then RECT then other
+ // Note also a ROUNDRECT pad with a corner radius = r can be considered as
+ // a smaller RECT (size - 2*r) with a clearance increased by r
+ // 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 or trapezoid
+ // pad ref shape is here oval, rect, roundrect or trapezoid
switch( aPad->GetShape() )
{
case PAD_SHAPE_CIRCLE:
@@ -622,6 +613,7 @@
break;
case PAD_SHAPE_RECT:
+ case PAD_SHAPE_ROUNDRECT:
if( aRefPad->GetShape() != PAD_SHAPE_OVAL )
swap_pads = true;
break;
@@ -637,10 +629,15 @@
relativePadPos = -relativePadPos;
}
+ // corners of aRefPad (used only for rect/roundrect/trap pad)
+ wxPoint polyref[4];
+ // corners of aPad (used only for rect/roundrect/trap pad)
+ wxPoint polycompare[4];
+
/* Because pad exchange, aRefPad shape is PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL,
* if one of the 2 pads was a PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL.
- * Therefore, if aRefPad is a PAD_SHAPE_SHAPE_RECT or a PAD_SHAPE_TRAPEZOID,
- * aPad is also a PAD_SHAPE_RECT or a PAD_SHAPE_TRAPEZOID
+ * Therefore, if aRefPad is a PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT or a PAD_SHAPE_TRAPEZOID,
+ * aPad is also a PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT or a PAD_SHAPE_TRAPEZOID
*/
bool diag = true;
@@ -660,6 +657,55 @@
diag = checkClearanceSegmToPad( aPad, aRefPad->GetSize().x, dist_min );
break;
+ case PAD_SHAPE_TRAPEZOID:
+ case PAD_SHAPE_ROUNDRECT:
+ case PAD_SHAPE_RECT:
+ // pad_angle = pad orient relative to the aRefPad orient
+ pad_angle = aRefPad->GetOrientation() + aPad->GetOrientation();
+ NORMALIZE_ANGLE_POS( pad_angle );
+
+ if( aRefPad->GetShape() == PAD_SHAPE_ROUNDRECT )
+ {
+ int padRadius = aRefPad->GetRoundRectCornerRadius();
+ dist_min += padRadius;
+ GetRoundRectCornerCenters( polyref, padRadius, wxPoint( 0, 0 ),
+ aRefPad->GetSize(), aRefPad->GetOrientation() );
+ }
+ else
+ aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
+
+ switch( aPad->GetShape() )
+ {
+ case PAD_SHAPE_ROUNDRECT:
+ case PAD_SHAPE_RECT:
+ case PAD_SHAPE_TRAPEZOID:
+ if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
+ {
+ int padRadius = aPad->GetRoundRectCornerRadius();
+ dist_min += padRadius;
+ GetRoundRectCornerCenters( polycompare, padRadius, wxPoint( 0, 0 ),
+ aPad->GetSize(), aPad->GetOrientation() );
+ }
+ else
+ {
+ aPad->BuildPadPolygon( polycompare, wxSize( 0, 0 ), aPad->GetOrientation() );
+
+ // Move aPad shape to relativePadPos
+ for( int ii = 0; ii < 4; ii++ )
+ polycompare[ii] += relativePadPos;
+
+ // And now test polygons:
+ if( !convex2convexDRC( polyref, 4, polycompare, 4, dist_min ) )
+ diag = false;
+ }
+ break;
+
+ default:
+ wxLogDebug( wxT( "DRC::checkClearancePadToPad: unexpected pad shape %d" ), aPad->GetShape() );
+ break;
+ }
+ break;
+
case PAD_SHAPE_OVAL: /* an oval pad is like a track segment */
{
/* Create a track segment with same dimensions as the oval aRefPad
@@ -702,26 +748,8 @@
break;
}
- case PAD_SHAPE_TRAPEZOID:
- case PAD_SHAPE_RECT:
- {
- wxPoint polyref[4]; // Shape of aRefPad
- wxPoint polycompare[4]; // Shape of aPad
- aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
- aPad->BuildPadPolygon( polycompare, wxSize( 0, 0 ), aPad->GetOrientation() );
-
- // Move aPad shape to relativePadPos
- for( int ii = 0; ii < 4; ii++ )
- polycompare[ii] += relativePadPos;
-
- // And now test polygons:
- if( !trapezoid2trapezoidDRC( polyref, polycompare, dist_min ) )
- diag = false;
- }
- break;
-
default:
- wxLogDebug( wxT( "DRC::checkClearancePadToPad: unexpected pad shape" ) );
+ wxLogDebug( wxT( "DRC::checkClearancePadToPad: unknown pad shape" ) );
break;
}
@@ -738,6 +766,7 @@
{
wxSize padHalfsize; // half dimension of the pad
wxPoint startPoint, endPoint;
+ int r;
int segmHalfWidth = aSegmentWidth / 2;
int distToLine = segmHalfWidth + aMinDist;
@@ -849,6 +878,13 @@
}
break;
+ case PAD_SHAPE_ROUNDRECT:
+ // a round rect is a smaller rect, with a clearance augmented by the corners radius
+ r = aPad->GetRoundRectCornerRadius();
+ padHalfsize.x -= r;
+ padHalfsize.y -= r;
+ distToLine += r;
+ // Fall through
case PAD_SHAPE_RECT:
// the area to test is a rounded rectangle.
// this can be done by testing 2 rectangles and 4 circles (the corners)
=== modified file 'pcbnew/exporters/gen_modules_placefile.cpp'
--- pcbnew/exporters/gen_modules_placefile.cpp 2015-11-17 16:18:00 +0000
+++ pcbnew/exporters/gen_modules_placefile.cpp 2016-01-12 13:19:27 +0000
@@ -723,7 +723,7 @@
(pad->GetOrientation() - Module->GetOrientation()) / 10.0 );
fputs( line, rptfile );
- static const char* shape_name[6] = { "???", "Circ", "Rect", "Oval", "Trap", "Spec" };
+ static const char* shape_name[6] = { "Circ", "Rect", "Oval", "Trap", "Rrec", "Spec" };
sprintf( line, "Shape %s\n", shape_name[pad->GetShape()] );
fputs( line, rptfile );
=== modified file 'pcbnew/kicad_plugin.cpp'
--- pcbnew/kicad_plugin.cpp 2016-01-17 17:31:00 +0000
+++ pcbnew/kicad_plugin.cpp 2016-01-18 08:31:58 +0000
@@ -1229,6 +1229,7 @@
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;
default:
THROW_IO_ERROR( wxString::Format( _( "unknown pad type: %d"), aPad->GetShape() ) );
=== modified file 'pcbnew/pcb_painter.cpp'
--- pcbnew/pcb_painter.cpp 2016-01-20 14:19:26 +0000
+++ pcbnew/pcb_painter.cpp 2016-01-20 17:12:09 +0000
@@ -38,6 +38,7 @@
#include <pcb_painter.h>
#include <gal/graphics_abstraction_layer.h>
+#include <convert_basic_shapes_to_polygon.h>
using namespace KIGFX;
@@ -653,6 +654,37 @@
m_gal->DrawRectangle( VECTOR2D( -size.x, -size.y ), VECTOR2D( size.x, size.y ) );
break;
+ case PAD_SHAPE_ROUNDRECT:
+ {
+ std::deque<VECTOR2D> pointList;
+
+ // Use solder[Paste/Mask]size or pad size to build pad shape
+ SHAPE_POLY_SET outline;
+ wxSize prsize( size.x*2, size.y*2 );
+ const int segmentToCircleCount = 64;
+ int corner_radius = aPad->GetRoundRectCornerRadius( prsize );
+ TransformRoundRectToPolygon( outline, wxPoint( 0, 0 ), prsize,
+ 0.0 , corner_radius, segmentToCircleCount );
+
+ // Draw the polygon: Inflate creates only one convex polygon
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+
+ for( int ii = 0; ii < poly.PointCount(); ii++ )
+ pointList.push_back( poly.Point( ii ) );
+
+ if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] )
+ {
+ // Add the beginning point to close the outline
+ pointList.push_back( pointList.front() );
+ m_gal->DrawPolyline( pointList );
+ }
+ else
+ {
+ m_gal->DrawPolygon( pointList );
+ }
+ break;
+ }
+
case PAD_SHAPE_TRAPEZOID:
{
std::deque<VECTOR2D> pointList;
=== modified file 'pcbnew/pcb_parser.cpp'
--- pcbnew/pcb_parser.cpp 2015-11-17 16:18:00 +0000
+++ pcbnew/pcb_parser.cpp 2016-01-12 13:19:27 +0000
@@ -2197,8 +2197,12 @@
pad->SetShape( PAD_SHAPE_TRAPEZOID );
break;
+ case T_roundrect:
+ pad->SetShape( PAD_SHAPE_ROUNDRECT );
+ break;
+
default:
- Expecting( "circle, rectangle, oval, or trapezoid" );
+ Expecting( "circle, rectangle, roundrect, oval, or trapezoid" );
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
=== modified file 'pcbnew/plot_board_layers.cpp'
--- pcbnew/plot_board_layers.cpp 2015-12-15 20:21:25 +0000
+++ pcbnew/plot_board_layers.cpp 2016-01-12 13:19:27 +0000
@@ -380,6 +380,7 @@
// Fall through:
case PAD_SHAPE_TRAPEZOID:
case PAD_SHAPE_RECT:
+ case PAD_SHAPE_ROUNDRECT:
default:
itemplotter.PlotPad( pad, color, plotMode );
break;
=== modified file 'pcbnew/plot_brditems_plotter.cpp'
--- pcbnew/plot_brditems_plotter.cpp 2015-08-23 19:40:33 +0000
+++ pcbnew/plot_brditems_plotter.cpp 2016-01-14 16:01:51 +0000
@@ -91,6 +91,11 @@
}
break;
+ case PAD_SHAPE_ROUNDRECT:
+ m_plotter->FlashPadRoundRect( shape_pos, aPad->GetSize(), aPad->GetRoundRectCornerRadius(),
+ aPad->GetOrientation(), aPlotMode );
+ break;
+
case PAD_SHAPE_RECT:
default:
m_plotter->FlashPadRect( shape_pos, aPad->GetSize(),
=== modified file 'pcbnew/router/pns_router.cpp'
--- pcbnew/router/pns_router.cpp 2015-11-18 14:35:17 +0000
+++ pcbnew/router/pns_router.cpp 2016-01-20 17:45:38 +0000
@@ -267,6 +267,31 @@
break;
}
+ case PAD_SHAPE_ROUNDRECT:
+ {
+ SHAPE_POLY_SET outline;
+ const int segmentToCircleCount = 64;
+ // FIXME: Perhaps not optimal because we are using a polygonal
+ // shape with segmentToCircleCount+4 corners,
+ // but perhaps using 2 rect and 4 circles could be better
+ // (better shape, although for more than 32 segm per circle
+ // the shape is good) and faster
+ aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ),
+ segmentToCircleCount, 1.0 );
+
+ // TransformRoundRectToPolygon creates only one convex polygon
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+ SHAPE_CONVEX* shape = new SHAPE_CONVEX();
+
+ for( int ii = 0; ii < poly.PointCount(); ++ii )
+ {
+ shape->Append( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
+ }
+
+ solid->SetShape( shape );
+ }
+ break;
+
default:
TRACEn( 0, "unsupported pad shape" );
delete solid;
@@ -344,6 +369,26 @@
break;
}
+ case PAD_SHAPE_ROUNDRECT:
+ {
+ SHAPE_POLY_SET outline;
+ const int segmentToCircleCount = 32;
+ aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ),
+ segmentToCircleCount, 1.0 );
+
+ // TransformRoundRectToPolygon creates only one convex polygon
+ SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
+ SHAPE_CONVEX* shape = new SHAPE_CONVEX();
+
+ for( int ii = 0; ii < poly.PointCount(); ++ii )
+ {
+ shape->Append( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
+ }
+
+ solid->SetShape( shape );
+ }
+ break;
+
default:
TRACEn( 0, "unsupported pad shape" );
delete solid;
References
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Chris Pavlina, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: jp charras, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Chris Pavlina, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Chris Pavlina, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: jp charras, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Chris Pavlina, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Bernhard Stegmaier, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Chris Pavlina, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Bernhard Stegmaier, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Bernhard Stegmaier, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Chris Pavlina, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Bernhard Stegmaier, 2016-01-19
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Jean-Paul Louis, 2016-01-20
-
Re: [PATCH] Fix typing problems with GR_KB_* constants
From: Andy Peters, 2016-01-20
-
[PATCH] new feature: adding rounded rect pads
From: jp charras, 2016-01-20
-
Re: [PATCH] new feature: adding rounded rect pads
From: Clemens Koller, 2016-01-20