Teardrops: store parameters in BOARD_DESIGN_SETTINGS.

This commit is contained in:
jean-pierre charras 2022-01-22 20:26:58 +01:00
parent 5d21d12a71
commit 1b42152ba0
8 changed files with 327 additions and 148 deletions

View File

@ -531,6 +531,7 @@ set( PCB_COMMON_SRCS
${CMAKE_SOURCE_DIR}/pcbnew/board_commit.cpp
${CMAKE_SOURCE_DIR}/pcbnew/board_connected_item.cpp
${CMAKE_SOURCE_DIR}/pcbnew/board_design_settings.cpp
${CMAKE_SOURCE_DIR}/pcbnew/teardrop/teardrop_parameters.cpp #needed by board_design_settings.cpp
${CMAKE_SOURCE_DIR}/pcbnew/board.cpp
${CMAKE_SOURCE_DIR}/pcbnew/board_item.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcb_dimension.cpp

View File

@ -34,6 +34,7 @@
#include <settings/nested_settings.h>
#include <widgets/ui_common.h>
#include <zone_settings.h>
#include <teardrop/teardrop_parameters.h>
#define DEFAULT_SILK_LINE_WIDTH 0.12
@ -231,6 +232,11 @@ public:
BOARD_STACKUP& GetStackupDescriptor() { return m_stackup; }
const BOARD_STACKUP& GetStackupDescriptor() const { return m_stackup; }
TEARDROP_PARAMETERS_LIST* GetTeadropParamsList()
{
return &m_TeardropParamsList;
}
SEVERITY GetSeverity( int aDRCErrorCode );
/**
@ -662,6 +668,11 @@ public:
std::vector<VIA_DIMENSION> m_ViasDimensionsList;
std::vector<DIFF_PAIR_DIMENSION> m_DiffPairDimensionsList;
/** The parameters of teardrops for the different teardrop targets (via/pad, track end)
* 3 set of parameters always exist: for round shapes, for rect shapes, for track ends
*/
TEARDROP_PARAMETERS_LIST m_TeardropParamsList;
bool m_MicroViasAllowed; ///< true to allow micro vias
bool m_BlindBuriedViaAllowed; ///< true to allow blind/buried vias
VIATYPE m_CurrentViaType; ///< (VIA_BLIND_BURIED, VIA_THROUGH, VIA_MICROVIA)

View File

@ -448,6 +448,110 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
},
{} ) );
// Handle options for teardrops (targets and some others):
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "teardrop_options",
[&]() -> nlohmann::json
{
nlohmann::json js = nlohmann::json::array();
nlohmann::json entry = {};
entry["td_onviapad"] = m_TeardropParamsList.m_TargetViasPads;
entry["td_onpadsmd"] = m_TeardropParamsList.m_TargetPadsWithNoHole;
entry["td_ontrackend"] = m_TeardropParamsList.m_TargetTrack2Track;
entry["td_onroundshapesonly"] = m_TeardropParamsList.m_UseRoundShapesOnly;
entry["td_allow_use_two_tracks"] = m_TeardropParamsList.m_AllowUseTwoTracks;
entry["td_curve_segcount"] = m_TeardropParamsList.m_CurveSegCount;
js.push_back( entry );
return js;
},
[&]( const nlohmann::json& aObj )
{
if( !aObj.is_array() )
return;
for( const nlohmann::json& entry : aObj )
{
if( entry.empty() || !entry.is_object() )
continue;
if( !entry.contains( "td_onviapad" )
|| !entry.contains( "td_onpadsmd" )
|| !entry.contains( "td_ontrackend" )
|| !entry.contains( "td_onroundshapesonly" )
|| !entry.contains( "td_allow_use_two_tracks" )
|| !entry.contains( "td_curve_segcount" )
)
continue;
m_TeardropParamsList.m_TargetViasPads = entry["td_onviapad"].get<bool>();
m_TeardropParamsList.m_TargetPadsWithNoHole = entry["td_onpadsmd"].get<bool>();
m_TeardropParamsList.m_TargetTrack2Track = entry["td_ontrackend"].get<bool>();
m_TeardropParamsList.m_UseRoundShapesOnly = entry["td_onroundshapesonly"].get<bool>();
m_TeardropParamsList.m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
m_TeardropParamsList.m_CurveSegCount = entry["td_curve_segcount"].get<int>();
}
},
{} ) );
// Handle parameters (sizes, shape) for each type of teardrop:
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "teardrop_parameters",
[&]() -> nlohmann::json
{
nlohmann::json js = nlohmann::json::array();
for( int ii = 0; ii < m_TeardropParamsList.GetParametersCount(); ii++ )
{
nlohmann::json entry = {};
TEARDROP_PARAMETERS* td_prm = m_TeardropParamsList.GetParameters( (TARGET_TD)ii );
entry["td_target_name"] = GetTeardropTargetCanonicalName( (TARGET_TD)ii );
entry["td_maxlen"] = Iu2Millimeter( td_prm->m_TdMaxLen );
entry["td_maxheight"] = Iu2Millimeter( td_prm->m_TdMaxHeight );
entry["td_length_ratio"] = td_prm->m_LengthRatio;
entry["td_height_ratio"] = td_prm->m_HeightRatio;
entry["td_curve_segcount"] = td_prm->m_CurveSegCount;
js.push_back( entry );
}
return js;
},
[&]( const nlohmann::json& aObj )
{
if( !aObj.is_array() )
return;
for( const nlohmann::json& entry : aObj )
{
if( entry.empty() || !entry.is_object() )
continue;
if( !entry.contains( "td_target_name" )
|| !entry.contains( "td_maxlen" )
|| !entry.contains( "td_maxheight" )
|| !entry.contains( "td_length_ratio" )
|| !entry.contains( "td_height_ratio" )
|| !entry.contains( "td_curve_segcount" )
)
continue;
int idx = GetTeardropTargetTypeFromCanonicalName( entry["td_target_name"].get<std::string>() );
if( idx >= 0 && idx < 3 )
{
TEARDROP_PARAMETERS* td_prm = m_TeardropParamsList.GetParameters( (TARGET_TD)idx );
td_prm->m_TdMaxLen = Millimeter2iu( entry["td_maxlen"].get<double>() );
td_prm->m_TdMaxHeight = Millimeter2iu( entry["td_maxheight"].get<double>() );
td_prm->m_LengthRatio = entry["td_length_ratio"].get<double>();
td_prm->m_HeightRatio = entry["td_height_ratio"].get<double>();
td_prm->m_CurveSegCount = entry["td_curve_segcount"].get<int>();
}
}
},
{} ) );
m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_line_width",
&m_LineThickness[LAYER_CLASS_SILK], Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ),
Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );

View File

@ -43,6 +43,7 @@ class TEARDROP_DIALOG: public TEARDROP_DIALOG_BASE
public:
TEARDROP_DIALOG( PCB_EDIT_FRAME* aParent ):
TEARDROP_DIALOG_BASE( aParent ),
m_brdSettings( nullptr ),
m_frame( aParent ),
m_teardropMaxLenSettingRound( aParent,m_stMaxLenRound, m_tcTdMaxLenRound, nullptr ),
m_teardropMaxHeightSettingRound( aParent, m_stTdMaxSizeRound, m_tcMaxHeightRound, m_stLenUnitRound ),
@ -56,30 +57,37 @@ public:
m_bitmapTdRectangularInfo->SetBitmap( KiBitmap( BITMAPS::teardrop_rect_sizes ) );
m_bitmapTdTrackInfo->SetBitmap( KiBitmap( BITMAPS::teardrop_track_sizes ) );
m_cbSmdSimilarPads->SetValue( m_includeNotPTH );
m_cbRoundShapesOnly->SetValue( m_roundShapesOnly );
m_rbShapeRound->SetSelection( m_curveOptionRoundShapes );
m_rbShapeRect->SetSelection( m_curveOptionRectShapes );
m_rbShapeTrack->SetSelection( m_curveOptionTrackShapes );
m_cbOptUseNextTrack->SetValue( m_canUseTwoTracks );
m_spPointCount->SetValue( m_curveSegCount );
m_cbTrack2Track->SetValue( m_track2Track );
m_cbPadVia->SetValue( m_includeViasAndPTH );
m_brdSettings = &m_frame->GetBoard()->GetBoard()->GetDesignSettings();
TEARDROP_PARAMETERS_LIST* prmsList = m_brdSettings->GetTeadropParamsList();
m_teardropMaxLenSettingRound.SetValue( m_teardropMaxLenPrmRound );
m_teardropMaxHeightSettingRound.SetValue( m_teardropMaxSizePrmRound );
m_spTeardropLenPercentRound->SetValue( m_teardropLenPrmRound );
m_spTeardropSizePercentRound->SetValue( m_teardropSizePrmRound );
m_cbPadVia->SetValue( prmsList->m_TargetViasPads );
m_cbSmdSimilarPads->SetValue( prmsList->m_TargetPadsWithNoHole );
m_cbRoundShapesOnly->SetValue( prmsList->m_UseRoundShapesOnly );
m_cbTrack2Track->SetValue( prmsList->m_TargetTrack2Track );
m_teardropMaxLenSettingRect.SetValue( m_teardropMaxLenPrmRect );
m_teardropMaxHeightSettingRect.SetValue( m_teardropMaxSizePrmRect );
m_spTeardropLenPercentRect->SetValue( m_teardropLenPrmRect );
m_spTeardropSizePercentRect->SetValue( m_teardropSizePrmRect );
m_cbOptUseNextTrack->SetValue( prmsList->m_AllowUseTwoTracks );
m_spPointCount->SetValue( prmsList->m_CurveSegCount );
m_teardropMaxLenSettingTrack.SetValue( m_teardropMaxLenPrmTrack );
m_teardropMaxHeightSettingTrack.SetValue( m_teardropMaxSizePrmTrack );
m_spTeardropLenPercentTrack->SetValue( m_teardropLenPrmTrack );
m_spTeardropSizePercentTrack->SetValue( m_teardropSizePrmTrack );
TEARDROP_PARAMETERS* prms = prmsList->GetParameters( TARGET_ROUND );
m_teardropMaxLenSettingRound.SetValue( prms->m_TdMaxLen );
m_teardropMaxHeightSettingRound.SetValue( prms->m_TdMaxHeight );
m_spTeardropLenPercentRound->SetValue( prms->m_LengthRatio*100 );
m_spTeardropSizePercentRound->SetValue( prms->m_HeightRatio*100 );
m_rbShapeRound->SetSelection( prms->IsCurved() );
prms = prmsList->GetParameters( TARGET_RECT );
m_teardropMaxLenSettingRect.SetValue( prms->m_TdMaxLen );
m_teardropMaxHeightSettingRect.SetValue( prms->m_TdMaxHeight );
m_spTeardropLenPercentRect->SetValue( prms->m_LengthRatio*100 );
m_spTeardropSizePercentRect->SetValue(prms->m_HeightRatio*100 );
m_rbShapeRect->SetSelection( prms->IsCurved() );
prms = prmsList->GetParameters( TARGET_TRACK );
m_teardropMaxLenSettingTrack.SetValue(prms->m_TdMaxLen );
m_teardropMaxHeightSettingTrack.SetValue( prms->m_TdMaxHeight );
m_spTeardropLenPercentTrack->SetValue( prms->m_LengthRatio*100 );
m_spTeardropSizePercentTrack->SetValue( prms->m_HeightRatio*100 );
m_rbShapeTrack->SetSelection( prms->IsCurved() );
// recalculate sizers, now the bitmap is initialized
finishDialogSettings();
@ -87,30 +95,37 @@ public:
~TEARDROP_DIALOG()
{
m_teardropLenPrmRound = m_spTeardropLenPercentRound->GetValue();
m_teardropSizePrmRound = m_spTeardropSizePercentRound->GetValue();
m_teardropMaxLenPrmRound = m_teardropMaxLenSettingRound.GetValue();
m_teardropMaxSizePrmRound = m_teardropMaxHeightSettingRound.GetValue();
int shape_seg_count = GetCurvePointCount();
TEARDROP_PARAMETERS_LIST* prmsList = m_brdSettings->GetTeadropParamsList();
m_teardropLenPrmRect = m_spTeardropLenPercentRect->GetValue();
m_teardropSizePrmRect = m_spTeardropSizePercentRect->GetValue();
m_teardropMaxLenPrmRect = m_teardropMaxLenSettingRect.GetValue();
m_teardropMaxSizePrmRect = m_teardropMaxHeightSettingRect.GetValue();
prmsList->m_TargetViasPads = m_cbPadVia->GetValue();
prmsList->m_TargetPadsWithNoHole = m_cbSmdSimilarPads->GetValue();
prmsList->m_UseRoundShapesOnly = m_cbRoundShapesOnly->GetValue();
prmsList->m_TargetTrack2Track = m_cbTrack2Track->GetValue();
m_teardropLenPrmTrack = m_spTeardropLenPercentTrack->GetValue();
m_teardropSizePrmTrack = m_spTeardropSizePercentTrack->GetValue();
m_teardropMaxLenPrmTrack = m_teardropMaxLenSettingTrack.GetValue();
m_teardropMaxSizePrmTrack = m_teardropMaxHeightSettingTrack.GetValue();
prmsList->m_AllowUseTwoTracks = m_cbOptUseNextTrack->GetValue();
prmsList->m_CurveSegCount = m_spPointCount->GetValue();
m_roundShapesOnly = m_cbRoundShapesOnly->GetValue();
m_includeNotPTH = m_cbSmdSimilarPads->GetValue();
m_curveOptionRoundShapes = m_rbShapeRound->GetSelection();
m_curveOptionRectShapes = m_rbShapeRect->GetSelection();
m_curveOptionTrackShapes = m_rbShapeTrack->GetSelection();
m_canUseTwoTracks = m_cbOptUseNextTrack->GetValue();
m_curveSegCount = m_spPointCount->GetValue();
m_track2Track = m_cbTrack2Track->GetValue();
m_includeViasAndPTH = m_cbPadVia->GetValue();
TEARDROP_PARAMETERS* prms = prmsList->GetParameters( TARGET_ROUND );
prms->m_LengthRatio = GetTeardropLenPercentRound();
prms->m_HeightRatio = GetTeardropSizePercentRound();
prms->m_TdMaxLen = m_teardropMaxLenSettingRound.GetValue();
prms->m_TdMaxHeight = m_teardropMaxHeightSettingRound.GetValue();
prms->m_CurveSegCount = (CurvedShapeOption() & CURVED_OPTION_ROUND) ? shape_seg_count : 0;
prms = prmsList->GetParameters( TARGET_RECT );
prms->m_LengthRatio = GetTeardropLenPercentRect();
prms->m_HeightRatio = GetTeardropSizePercentRect();
prms->m_TdMaxLen = m_teardropMaxLenSettingRect.GetValue();
prms->m_TdMaxHeight = m_teardropMaxHeightSettingRect.GetValue();
prms->m_CurveSegCount = (CurvedShapeOption() & CURVED_OPTION_RECT) ? shape_seg_count : 0;
prms = prmsList->GetParameters( TARGET_TRACK );
prms->m_LengthRatio = GetTeardropLenPercentTrack();
prms->m_HeightRatio = GetTeardropSizePercentTrack();
prms->m_TdMaxLen = m_teardropMaxLenSettingTrack.GetValue();
prms->m_TdMaxHeight = m_teardropMaxHeightSettingTrack.GetValue();
prms->m_CurveSegCount = (CurvedShapeOption() & CURVED_OPTION_TRACK) ? shape_seg_count : 0;
}
int CurvedShapeOption()
@ -158,6 +173,7 @@ public:
bool TeardropOnTracks() { return m_cbTrack2Track->GetValue(); }
private:
BOARD_DESIGN_SETTINGS* m_brdSettings;
PCB_EDIT_FRAME* m_frame;
UNIT_BINDER m_teardropMaxLenSettingRound;
UNIT_BINDER m_teardropMaxHeightSettingRound;
@ -165,61 +181,8 @@ private:
UNIT_BINDER m_teardropMaxHeightSettingRect;
UNIT_BINDER m_teardropMaxLenSettingTrack;
UNIT_BINDER m_teardropMaxHeightSettingTrack;
// Used to store settings during a session:
static double m_teardropLenPrmRound;
static double m_teardropSizePrmRound;
static int m_teardropMaxLenPrmRound;
static int m_teardropMaxSizePrmRound;
static double m_teardropLenPrmRect;
static double m_teardropSizePrmRect;
static int m_teardropMaxLenPrmRect;
static int m_teardropMaxSizePrmRect;
static double m_teardropLenPrmTrack;
static double m_teardropSizePrmTrack;
static int m_teardropMaxLenPrmTrack;
static int m_teardropMaxSizePrmTrack;
static bool m_includeNotPTH;
static bool m_roundShapesOnly;
static int m_curveOptionRoundShapes;
static int m_curveOptionRectShapes;
static int m_curveOptionTrackShapes;
static bool m_canUseTwoTracks;
static int m_curveSegCount;
static bool m_track2Track;
static bool m_includeViasAndPTH;
};
// Store settings during a session:
double TEARDROP_DIALOG::m_teardropLenPrmRound = 50;
double TEARDROP_DIALOG::m_teardropSizePrmRound = 100;
int TEARDROP_DIALOG::m_teardropMaxLenPrmRound = Millimeter2iu( 1.0 );
int TEARDROP_DIALOG::m_teardropMaxSizePrmRound = Millimeter2iu( 2.0 );
double TEARDROP_DIALOG::m_teardropLenPrmRect = 50;
double TEARDROP_DIALOG::m_teardropSizePrmRect = 100;
int TEARDROP_DIALOG::m_teardropMaxLenPrmRect = Millimeter2iu( 1.0 );
int TEARDROP_DIALOG::m_teardropMaxSizePrmRect = Millimeter2iu( 2.0 );
double TEARDROP_DIALOG::m_teardropLenPrmTrack = 100;
double TEARDROP_DIALOG::m_teardropSizePrmTrack = 100;
int TEARDROP_DIALOG::m_teardropMaxLenPrmTrack = Millimeter2iu( 2.0 );
int TEARDROP_DIALOG::m_teardropMaxSizePrmTrack = Millimeter2iu( 2.0 );
bool TEARDROP_DIALOG::m_includeNotPTH = true;
bool TEARDROP_DIALOG::m_roundShapesOnly = false;
int TEARDROP_DIALOG::m_curveOptionRoundShapes = 0;
int TEARDROP_DIALOG::m_curveOptionRectShapes = 0;
int TEARDROP_DIALOG::m_curveOptionTrackShapes = 0;
bool TEARDROP_DIALOG::m_canUseTwoTracks = true;
int TEARDROP_DIALOG::m_curveSegCount = 5;
bool TEARDROP_DIALOG::m_track2Track = true;
bool TEARDROP_DIALOG::m_includeViasAndPTH = true;
void PCB_EDIT_FRAME::OnRunTeardropTool( wxCommandEvent& event )
{

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022 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
@ -156,8 +156,8 @@ int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter,
// Ensure a teardrop shape can be built:
// The track width must be < teardrop height
if( track->GetWidth() >= currParams->m_tdMaxHeight
|| track->GetWidth() >= viapad.m_Width * currParams->m_heightRatio )
if( track->GetWidth() >= currParams->m_TdMaxHeight
|| track->GetWidth() >= viapad.m_Width * currParams->m_HeightRatio )
continue;
// Skip case where pad/via and the track is within a copper zone with the same net

View File

@ -0,0 +1,62 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2022 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
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "teardrop_parameters.h"
#define TARGET_NAME_ROUND "td_round_shape"
#define TARGET_NAME_RECT "td_rect_shape"
#define TARGET_NAME_TRACK "td_track_end"
std::string GetTeardropTargetCanonicalName( TARGET_TD aTdType )
{
// return the canonical name of the target aTdType
std::string name;
switch( aTdType )
{
case TARGET_ROUND: name = TARGET_NAME_ROUND; break;
case TARGET_RECT: name = TARGET_NAME_RECT; break;
case TARGET_TRACK: name = TARGET_NAME_TRACK; break;
default: break;
}
return name;
}
TARGET_TD GetTeardropTargetTypeFromCanonicalName( const std::string& aTargetName )
{
// return the target type from the canonical name
if( aTargetName == TARGET_NAME_ROUND )
return TARGET_ROUND;
if( aTargetName == TARGET_NAME_RECT )
return TARGET_RECT;
if( aTargetName == TARGET_NAME_TRACK )
return TARGET_TRACK;
return TARGET_UNKNOWN;
}

View File

@ -25,9 +25,14 @@
#ifndef TEARDROP_PARAMS_H
#define TEARDROP_PARAMS_H
#include <string>
#include <vector>
#include <convert_to_biu.h>
// IDs for targets when creating teardrops
enum TARGET_TD
{
TARGET_UNKNOWN = -1,
TARGET_ROUND = 0,
TARGET_RECT = 1,
TARGET_TRACK = 2,
@ -41,16 +46,14 @@ enum TARGET_TD
*/
class TEARDROP_PARAMETERS
{
friend class TEARDROP_MANAGER;
friend class TEARDROP_PARAMETERS_LIST;
public:
TEARDROP_PARAMETERS():
m_tdMaxLen( Millimeter2iu( 1.0 ) ),
m_tdMaxHeight( Millimeter2iu( 2.0 ) ),
m_lengthRatio( 0.5),
m_heightRatio( 1.0 ),
m_curveSegCount( 0 )
TEARDROP_PARAMETERS( TARGET_TD aTdType ):
m_TdType( aTdType ),
m_TdMaxLen( Millimeter2iu( 1.0 ) ),
m_TdMaxHeight( Millimeter2iu( 2.0 ) ),
m_LengthRatio( 0.5),
m_HeightRatio( 1.0 ),
m_CurveSegCount( 0 )
{
}
@ -60,8 +63,8 @@ public:
*/
void SetTeardropMaxSize( int aMaxLen, int aMaxHeight )
{
m_tdMaxLen = aMaxLen;
m_tdMaxHeight = aMaxHeight;
m_TdMaxLen = aMaxLen;
m_TdMaxHeight = aMaxHeight;
}
/**
@ -71,8 +74,8 @@ public:
*/
void SetTeardropSizeRatio( double aLenghtRatio = 0.5, double aHeightRatio = 1.0 )
{
m_lengthRatio = aLenghtRatio;
m_heightRatio = aHeightRatio;
m_LengthRatio = aLenghtRatio;
m_HeightRatio = aHeightRatio;
}
/**
@ -81,23 +84,24 @@ public:
*/
void SetTeardropCurvedPrm( int aCurveSegCount = 0 )
{
m_curveSegCount = aCurveSegCount;
m_CurveSegCount = aCurveSegCount;
}
bool IsCurved() const { return m_curveSegCount > 2; }
bool IsCurved() const { return m_CurveSegCount > 2; }
protected:
public:
TARGET_TD m_TdType; /// the type of target for these parameters
/// max allowed length for teardrops in IU. <= 0 to disable
int m_tdMaxLen;
int m_TdMaxLen;
/// max allowed height for teardrops in IU. <= 0 to disable
int m_tdMaxHeight;
int m_TdMaxHeight;
/// The length of a teardrop as ratio between length and size of pad/via
double m_lengthRatio;
double m_LengthRatio;
/// The height of a teardrop as ratio between height and size of pad/via
double m_heightRatio;
double m_HeightRatio;
/// number of segments to build the curved sides of a teardrop area
/// must be > 2. for values <= 2 a straight line is used
int m_curveSegCount;
int m_CurveSegCount;
};
@ -111,11 +115,33 @@ class TEARDROP_PARAMETERS_LIST
std::vector<TEARDROP_PARAMETERS> m_params_list;
public:
TEARDROP_PARAMETERS_LIST()
/// True to create teardrops for vias and pads with holes
bool m_TargetViasPads;
/// True to create teardrops for pads without holes (SMD and others
bool m_TargetPadsWithNoHole;
/// True to create teardrops at the end of a track connected to the end of
/// another track having a different width
bool m_TargetTrack2Track;
/// True to create teardrops for round shapes only
bool m_UseRoundShapesOnly;
/// True to create teardrops using 2 track segments if the first in too small
bool m_AllowUseTwoTracks;
/// the number of segments to apprximate a curve (Bezier curve) in a teardrop
/// Must be > 2, otherwise a line is used
int m_CurveSegCount;
public:
TEARDROP_PARAMETERS_LIST() :
m_TargetViasPads( true ),
m_TargetPadsWithNoHole( true ),
m_TargetTrack2Track( false ),
m_UseRoundShapesOnly( false ),
m_AllowUseTwoTracks( true ),
m_CurveSegCount( 5 )
{
m_params_list.emplace_back( ); // parameters for TARGET_ROUND
m_params_list.emplace_back( ); // parameters for TARGET_RECT
m_params_list.emplace_back( ); // parameters for TARGET_TRACK
m_params_list.emplace_back( TARGET_ROUND ); // parameters for TARGET_ROUND
m_params_list.emplace_back( TARGET_RECT ); // parameters for TARGET_RECT
m_params_list.emplace_back( TARGET_TRACK ); // parameters for TARGET_TRACK
}
/**
@ -136,4 +162,16 @@ public:
};
/**
* @return the canonical name of a target type of a TEARDROP_PARAMETERS
* @param aTdType is the target type
*/
std::string GetTeardropTargetCanonicalName( TARGET_TD aTdType );
/**
* @return the target type from a canonical name of a TEARDROP_PARAMETERS
* @param aTargetName is the canonical name
*/
TARGET_TD GetTeardropTargetTypeFromCanonicalName( const std::string& aTargetName );
#endif // ifndef TEARDROP_PARAMS_H

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022 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
@ -263,14 +263,14 @@ void TEARDROP_MANAGER::computeCurvedForRoundShape( TEARDROP_PARAMETERS* aCurrPar
// A and B are points on the track ( pts[0] and pts[1] )
// C and E are points on the aViaPad ( pts[2] and pts[4] )
// D is the aViaPad centre ( pts[3] )
double Vpercent = aCurrParams->m_heightRatio;
double Vpercent = aCurrParams->m_HeightRatio;
int td_height = aViaPad.m_Width * Vpercent;
// First, calculate a aVpercent equivalent to the td_height clamped by aTdMaxHeight
// We cannot use the initial aVpercent because it gives bad shape with points
// on aViaPad calculated for a clamped aViaPad size
if( aCurrParams->m_tdMaxHeight > 0 && aCurrParams->m_tdMaxHeight < td_height )
Vpercent *= (double)aCurrParams->m_tdMaxHeight / td_height;
if( aCurrParams->m_TdMaxHeight > 0 && aCurrParams->m_TdMaxHeight < td_height )
Vpercent *= (double)aCurrParams->m_TdMaxHeight / td_height;
int radius = aViaPad.m_Width / 2;
double minVpercent = double( aTrackHalfWidth ) / radius;
@ -290,9 +290,9 @@ void TEARDROP_MANAGER::computeCurvedForRoundShape( TEARDROP_PARAMETERS* aCurrPar
VECTOR2I tangentA = VECTOR2I( pts[0].x - aTrackDir.x * biasAE, pts[0].y - aTrackDir.y * biasAE );
std::vector<VECTOR2I> curve_pts;
curve_pts.reserve( aCurrParams->m_curveSegCount );
curve_pts.reserve( aCurrParams->m_CurveSegCount );
BEZIER_POLY( pts[1], tangentB, tangentC, pts[2] ).GetPoly( curve_pts, 0,
aCurrParams->m_curveSegCount );
aCurrParams->m_CurveSegCount );
for( VECTOR2I& corner: curve_pts )
aPoly.push_back( corner );
@ -301,7 +301,7 @@ void TEARDROP_MANAGER::computeCurvedForRoundShape( TEARDROP_PARAMETERS* aCurrPar
curve_pts.clear();
BEZIER_POLY( pts[4], tangentE, tangentA, pts[0] ).GetPoly( curve_pts, 0,
aCurrParams->m_curveSegCount );
aCurrParams->m_CurveSegCount );
for( VECTOR2I& corner: curve_pts )
aPoly.push_back( corner );
@ -328,7 +328,7 @@ void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrPar
VECTOR2I side2( aPts[4] - aPts[0] ); // vector from track to via
std::vector<VECTOR2I> curve_pts;
curve_pts.reserve( aCurrParams->m_curveSegCount );
curve_pts.reserve( aCurrParams->m_CurveSegCount );
// Note: This side is from track to via
VECTOR2I ctrl1 = ( aPts[1] + aPts[1] + aPts[2] ) / 3;
@ -360,7 +360,7 @@ void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrPar
ctrl2.y += bias.y;
BEZIER_POLY( aPts[1], ctrl1, ctrl2, aPts[2] ).GetPoly( curve_pts, 0,
aCurrParams->m_curveSegCount );
aCurrParams->m_CurveSegCount );
for( VECTOR2I& corner: curve_pts )
aPoly.push_back( corner );
@ -388,7 +388,7 @@ void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrPar
ctrl2.y += bias.y;
BEZIER_POLY( aPts[4], ctrl1, ctrl2, aPts[0] ).GetPoly( curve_pts, 0,
aCurrParams->m_curveSegCount );
aCurrParams->m_CurveSegCount );
for( VECTOR2I& corner: curve_pts )
aPoly.push_back( corner );
@ -410,17 +410,17 @@ bool TEARDROP_MANAGER::ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
// For rectangular (and similar) shapes, the preferred_height is calculated from the min
// dim of the rectangle = aViaPad.m_Width
int preferred_height = aViaPad.m_Width * aCurrParams->m_heightRatio;
int preferred_height = aViaPad.m_Width * aCurrParams->m_HeightRatio;
// force_clip_shape = true to force the via/pad polygon to be clipped to follow
// contraints
// Clipping is also needed for rectangular shapes, because the teardrop shape is
// restricted to a polygonal area smaller than the pad area (the teardrop height
// use the smaller value of X and Y sizes).
bool force_clip_shape = aCurrParams->m_heightRatio < 1.0;
bool force_clip_shape = aCurrParams->m_HeightRatio < 1.0;
// To find the anchor points on via/pad shape, we build the polygonal shape, and clip the polygon
// to the max size (preferred_height or m_tdMaxHeight) by a rectangle centered on the
// to the max size (preferred_height or m_TdMaxHeight) by a rectangle centered on the
// axis of the expected teardrop shape.
// (only reduce the size of polygonal shape does not give good anchor points)
if( aViaPad.m_IsRound )
@ -433,18 +433,18 @@ bool TEARDROP_MANAGER::ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
wxASSERT( pad );
force_clip_shape = true;
preferred_height = aViaPad.m_Width * aCurrParams->m_heightRatio;
preferred_height = aViaPad.m_Width * aCurrParams->m_HeightRatio;
pad->TransformShapeWithClearanceToPolygon( c_buffer, aTrack->GetLayer(), 0,
ARC_LOW_DEF, ERROR_INSIDE );
}
// Clip the pad/via shape to match the m_tdMaxHeight constraint, and for
// Clip the pad/via shape to match the m_TdMaxHeight constraint, and for
// not rounded pad, clip the shape at the aViaPad.m_Width, i.e. the value
// of the smallest value between size.x and size.y values.
if( force_clip_shape || ( aCurrParams->m_tdMaxHeight > 0
&& aCurrParams->m_tdMaxHeight < preferred_height ) )
if( force_clip_shape || ( aCurrParams->m_TdMaxHeight > 0
&& aCurrParams->m_TdMaxHeight < preferred_height ) )
{
int halfsize = std::min( aCurrParams->m_tdMaxHeight, preferred_height )/2;
int halfsize = std::min( aCurrParams->m_TdMaxHeight, preferred_height )/2;
// teardrop_axis is the line from anchor point on the track and the end point
// of the teardrop in the pad/via
@ -457,7 +457,7 @@ bool TEARDROP_MANAGER::ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
// Build the constraint polygon: a rectangle with
// length = dist between the point on track and the pad/via pos
// height = m_tdMaxHeight or aViaPad.m_Width
// height = m_TdMaxHeight or aViaPad.m_Width
SHAPE_POLY_SET clipping_rect;
clipping_rect.NewOutline();
@ -592,10 +592,10 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
int radius = aViaPad.m_Width / 2;
// Requested length of the teardrop:
int targetLength = aViaPad.m_Width * aCurrParams->m_lengthRatio;
int targetLength = aViaPad.m_Width * aCurrParams->m_LengthRatio;
if( aCurrParams->m_tdMaxLen > 0 )
targetLength = std::min( aCurrParams->m_tdMaxLen, targetLength );
if( aCurrParams->m_TdMaxLen > 0 )
targetLength = std::min( aCurrParams->m_TdMaxLen, targetLength );
int actualTdLen; // The actual teardrop length, limited by the available track length
@ -738,10 +738,10 @@ bool TEARDROP_MANAGER::computeTeardropPolygonPoints( TEARDROP_PARAMETERS* aCurrP
}
else
{
int td_height = aViaPad.m_Width * aCurrParams->m_heightRatio;
int td_height = aViaPad.m_Width * aCurrParams->m_HeightRatio;
if( aCurrParams->m_tdMaxHeight > 0 && aCurrParams->m_tdMaxHeight < td_height )
td_height = aCurrParams->m_tdMaxHeight;
if( aCurrParams->m_TdMaxHeight > 0 && aCurrParams->m_TdMaxHeight < td_height )
td_height = aCurrParams->m_TdMaxHeight;
computeCurvedForRectShape( aCurrParams, aCorners, td_height, track_halfwidth,
aViaPad, pts );