From 305abb210f05790cb83b29121a6f3676fbc384c6 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 30 Aug 2020 15:18:35 +0100 Subject: [PATCH] Add a mode to allow zone smoothing to produce external fillets. Fixes https://gitlab.com/kicad/code/kicad/issues/5306 --- bitmaps_png/CMakeLists.txt | 1 + bitmaps_png/cpp_26/zone_fillet.cpp | 46 ++++++ .../include/bitmaps_png/bitmaps_list.h | 1 + bitmaps_png/sources/zone_fillet.svg | 108 ++++++++++++++ include/board_design_settings.h | 45 +++--- pcbnew/board_design_settings.cpp | 71 +++++---- pcbnew/class_zone.cpp | 72 ++++++---- .../panel_setup_feature_constraints.cpp | 3 + .../panel_setup_feature_constraints_base.cpp | 14 +- .../panel_setup_feature_constraints_base.fbp | 135 +++++++++++++++++- .../panel_setup_feature_constraints_base.h | 4 +- 11 files changed, 418 insertions(+), 82 deletions(-) create mode 100644 bitmaps_png/cpp_26/zone_fillet.cpp create mode 100644 bitmaps_png/sources/zone_fillet.svg diff --git a/bitmaps_png/CMakeLists.txt b/bitmaps_png/CMakeLists.txt index c5c9c3b84d..6a0a4b7103 100644 --- a/bitmaps_png/CMakeLists.txt +++ b/bitmaps_png/CMakeLists.txt @@ -499,6 +499,7 @@ set( BMAPS_MID wizard_add_fplib_small zip zone_duplicate + zone_fillet zone_unfill zoom zoom_area diff --git a/bitmaps_png/cpp_26/zone_fillet.cpp b/bitmaps_png/cpp_26/zone_fillet.cpp new file mode 100644 index 0000000000..d121ec4f75 --- /dev/null +++ b/bitmaps_png/cpp_26/zone_fillet.cpp @@ -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 + +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 diff --git a/bitmaps_png/include/bitmaps_png/bitmaps_list.h b/bitmaps_png/include/bitmaps_png/bitmaps_list.h index d7c299b458..eec132e59e 100644 --- a/bitmaps_png/include/bitmaps_png/bitmaps_list.h +++ b/bitmaps_png/include/bitmaps_png/bitmaps_list.h @@ -486,6 +486,7 @@ EXTERN_BITMAP( wizard_add_fplib_small_xpm ) EXTERN_BITMAP( www_xpm ) EXTERN_BITMAP( zip_xpm ) EXTERN_BITMAP( zone_duplicate_xpm ) +EXTERN_BITMAP( zone_fillet_xpm ) EXTERN_BITMAP( zone_unfill_xpm ) EXTERN_BITMAP( zoom_area_xpm ) EXTERN_BITMAP( zoom_auto_fit_in_page_xpm ) diff --git a/bitmaps_png/sources/zone_fillet.svg b/bitmaps_png/sources/zone_fillet.svg new file mode 100644 index 0000000000..53abfce50f --- /dev/null +++ b/bitmaps_png/sources/zone_fillet.svg @@ -0,0 +1,108 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/include/board_design_settings.h b/include/board_design_settings.h index e7a3211f0a..36c770393f 100644 --- a/include/board_design_settings.h +++ b/include/board_design_settings.h @@ -239,25 +239,28 @@ public: std::map< int, int > m_DRCSeverities; // Map from DRCErrorCode to SEVERITY std::set m_DrcExclusions; - /** Option to handle filled polygons in zones: - * 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 - * moreover when exporting zone filled areas, the excatct shape is exported. - * the legacy option can really create redraw time issues for large boards. - */ - bool m_ZoneUseNoOutlineInFill; ///< true for new zone filling option + // Option to handle filled polygons in zones: + // 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 + // moreover when exporting zone filled areas, the excatct shape is exported. + // the legacy option can really create redraw time issues for large boards. + bool m_ZoneUseNoOutlineInFill; + + // 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 int m_MaxError; // Global mask margins: - int m_SolderMaskMargin; ///< Solder mask margin - int m_SolderMaskMinWidth; ///< Solder mask min width - // 2 areas near than m_SolderMaskMinWidth - // are merged - int m_SolderPasteMargin; ///< Solder paste margin absolute value - double m_SolderPasteMarginRatio; ///< Solder pask margin ratio value of pad size - ///< The final margin is the sum of these 2 values + int m_SolderMaskMargin; // Solder mask margin + int m_SolderMaskMinWidth; // Solder mask min width (2 areas closer than this + // width are merged) + int m_SolderPasteMargin; // Solder paste margin absolute value + double m_SolderPasteMarginRatio; // Solder pask margin ratio value of pad size + // The final margin is the sum of these 2 values // Variables used in footprint editing (default value in item/footprint creation) std::vector m_DefaultFPTextItems; @@ -276,16 +279,12 @@ public: wxPoint m_AuxOrigin; ///< origin for plot exports wxPoint m_GridOrigin; ///< origin for grid offsets - D_PAD m_Pad_Master; ///< A dummy pad to store all default parameters - // when importing values or create a new pad + D_PAD m_Pad_Master; // A dummy pad to store all default parameters + // when importing values or creating a new pad - /** Set to true if the board has a stackup management. - * if m_hasStackup is false, a default basic stackup witll be used to - * generate the ;gbrjob file. - * 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 - */ + // Set to true if the board has a stackup management. + // If not set a default basic stackup witll be used to generate the ;gbrjob file. + // Could be removed later, or at least always set to true bool m_HasStackup; private: diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp index f9a1aa260d..73324859aa 100644 --- a/pcbnew/board_design_settings.cpp +++ b/pcbnew/board_design_settings.cpp @@ -23,14 +23,13 @@ #include #include -#include #include #include #include -#include +//#include #include #include -#include +//#include #include #include #include @@ -157,7 +156,9 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: m_DRCSeverities[ DRCE_EXTRA_FOOTPRINT ] = RPT_SEVERITY_WARNING; 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: 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( "rules.allow_microvias", &m_MicroViasAllowed, false ) ); - m_params.emplace_back( - new PARAM( "rules.allow_blind_buried_vias", &m_BlindBuriedViaAllowed, false ) ); + m_params.emplace_back( new PARAM( "rules.allow_blind_buried_vias", + &m_BlindBuriedViaAllowed, false ) ); m_params.emplace_back( new PARAM_SCALED( "rules.min_clearance", &m_MinClearance, 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, TEXTS_MAX_WIDTH, MM_PER_IU ) ); - m_params.emplace_back( new PARAM( - "defaults.silk_text_italic", &m_TextItalic[LAYER_CLASS_SILK], false ) ); + m_params.emplace_back( new PARAM( "defaults.silk_text_italic", + &m_TextItalic[LAYER_CLASS_SILK], false ) ); - m_params.emplace_back( new PARAM( - "defaults.silk_text_upright", &m_TextUpright[ LAYER_CLASS_SILK ], true ) ); + m_params.emplace_back( new PARAM( "defaults.silk_text_upright", + &m_TextUpright[ LAYER_CLASS_SILK ], true ) ); m_params.emplace_back( new PARAM_SCALED( "defaults.copper_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 ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) ); - m_params.emplace_back( new PARAM( - "defaults.copper_text_italic", &m_TextItalic[LAYER_CLASS_COPPER], false ) ); + m_params.emplace_back( new PARAM( "defaults.copper_text_italic", + &m_TextItalic[LAYER_CLASS_COPPER], false ) ); - m_params.emplace_back( new PARAM( - "defaults.copper_text_upright", &m_TextUpright[LAYER_CLASS_COPPER], true ) ); + m_params.emplace_back( new PARAM( "defaults.copper_text_upright", + &m_TextUpright[LAYER_CLASS_COPPER], true ) ); m_params.emplace_back( new PARAM_SCALED( "defaults.board_outline_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 ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) ); - m_params.emplace_back( - new PARAM( "defaults.fab_text_italic", &m_TextItalic[LAYER_CLASS_FAB], false ) ); + m_params.emplace_back( new PARAM( "defaults.fab_text_italic", + &m_TextItalic[LAYER_CLASS_FAB], false ) ); - m_params.emplace_back( - new PARAM( "defaults.fab_text_upright", &m_TextUpright[LAYER_CLASS_FAB], true ) ); + m_params.emplace_back( new PARAM( "defaults.fab_text_upright", + &m_TextUpright[LAYER_CLASS_FAB], true ) ); m_params.emplace_back( new PARAM_SCALED( "defaults.other_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 ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) ); - m_params.emplace_back( new PARAM( - "defaults.other_text_italic", &m_TextItalic[LAYER_CLASS_OTHERS], false ) ); + m_params.emplace_back( new PARAM( "defaults.other_text_italic", + &m_TextItalic[LAYER_CLASS_OTHERS], false ) ); - m_params.emplace_back( new PARAM( - "defaults.other_text_upright", &m_TextUpright[LAYER_CLASS_OTHERS], true ) ); + m_params.emplace_back( new PARAM( "defaults.other_text_upright", + &m_TextUpright[LAYER_CLASS_OTHERS], true ) ); - m_params.emplace_back( - new PARAM( "defaults.dimension_units", &m_DimensionUnits, 0, 0, 2 ) ); + m_params.emplace_back( new PARAM( "defaults.dimension_units", + &m_DimensionUnits, 0, 0, 2 ) ); - m_params.emplace_back( - new PARAM( "defaults.dimension_precision", &m_DimensionPrecision, 1, 0, 2 ) ); + m_params.emplace_back( new PARAM( "defaults.dimension_precision", + &m_DimensionPrecision, 1, 0, 2 ) ); - m_params.emplace_back( new PARAM( - "defaults.zones.45_degree_only", &m_defaultZoneSettings.m_Zone_45_Only, false ) ); + m_params.emplace_back( new PARAM( "defaults.zones.45_degree_only", + &m_defaultZoneSettings.m_Zone_45_Only, false ) ); m_params.emplace_back( new PARAM_SCALED( "defaults.zones.min_clearance", &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( "rules.max_error", &m_MaxError, ARC_HIGH_DEF, Millimeter2iu( 0.0001 ), Millimeter2iu( 1.0 ), MM_PER_IU ) ); - m_params.emplace_back( - new PARAM( "zones_use_no_outline", &m_ZoneUseNoOutlineInFill, true ) ); + m_params.emplace_back( new PARAM( "zones_use_no_outline", + &m_ZoneUseNoOutlineInFill, true ) ); + + m_params.emplace_back( new PARAM( "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_DrcExclusions = aOther.m_DrcExclusions; m_ZoneUseNoOutlineInFill = aOther.m_ZoneUseNoOutlineInFill; + m_ZoneKeepExternalFillets= aOther.m_ZoneKeepExternalFillets; m_MaxError = aOther.m_MaxError; m_SolderMaskMargin = aOther.m_SolderMaskMargin; m_SolderMaskMinWidth = aOther.m_SolderMaskMinWidth; @@ -709,7 +714,13 @@ bool BOARD_DESIGN_SETTINGS::LoadFromFile( const wxString& aDirectory ) } 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" ); + } // Now that we have everything, we need to load again if( migrated ) diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index d6285cd74f..6aba983d04 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -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 { - if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations do not like it ... + if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations will not like it ... 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 interactingZones; GetInteractingZones( aLayer, &interactingZones ); + SHAPE_POLY_SET* maxExtents = m_Poly; + SHAPE_POLY_SET withFillets; + 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 ) aSmoothedPoly.BooleanAdd( *zone->Outline(), SHAPE_POLY_SET::PM_FAST ); - // Make a smoothed polygon out of the user-drawn polygon if required - 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; - } + smooth( aSmoothedPoly ); if( interactingZones.size() ) - aSmoothedPoly.BooleanIntersection( *m_Poly, SHAPE_POLY_SET::PM_FAST ); + aSmoothedPoly.BooleanIntersection( *maxExtents, SHAPE_POLY_SET::PM_FAST ); return true; -}; +} double ZONE_CONTAINER::CalculateFilledArea() diff --git a/pcbnew/dialogs/panel_setup_feature_constraints.cpp b/pcbnew/dialogs/panel_setup_feature_constraints.cpp index e9ec535a42..6a8e05593c 100644 --- a/pcbnew/dialogs/panel_setup_feature_constraints.cpp +++ b/pcbnew/dialogs/panel_setup_feature_constraints.cpp @@ -66,6 +66,7 @@ bool PANEL_SETUP_FEATURE_CONSTRAINTS::TransferDataToWindow() m_rbOutlinePolygonFastest->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_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_BrdSettings->m_ZoneUseNoOutlineInFill = m_rbOutlinePolygonFastest->GetValue(); + m_BrdSettings->m_ZoneKeepExternalFillets = m_allowExternalFilletsOpt->GetValue(); m_BrdSettings->m_MinClearance = m_minClearance.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 then the icons will be blank unless they're set here. m_bitmapZoneFillOpt->SetBitmap( KiBitmap( show_zone_xpm ) ); + m_filletBitmap->SetBitmap( KiBitmap( zone_fillet_xpm ) ); m_bitmapClearance->SetBitmap( KiBitmap( ps_diff_pair_gap_xpm ) ); m_bitmapMinTrackWidth->SetBitmap( KiBitmap( width_track_xpm ) ); m_bitmapMinViaAnnulus->SetBitmap( KiBitmap( via_annulus_xpm ) ); diff --git a/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp b/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp index 9618f29914..67f7ee317d 100644 --- a/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp +++ b/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp @@ -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/ // // 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 ); + 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 ); diff --git a/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp b/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp index 7cc2aca27c..8507fcf370 100644 --- a/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp +++ b/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp @@ -14,7 +14,6 @@ panel_setup_feature_constraints_base 1000 none - 1 panel_setup_feature_constraints_base @@ -26,7 +25,6 @@ 1 1 UI - 0 1 0 @@ -1210,6 +1208,139 @@ + + 5 + wxEXPAND + 1 + + + bSizer9 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_filletBitmap + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Allow fillets outside zone outline + + 0 + + + 0 + + 1 + m_allowExternalFilletsOpt + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + diff --git a/pcbnew/dialogs/panel_setup_feature_constraints_base.h b/pcbnew/dialogs/panel_setup_feature_constraints_base.h index a19a68663d..4d5eb51cf6 100644 --- a/pcbnew/dialogs/panel_setup_feature_constraints_base.h +++ b/pcbnew/dialogs/panel_setup_feature_constraints_base.h @@ -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/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -56,6 +56,8 @@ class PANEL_SETUP_FEATURE_CONSTRAINTS_BASE : public wxPanel wxStaticBitmap* m_bitmapZoneFillOpt; wxRadioButton* m_rbOutlinePolygonBestQ; wxRadioButton* m_rbOutlinePolygonFastest; + wxStaticBitmap* m_filletBitmap; + wxCheckBox* m_allowExternalFilletsOpt; wxStaticText* m_staticText23; wxStaticBitmap* m_bitmapClearance; wxStaticText* m_clearanceTitle;