Add a mode to allow zone smoothing to produce external fillets.

Fixes https://gitlab.com/kicad/code/kicad/issues/5306
This commit is contained in:
Jeff Young 2020-08-30 15:18:35 +01:00
parent 5be39c6299
commit 305abb210f
11 changed files with 418 additions and 82 deletions

View File

@ -499,6 +499,7 @@ set( BMAPS_MID
wizard_add_fplib_small wizard_add_fplib_small
zip zip
zone_duplicate zone_duplicate
zone_fillet
zone_unfill zone_unfill
zoom zoom
zoom_area zoom_area

View File

@ -0,0 +1,46 @@
/* Do not modify this file, it was automatically generated by the
* PNG2cpp CMake script, using a *.png file as input.
*/
#include <bitmaps_png/bitmaps_list.h>
static const unsigned char png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c,
0xce, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, 0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64,
0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0e,
0xc4, 0x01, 0x95, 0x2b, 0x0e, 0x1b, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f,
0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63,
0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x00, 0x00, 0x01, 0x8a, 0x49,
0x44, 0x41, 0x54, 0x48, 0x89, 0xed, 0xd6, 0xbf, 0x6b, 0x53, 0x51, 0x18, 0xc6, 0xf1, 0xcf, 0xbd,
0xb9, 0x89, 0x35, 0x31, 0xad, 0x9a, 0xc1, 0xcc, 0x62, 0x70, 0xd0, 0x4d, 0xc1, 0xc9, 0xb1, 0x83,
0xae, 0x19, 0x1d, 0x04, 0x41, 0x17, 0xad, 0x1d, 0x04, 0x17, 0x17, 0x07, 0x17, 0xff, 0x89, 0xa2,
0x88, 0x83, 0x93, 0xe0, 0xa6, 0x0e, 0x2a, 0x0a, 0xa2, 0xe0, 0x24, 0x08, 0x45, 0xe9, 0xe0, 0x62,
0x4a, 0x29, 0xda, 0x56, 0x9a, 0x34, 0xbd, 0x3f, 0x1c, 0x5c, 0x2a, 0xdc, 0xd4, 0xb4, 0xf6, 0x6c,
0x3e, 0xd3, 0x81, 0xe7, 0xbc, 0x7c, 0x0f, 0xe7, 0x3d, 0xbc, 0xcf, 0x89, 0xdc, 0x76, 0x47, 0x99,
0xbe, 0xba, 0x81, 0xc2, 0x9c, 0x7a, 0xa9, 0xbf, 0x43, 0xc5, 0x23, 0x9d, 0x5c, 0x21, 0xda, 0xc6,
0xdf, 0x33, 0x10, 0xa9, 0x58, 0x12, 0x1e, 0x94, 0xda, 0x10, 0xa9, 0xb8, 0xa2, 0x1a, 0x16, 0x34,
0xb4, 0x06, 0xea, 0x4e, 0x87, 0x05, 0xf5, 0x2d, 0x83, 0xc2, 0xf9, 0xb0, 0xa0, 0x75, 0x3f, 0x14,
0x0a, 0x59, 0x68, 0x10, 0x85, 0x4c, 0x5f, 0xea, 0x24, 0xa2, 0x90, 0x20, 0x7e, 0x5a, 0x94, 0xab,
0x99, 0x71, 0x31, 0x2c, 0xe8, 0xbb, 0x05, 0xb1, 0x5c, 0xee, 0x56, 0x58, 0x50, 0x2e, 0xb7, 0xdf,
0x82, 0x4d, 0xc7, 0xcc, 0xea, 0x86, 0x03, 0x41, 0xd3, 0x63, 0xb1, 0xcc, 0xd0, 0x9c, 0x73, 0xf6,
0x85, 0x03, 0xc5, 0x86, 0x9a, 0x5e, 0xc8, 0x4c, 0x3a, 0xea, 0x83, 0x5d, 0x3e, 0x8c, 0xf1, 0x66,
0x59, 0xc3, 0x3b, 0x0d, 0x1f, 0x6d, 0x3a, 0xe1, 0x9a, 0xb7, 0xbb, 0x99, 0x16, 0xe3, 0x0f, 0xcd,
0x29, 0x4f, 0xd4, 0x7d, 0x31, 0x74, 0x46, 0xd5, 0x37, 0xb3, 0x8e, 0x87, 0x01, 0xc1, 0x41, 0x8f,
0x4c, 0x7a, 0x25, 0x75, 0xd8, 0xc0, 0x27, 0xd7, 0xdd, 0x35, 0xe6, 0x55, 0xee, 0x3c, 0x06, 0x0e,
0x78, 0xa3, 0xe5, 0xbe, 0xaa, 0xbe, 0x81, 0x9b, 0xae, 0x5a, 0x34, 0xe3, 0xd2, 0xdf, 0xca, 0xa2,
0xd2, 0xe0, 0x7b, 0x68, 0x5a, 0x4f, 0x07, 0xb4, 0x7d, 0x76, 0xc1, 0xf3, 0xd2, 0xea, 0x55, 0xd3,
0xfa, 0x4e, 0xc9, 0x54, 0x54, 0xac, 0xa9, 0x7a, 0x86, 0x07, 0x56, 0x3d, 0x75, 0xcf, 0x60, 0xeb,
0xd6, 0xf2, 0xbc, 0x59, 0xd6, 0xb6, 0xae, 0xa9, 0x10, 0xeb, 0xe9, 0x78, 0x6d, 0x65, 0xc4, 0x41,
0x57, 0xc4, 0x5e, 0x6a, 0xe9, 0x68, 0x68, 0xcb, 0x74, 0xd1, 0x55, 0xc3, 0x65, 0x99, 0x5c, 0x8a,
0x42, 0x62, 0x63, 0x74, 0xb0, 0x45, 0xf2, 0x91, 0xde, 0x56, 0xe5, 0x72, 0x4b, 0xe6, 0x2d, 0x99,
0x97, 0x98, 0x30, 0xe5, 0x88, 0x9a, 0x43, 0x12, 0x13, 0x22, 0x89, 0xdf, 0x3d, 0x4c, 0xca, 0x41,
0x2d, 0xbd, 0x3f, 0xd6, 0x67, 0xbd, 0x1f, 0x0b, 0xba, 0x8d, 0xca, 0x41, 0xa3, 0x7a, 0xf2, 0x0f,
0xda, 0xb3, 0xcf, 0xc7, 0x7f, 0x50, 0x30, 0xfd, 0x02, 0x4e, 0x6a, 0x68, 0x68, 0x4d, 0x05, 0xab,
0xba, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE zone_fillet_xpm[1] = {{ png, sizeof( png ), "zone_fillet_xpm" }};
//EOF

View File

@ -486,6 +486,7 @@ EXTERN_BITMAP( wizard_add_fplib_small_xpm )
EXTERN_BITMAP( www_xpm ) EXTERN_BITMAP( www_xpm )
EXTERN_BITMAP( zip_xpm ) EXTERN_BITMAP( zip_xpm )
EXTERN_BITMAP( zone_duplicate_xpm ) EXTERN_BITMAP( zone_duplicate_xpm )
EXTERN_BITMAP( zone_fillet_xpm )
EXTERN_BITMAP( zone_unfill_xpm ) EXTERN_BITMAP( zone_unfill_xpm )
EXTERN_BITMAP( zoom_area_xpm ) EXTERN_BITMAP( zoom_area_xpm )
EXTERN_BITMAP( zoom_auto_fit_in_page_xpm ) EXTERN_BITMAP( zoom_auto_fit_in_page_xpm )

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="26"
width="26"
version="1.1"
id="svg2"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="zone_fillet.svg"
inkscape:export-filename="/Users/jeff/kicad_dev/kicad/bitmaps_png/png_26/zone_fillet.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<metadata
id="metadata40">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1345"
inkscape:window-height="840"
id="namedview38"
showgrid="true"
inkscape:snap-to-guides="false"
inkscape:snap-grids="true"
inkscape:zoom="22.961538"
inkscape:cx="11.214405"
inkscape:cy="13"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="0"
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid3017"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="0.5"
spacingy="0.5"
originx="0"
originy="0" />
</sodipodi:namedview>
<defs
id="defs4" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7,-1 V 19 H 25"
id="path49"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:#008000;fill-opacity:0.51764709;stroke:#008000;stroke-width:1.29999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 7,-1 c 0,2.5 0,10.5 5,15 6,5 9.5,5 15,5 v 8 H -1 V -1 Z"
id="rect3811"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<g
transform="matrix(1.6382539,0,0,1.5572263,1.2572207,0.36314149)"
id="g16">
<rect
height="16"
width="16"
y="0"
x="0"
id="rect18"
style="fill-opacity:0" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 7,0 v 19 h 11.5 7"
id="path856"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 6,18 v 2 h 2 v -2 z"
id="path858"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path948"
d="m 7,-1 c 0,2.5 0,10.5 5,15 6,5 9.5,5 15,5 v 8 H -1 V -1 Z"
style="fill:none;fill-opacity:0.51764709;stroke:#006600;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -239,25 +239,28 @@ public:
std::map< int, int > m_DRCSeverities; // Map from DRCErrorCode to SEVERITY std::map< int, int > m_DRCSeverities; // Map from DRCErrorCode to SEVERITY
std::set<wxString> m_DrcExclusions; std::set<wxString> m_DrcExclusions;
/** Option to handle filled polygons in zones: // Option to handle filled polygons in zones:
* the "legacy" option is using thick outlines around filled polygons: give the best shape // the "legacy" option is using thick outlines around filled polygons: give the best shape
* the "new" option is using only filled polygons (no outline: give the faster redraw time // the "new" option is using only filled polygons (no outline: give the faster redraw time
* moreover when exporting zone filled areas, the excatct shape is exported. // moreover when exporting zone filled areas, the excatct shape is exported.
* the legacy option can really create redraw time issues for large boards. // the legacy option can really create redraw time issues for large boards.
*/ bool m_ZoneUseNoOutlineInFill;
bool m_ZoneUseNoOutlineInFill; ///< true for new zone filling option
// When smoothing the zone's outline there's the question of external fillets (that is, those
// applied to concave corners). While it seems safer to never have copper extend outside the
// zone outline, 5.1.x and prior did indeed fill them so we leave the mode available.
bool m_ZoneKeepExternalFillets;
// Maximum error allowed when approximating circles and arcs to segments // Maximum error allowed when approximating circles and arcs to segments
int m_MaxError; int m_MaxError;
// Global mask margins: // Global mask margins:
int m_SolderMaskMargin; ///< Solder mask margin int m_SolderMaskMargin; // Solder mask margin
int m_SolderMaskMinWidth; ///< Solder mask min width int m_SolderMaskMinWidth; // Solder mask min width (2 areas closer than this
// 2 areas near than m_SolderMaskMinWidth // width are merged)
// are merged int m_SolderPasteMargin; // Solder paste margin absolute value
int m_SolderPasteMargin; ///< Solder paste margin absolute value double m_SolderPasteMarginRatio; // Solder pask margin ratio value of pad size
double m_SolderPasteMarginRatio; ///< Solder pask margin ratio value of pad size // The final margin is the sum of these 2 values
///< The final margin is the sum of these 2 values
// Variables used in footprint editing (default value in item/footprint creation) // Variables used in footprint editing (default value in item/footprint creation)
std::vector<TEXT_ITEM_INFO> m_DefaultFPTextItems; std::vector<TEXT_ITEM_INFO> m_DefaultFPTextItems;
@ -276,16 +279,12 @@ public:
wxPoint m_AuxOrigin; ///< origin for plot exports wxPoint m_AuxOrigin; ///< origin for plot exports
wxPoint m_GridOrigin; ///< origin for grid offsets wxPoint m_GridOrigin; ///< origin for grid offsets
D_PAD m_Pad_Master; ///< A dummy pad to store all default parameters D_PAD m_Pad_Master; // A dummy pad to store all default parameters
// when importing values or create a new pad // when importing values or creating a new pad
/** Set to true if the board has a stackup management. // Set to true if the board has a stackup management.
* if m_hasStackup is false, a default basic stackup witll be used to // If not set a default basic stackup witll be used to generate the ;gbrjob file.
* generate the ;gbrjob file. // Could be removed later, or at least always set to true
* if m_hasStackup is true, the stackup defined for the board is used.
* if not up to date, a error message will be set
* Could be removed later, or at least always set to true
*/
bool m_HasStackup; bool m_HasStackup;
private: private:

View File

@ -23,14 +23,13 @@
#include <fctsys.h> #include <fctsys.h>
#include <common.h> #include <common.h>
#include <class_board.h>
#include <class_track.h> #include <class_track.h>
#include <layers_id_colors_and_visibility.h> #include <layers_id_colors_and_visibility.h>
#include <kiface_i.h> #include <kiface_i.h>
#include <pcbnew.h> //#include <pcbnew.h>
#include <board_design_settings.h> #include <board_design_settings.h>
#include <drc/drc.h> #include <drc/drc.h>
#include <widgets/ui_common.h> //#include <widgets/ui_common.h>
#include <drc/drc_rule.h> #include <drc/drc_rule.h>
#include <settings/parameters.h> #include <settings/parameters.h>
#include <project/project_file.h> #include <project/project_file.h>
@ -157,7 +156,9 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
m_DRCSeverities[ DRCE_EXTRA_FOOTPRINT ] = RPT_SEVERITY_WARNING; m_DRCSeverities[ DRCE_EXTRA_FOOTPRINT ] = RPT_SEVERITY_WARNING;
m_MaxError = ARC_HIGH_DEF; m_MaxError = ARC_HIGH_DEF;
m_ZoneUseNoOutlineInFill = true; // Use new algo by default ti fill zones m_ZoneUseNoOutlineInFill = true; // Use new algo by default to fill zones
m_ZoneKeepExternalFillets = false; // Use new algo by default. Legacy boards might
// want to set it to true for old algo....
// Global mask margins: // Global mask margins:
m_SolderMaskMargin = Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE ); m_SolderMaskMargin = Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE );
@ -183,8 +184,8 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
m_params.emplace_back( new PARAM<bool>( "rules.allow_microvias", &m_MicroViasAllowed, false ) ); m_params.emplace_back( new PARAM<bool>( "rules.allow_microvias", &m_MicroViasAllowed, false ) );
m_params.emplace_back( m_params.emplace_back( new PARAM<bool>( "rules.allow_blind_buried_vias",
new PARAM<bool>( "rules.allow_blind_buried_vias", &m_BlindBuriedViaAllowed, false ) ); &m_BlindBuriedViaAllowed, false ) );
m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_clearance", &m_MinClearance, m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_clearance", &m_MinClearance,
Millimeter2iu( DEFAULT_MINCLEARANCE ), Millimeter2iu( 0.01 ), Millimeter2iu( 25.0 ), Millimeter2iu( DEFAULT_MINCLEARANCE ), Millimeter2iu( 0.01 ), Millimeter2iu( 25.0 ),
@ -428,11 +429,11 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
&m_TextThickness[LAYER_CLASS_SILK], Millimeter2iu( DEFAULT_SILK_TEXT_WIDTH ), 1, &m_TextThickness[LAYER_CLASS_SILK], Millimeter2iu( DEFAULT_SILK_TEXT_WIDTH ), 1,
TEXTS_MAX_WIDTH, MM_PER_IU ) ); TEXTS_MAX_WIDTH, MM_PER_IU ) );
m_params.emplace_back( new PARAM<bool>( m_params.emplace_back( new PARAM<bool>( "defaults.silk_text_italic",
"defaults.silk_text_italic", &m_TextItalic[LAYER_CLASS_SILK], false ) ); &m_TextItalic[LAYER_CLASS_SILK], false ) );
m_params.emplace_back( new PARAM<bool>( m_params.emplace_back( new PARAM<bool>( "defaults.silk_text_upright",
"defaults.silk_text_upright", &m_TextUpright[ LAYER_CLASS_SILK ], true ) ); &m_TextUpright[ LAYER_CLASS_SILK ], true ) );
m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_line_width", m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_line_width",
&m_LineThickness[LAYER_CLASS_COPPER], Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ), &m_LineThickness[LAYER_CLASS_COPPER], Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ),
@ -450,11 +451,11 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
&m_TextThickness[LAYER_CLASS_COPPER], Millimeter2iu( DEFAULT_COPPER_TEXT_WIDTH ), &m_TextThickness[LAYER_CLASS_COPPER], Millimeter2iu( DEFAULT_COPPER_TEXT_WIDTH ),
Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) ); Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
m_params.emplace_back( new PARAM<bool>( m_params.emplace_back( new PARAM<bool>( "defaults.copper_text_italic",
"defaults.copper_text_italic", &m_TextItalic[LAYER_CLASS_COPPER], false ) ); &m_TextItalic[LAYER_CLASS_COPPER], false ) );
m_params.emplace_back( new PARAM<bool>( m_params.emplace_back( new PARAM<bool>( "defaults.copper_text_upright",
"defaults.copper_text_upright", &m_TextUpright[LAYER_CLASS_COPPER], true ) ); &m_TextUpright[LAYER_CLASS_COPPER], true ) );
m_params.emplace_back( new PARAM_SCALED<int>( "defaults.board_outline_line_width", m_params.emplace_back( new PARAM_SCALED<int>( "defaults.board_outline_line_width",
&m_LineThickness[LAYER_CLASS_EDGES], Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ), &m_LineThickness[LAYER_CLASS_EDGES], Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ),
@ -480,11 +481,11 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
&m_TextThickness[LAYER_CLASS_FAB], Millimeter2iu( DEFAULT_TEXT_WIDTH ), &m_TextThickness[LAYER_CLASS_FAB], Millimeter2iu( DEFAULT_TEXT_WIDTH ),
Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) ); Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
m_params.emplace_back( m_params.emplace_back( new PARAM<bool>( "defaults.fab_text_italic",
new PARAM<bool>( "defaults.fab_text_italic", &m_TextItalic[LAYER_CLASS_FAB], false ) ); &m_TextItalic[LAYER_CLASS_FAB], false ) );
m_params.emplace_back( m_params.emplace_back( new PARAM<bool>( "defaults.fab_text_upright",
new PARAM<bool>( "defaults.fab_text_upright", &m_TextUpright[LAYER_CLASS_FAB], true ) ); &m_TextUpright[LAYER_CLASS_FAB], true ) );
m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_line_width", m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_line_width",
&m_LineThickness[LAYER_CLASS_OTHERS], Millimeter2iu( DEFAULT_LINE_WIDTH ), &m_LineThickness[LAYER_CLASS_OTHERS], Millimeter2iu( DEFAULT_LINE_WIDTH ),
@ -502,20 +503,20 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
&m_TextThickness[LAYER_CLASS_OTHERS], Millimeter2iu( DEFAULT_TEXT_WIDTH ), &m_TextThickness[LAYER_CLASS_OTHERS], Millimeter2iu( DEFAULT_TEXT_WIDTH ),
Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) ); Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
m_params.emplace_back( new PARAM<bool>( m_params.emplace_back( new PARAM<bool>( "defaults.other_text_italic",
"defaults.other_text_italic", &m_TextItalic[LAYER_CLASS_OTHERS], false ) ); &m_TextItalic[LAYER_CLASS_OTHERS], false ) );
m_params.emplace_back( new PARAM<bool>( m_params.emplace_back( new PARAM<bool>( "defaults.other_text_upright",
"defaults.other_text_upright", &m_TextUpright[LAYER_CLASS_OTHERS], true ) ); &m_TextUpright[LAYER_CLASS_OTHERS], true ) );
m_params.emplace_back( m_params.emplace_back( new PARAM<int>( "defaults.dimension_units",
new PARAM<int>( "defaults.dimension_units", &m_DimensionUnits, 0, 0, 2 ) ); &m_DimensionUnits, 0, 0, 2 ) );
m_params.emplace_back( m_params.emplace_back( new PARAM<int>( "defaults.dimension_precision",
new PARAM<int>( "defaults.dimension_precision", &m_DimensionPrecision, 1, 0, 2 ) ); &m_DimensionPrecision, 1, 0, 2 ) );
m_params.emplace_back( new PARAM<bool>( m_params.emplace_back( new PARAM<bool>( "defaults.zones.45_degree_only",
"defaults.zones.45_degree_only", &m_defaultZoneSettings.m_Zone_45_Only, false ) ); &m_defaultZoneSettings.m_Zone_45_Only, false ) );
m_params.emplace_back( new PARAM_SCALED<int>( "defaults.zones.min_clearance", m_params.emplace_back( new PARAM_SCALED<int>( "defaults.zones.min_clearance",
&m_defaultZoneSettings.m_ZoneClearance, Mils2iu( ZONE_CLEARANCE_MIL ), &m_defaultZoneSettings.m_ZoneClearance, Mils2iu( ZONE_CLEARANCE_MIL ),
@ -553,8 +554,11 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
m_params.emplace_back( new PARAM_SCALED<int>( "rules.max_error", &m_MaxError, ARC_HIGH_DEF, m_params.emplace_back( new PARAM_SCALED<int>( "rules.max_error", &m_MaxError, ARC_HIGH_DEF,
Millimeter2iu( 0.0001 ), Millimeter2iu( 1.0 ), MM_PER_IU ) ); Millimeter2iu( 0.0001 ), Millimeter2iu( 1.0 ), MM_PER_IU ) );
m_params.emplace_back( m_params.emplace_back( new PARAM<bool>( "zones_use_no_outline",
new PARAM<bool>( "zones_use_no_outline", &m_ZoneUseNoOutlineInFill, true ) ); &m_ZoneUseNoOutlineInFill, true ) );
m_params.emplace_back( new PARAM<bool>( "zones_allow_external_fillets",
&m_ZoneKeepExternalFillets, false ) );
} }
@ -607,6 +611,7 @@ void BOARD_DESIGN_SETTINGS::initFromOther( const BOARD_DESIGN_SETTINGS& aOther )
m_DRCSeverities = aOther.m_DRCSeverities; m_DRCSeverities = aOther.m_DRCSeverities;
m_DrcExclusions = aOther.m_DrcExclusions; m_DrcExclusions = aOther.m_DrcExclusions;
m_ZoneUseNoOutlineInFill = aOther.m_ZoneUseNoOutlineInFill; m_ZoneUseNoOutlineInFill = aOther.m_ZoneUseNoOutlineInFill;
m_ZoneKeepExternalFillets= aOther.m_ZoneKeepExternalFillets;
m_MaxError = aOther.m_MaxError; m_MaxError = aOther.m_MaxError;
m_SolderMaskMargin = aOther.m_SolderMaskMargin; m_SolderMaskMargin = aOther.m_SolderMaskMargin;
m_SolderMaskMinWidth = aOther.m_SolderMaskMinWidth; m_SolderMaskMinWidth = aOther.m_SolderMaskMinWidth;
@ -709,7 +714,13 @@ bool BOARD_DESIGN_SETTINGS::LoadFromFile( const wxString& aDirectory )
} }
if( project->contains( "legacy" ) ) if( project->contains( "legacy" ) )
{
// This defaults to false for new boards, but version 5.1.x and prior kept the fillets
// so we do the same for legacy boards.
m_ZoneKeepExternalFillets = true;
project->at( "legacy" ).erase( "pcbnew" ); project->at( "legacy" ).erase( "pcbnew" );
}
// Now that we have everything, we need to load again // Now that we have everything, we need to load again
if( migrated ) if( migrated )

View File

@ -1193,45 +1193,67 @@ void ZONE_CONTAINER::GetInteractingZones( PCB_LAYER_ID aLayer,
bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer ) const bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer ) const
{ {
if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations do not like it ... if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations will not like it ...
return false; return false;
BOARD* board = GetBoard();
int maxError = ARC_HIGH_DEF;
bool keepExternalFillets = false;
if( board )
{
maxError = board->GetDesignSettings().m_MaxError;
keepExternalFillets = board->GetDesignSettings().m_ZoneKeepExternalFillets;
}
auto smooth = [&]( SHAPE_POLY_SET& aPoly )
{
switch( m_cornerSmoothingType )
{
case ZONE_SETTINGS::SMOOTHING_CHAMFER:
aPoly = aPoly.Chamfer( (int) m_cornerRadius );
break;
case ZONE_SETTINGS::SMOOTHING_FILLET:
{
aPoly = aPoly.Fillet( (int) m_cornerRadius, maxError );
break;
}
default:
break;
}
};
std::vector<ZONE_CONTAINER*> interactingZones; std::vector<ZONE_CONTAINER*> interactingZones;
GetInteractingZones( aLayer, &interactingZones ); GetInteractingZones( aLayer, &interactingZones );
SHAPE_POLY_SET* maxExtents = m_Poly;
SHAPE_POLY_SET withFillets;
aSmoothedPoly = *m_Poly; aSmoothedPoly = *m_Poly;
// Should external fillets (that is, those applied to concave corners) be kept? While it
// seems safer to never have copper extend outside the zone outline, 5.1.x and prior did
// indeed fill them so we leave the mode available.
if( keepExternalFillets )
{
withFillets = *m_Poly;
smooth( withFillets );
withFillets.BooleanAdd( *m_Poly, SHAPE_POLY_SET::PM_FAST );
maxExtents = &withFillets;
}
for( ZONE_CONTAINER* zone : interactingZones ) for( ZONE_CONTAINER* zone : interactingZones )
aSmoothedPoly.BooleanAdd( *zone->Outline(), SHAPE_POLY_SET::PM_FAST ); aSmoothedPoly.BooleanAdd( *zone->Outline(), SHAPE_POLY_SET::PM_FAST );
// Make a smoothed polygon out of the user-drawn polygon if required smooth( aSmoothedPoly );
switch( m_cornerSmoothingType )
{
case ZONE_SETTINGS::SMOOTHING_CHAMFER:
aSmoothedPoly = aSmoothedPoly.Chamfer( m_cornerRadius );
break;
case ZONE_SETTINGS::SMOOTHING_FILLET:
{
BOARD* board = GetBoard();
int maxError = ARC_HIGH_DEF;
if( board )
maxError = board->GetDesignSettings().m_MaxError;
aSmoothedPoly = aSmoothedPoly.Fillet( m_cornerRadius, maxError );
break;
}
default:
break;
}
if( interactingZones.size() ) if( interactingZones.size() )
aSmoothedPoly.BooleanIntersection( *m_Poly, SHAPE_POLY_SET::PM_FAST ); aSmoothedPoly.BooleanIntersection( *maxExtents, SHAPE_POLY_SET::PM_FAST );
return true; return true;
}; }
double ZONE_CONTAINER::CalculateFilledArea() double ZONE_CONTAINER::CalculateFilledArea()

View File

@ -66,6 +66,7 @@ bool PANEL_SETUP_FEATURE_CONSTRAINTS::TransferDataToWindow()
m_rbOutlinePolygonFastest->SetValue( m_BrdSettings->m_ZoneUseNoOutlineInFill ); m_rbOutlinePolygonFastest->SetValue( m_BrdSettings->m_ZoneUseNoOutlineInFill );
m_rbOutlinePolygonBestQ->SetValue( !m_BrdSettings->m_ZoneUseNoOutlineInFill ); m_rbOutlinePolygonBestQ->SetValue( !m_BrdSettings->m_ZoneUseNoOutlineInFill );
m_allowExternalFilletsOpt->SetValue( m_BrdSettings->m_ZoneKeepExternalFillets );
m_minClearance.SetValue( m_BrdSettings->m_MinClearance ); m_minClearance.SetValue( m_BrdSettings->m_MinClearance );
m_trackMinWidth.SetValue( m_BrdSettings->m_TrackMinWidth ); m_trackMinWidth.SetValue( m_BrdSettings->m_TrackMinWidth );
@ -113,6 +114,7 @@ bool PANEL_SETUP_FEATURE_CONSTRAINTS::TransferDataFromWindow()
m_maxError.GetValue(), IU_PER_MM * MAXIMUM_ERROR_SIZE_MM ); m_maxError.GetValue(), IU_PER_MM * MAXIMUM_ERROR_SIZE_MM );
m_BrdSettings->m_ZoneUseNoOutlineInFill = m_rbOutlinePolygonFastest->GetValue(); m_BrdSettings->m_ZoneUseNoOutlineInFill = m_rbOutlinePolygonFastest->GetValue();
m_BrdSettings->m_ZoneKeepExternalFillets = m_allowExternalFilletsOpt->GetValue();
m_BrdSettings->m_MinClearance = m_minClearance.GetValue(); m_BrdSettings->m_MinClearance = m_minClearance.GetValue();
m_BrdSettings->m_TrackMinWidth = m_trackMinWidth.GetValue(); m_BrdSettings->m_TrackMinWidth = m_trackMinWidth.GetValue();
@ -140,6 +142,7 @@ bool PANEL_SETUP_FEATURE_CONSTRAINTS::Show( bool aShow )
// first displayed. However, on OSX 3.0.5 (at least), if another panel is displayed // first displayed. However, on OSX 3.0.5 (at least), if another panel is displayed
// first then the icons will be blank unless they're set here. // first then the icons will be blank unless they're set here.
m_bitmapZoneFillOpt->SetBitmap( KiBitmap( show_zone_xpm ) ); m_bitmapZoneFillOpt->SetBitmap( KiBitmap( show_zone_xpm ) );
m_filletBitmap->SetBitmap( KiBitmap( zone_fillet_xpm ) );
m_bitmapClearance->SetBitmap( KiBitmap( ps_diff_pair_gap_xpm ) ); m_bitmapClearance->SetBitmap( KiBitmap( ps_diff_pair_gap_xpm ) );
m_bitmapMinTrackWidth->SetBitmap( KiBitmap( width_track_xpm ) ); m_bitmapMinTrackWidth->SetBitmap( KiBitmap( width_track_xpm ) );
m_bitmapMinViaAnnulus->SetBitmap( KiBitmap( via_annulus_xpm ) ); m_bitmapMinViaAnnulus->SetBitmap( KiBitmap( via_annulus_xpm ) );

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 10 2019) // C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -132,6 +132,18 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
m_bSizerPolygonFillOption->Add( bSizer5, 1, wxEXPAND, 15 ); m_bSizerPolygonFillOption->Add( bSizer5, 1, wxEXPAND, 15 );
wxBoxSizer* bSizer9;
bSizer9 = new wxBoxSizer( wxHORIZONTAL );
m_filletBitmap = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bSizer9->Add( m_filletBitmap, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_allowExternalFilletsOpt = new wxCheckBox( this, wxID_ANY, _("Allow fillets outside zone outline"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer9->Add( m_allowExternalFilletsOpt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_bSizerPolygonFillOption->Add( bSizer9, 1, wxEXPAND, 5 );
sbFeatureRules->Add( m_bSizerPolygonFillOption, 0, wxEXPAND|wxTOP, 10 ); sbFeatureRules->Add( m_bSizerPolygonFillOption, 0, wxEXPAND|wxTOP, 10 );

View File

@ -14,7 +14,6 @@
<property name="file">panel_setup_feature_constraints_base</property> <property name="file">panel_setup_feature_constraints_base</property>
<property name="first_id">1000</property> <property name="first_id">1000</property>
<property name="help_provider">none</property> <property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property> <property name="indent_with_spaces"></property>
<property name="internationalize">1</property> <property name="internationalize">1</property>
<property name="name">panel_setup_feature_constraints_base</property> <property name="name">panel_setup_feature_constraints_base</property>
@ -26,7 +25,6 @@
<property name="skip_php_events">1</property> <property name="skip_php_events">1</property>
<property name="skip_python_events">1</property> <property name="skip_python_events">1</property>
<property name="ui_table">UI</property> <property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">1</property> <property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property> <property name="use_microsoft_bom">0</property>
<object class="Panel" expanded="1"> <object class="Panel" expanded="1">
@ -1210,6 +1208,139 @@
</object> </object>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizer9</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticBitmap" 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="bitmap"></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="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_filletBitmap</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="subclass">; ; forward_declare</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>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" 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="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">Allow fillets outside zone outline</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_allowExternalFilletsOpt</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>
</object>
</object>
</object>
</object>
</object> </object>
</object> </object>
</object> </object>

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 10 2019) // C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -56,6 +56,8 @@ class PANEL_SETUP_FEATURE_CONSTRAINTS_BASE : public wxPanel
wxStaticBitmap* m_bitmapZoneFillOpt; wxStaticBitmap* m_bitmapZoneFillOpt;
wxRadioButton* m_rbOutlinePolygonBestQ; wxRadioButton* m_rbOutlinePolygonBestQ;
wxRadioButton* m_rbOutlinePolygonFastest; wxRadioButton* m_rbOutlinePolygonFastest;
wxStaticBitmap* m_filletBitmap;
wxCheckBox* m_allowExternalFilletsOpt;
wxStaticText* m_staticText23; wxStaticText* m_staticText23;
wxStaticBitmap* m_bitmapClearance; wxStaticBitmap* m_bitmapClearance;
wxStaticText* m_clearanceTitle; wxStaticText* m_clearanceTitle;