Add "generate raw teardrops" option to Add Teardrops dialog.

Fixes https://gitlab.com/kicad/code/kicad/issues/14711

Fixes https://gitlab.com/kicad/code/kicad/issues/14704
This commit is contained in:
Jeff Young 2023-05-11 15:46:58 +01:00
parent daa3a1aae9
commit 4da6d5ff28
6 changed files with 221 additions and 37 deletions

View File

@ -39,6 +39,8 @@
#define CURVED_OPTION_RECT 2 /* Curved teardrop shape for rect pad shapes */
#define CURVED_OPTION_TRACK 4 /* Curved teardrop shape for track to track shapes */
bool g_rawTeardrops = false;
class TEARDROP_DIALOG: public TEARDROP_DIALOG_BASE
{
public:
@ -58,6 +60,8 @@ public:
m_bitmapTdRectangularInfo->SetBitmap( KiBitmap( BITMAPS::teardrop_rect_sizes ) );
m_bitmapTdTrackInfo->SetBitmap( KiBitmap( BITMAPS::teardrop_track_sizes ) );
m_rawTeardropsHint->SetFont( KIUI::GetInfoFont( this ) );
m_brdSettings = &m_frame->GetBoard()->GetBoard()->GetDesignSettings();
TEARDROP_PARAMETERS_LIST* prmsList = m_brdSettings->GetTeadropParamsList();
@ -94,12 +98,16 @@ public:
m_rbShapeTrack->SetSelection( prms->IsCurved() );
m_spTeardropHDPercentTrack->SetValue( prms->m_WidthtoSizeFilterRatio*100 );
m_generateRawTeardrops->SetValue( g_rawTeardrops );
// recalculate sizers, now the bitmap is initialized
finishDialogSettings();
}
~TEARDROP_DIALOG()
{
g_rawTeardrops = m_generateRawTeardrops->GetValue();
TransferToParamList();
}
@ -189,6 +197,8 @@ public:
bool TeardropOnTracks() { return m_cbTrack2Track->GetValue(); }
bool GenerateRawTeardrops() { return m_generateRawTeardrops->GetValue(); }
private:
BOARD_DESIGN_SETTINGS* m_brdSettings;
PCB_EDIT_FRAME* m_frame;
@ -215,7 +225,8 @@ void PCB_EDIT_FRAME::OnRunTeardropTool( wxCommandEvent& event )
dlg.TransferToParamList();
TEARDROP_MANAGER trdm( GetBoard(), this );
int added_count = trdm.SetTeardrops( &committer, dlg.CanUseTwoTracks() );
int added_count = trdm.SetTeardrops( &committer, dlg.CanUseTwoTracks(),
!dlg.GenerateRawTeardrops() );
GetToolManager()->PostEvent( EVENTS::ConnectivityChangedEvent );

View File

@ -402,7 +402,22 @@ TEARDROP_DIALOG_BASE::TEARDROP_DIALOG_BASE( wxWindow* parent, wxWindowID id, con
bSizer6->Add( m_spPointCount, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
sbSizerOptions->Add( bSizer6, 1, wxEXPAND, 5 );
sbSizerOptions->Add( bSizer6, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_generateRawTeardrops = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Generate raw teardrops"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerOptions->Add( m_generateRawTeardrops, 0, wxRIGHT|wxLEFT, 5 );
sbSizerOptions->Add( 0, 2, 0, 0, 5 );
m_rawTeardropsHint = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("(Shapes will be adjusted for clearances on next zone fill.)"), wxDefaultPosition, wxDefaultSize, 0 );
m_rawTeardropsHint->Wrap( -1 );
m_rawTeardropsHint->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
sbSizerOptions->Add( m_rawTeardropsHint, 0, wxLEFT, 27 );
sbSizerOptions->Add( 0, 2, 0, 0, 5 );
bSizerShape->Add( sbSizerOptions, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );

View File

@ -4494,7 +4494,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
@ -4626,6 +4626,151 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxRIGHT|wxLEFT</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">Generate raw teardrops</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_generateRawTeardrops</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 class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="spacer" expanded="1">
<property name="height">2</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">27</property>
<property name="flag">wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font">,90,400,11,70,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">(Shapes will be adjusted for clearances on next zone fill.)</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_rawTeardropsHint</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="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="spacer" expanded="1">
<property name="height">2</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
</object>
</object>
</object>

View File

@ -112,6 +112,8 @@ class TEARDROP_DIALOG_BASE : public DIALOG_SHIM
wxCheckBox* m_cbPadsInZones;
wxStaticText* m_stPointCount;
wxSpinCtrl* m_spPointCount;
wxCheckBox* m_generateRawTeardrops;
wxStaticText* m_rawTeardropsHint;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;

View File

@ -48,6 +48,7 @@ TEARDROP_MANAGER::TEARDROP_MANAGER( BOARD* aBoard, PCB_EDIT_FRAME* aFrame )
m_board = aBoard;
m_prmsList = m_board->GetDesignSettings().GetTeadropParamsList();
m_tolerance = 0;
m_toolManager = aFrame->GetToolManager();
}
@ -55,7 +56,7 @@ TEARDROP_MANAGER::TEARDROP_MANAGER( BOARD* aBoard, PCB_EDIT_FRAME* aFrame )
static ZONE_SETTINGS s_default_settings; // Use zone default settings for teardrop
ZONE* TEARDROP_MANAGER::createTeardrop( TEARDROP_VARIANT aTeardropVariant,
std::vector<VECTOR2I>& aPoints, PCB_TRACK* aTrack) const
std::vector<VECTOR2I>& aPoints, PCB_TRACK* aTrack ) const
{
ZONE* teardrop = new ZONE( m_board );
@ -90,7 +91,7 @@ ZONE* TEARDROP_MANAGER::createTeardrop( TEARDROP_VARIANT aTeardropVariant,
}
int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks )
int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks, bool aFillAfter )
{
// Init parameters:
m_tolerance = pcbIUScale.mmToIU( 0.01 );
@ -162,7 +163,9 @@ int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks
// The track width must be < teardrop height
if( track->GetWidth() >= currParams->m_TdMaxHeight
|| track->GetWidth() >= viapad.m_Width * currParams->m_HeightRatio )
{
continue;
}
// Ensure also it is not filtered by a too high track->GetWidth()/viapad.m_Width ratio
if( track->GetWidth() >= viapad.m_Width * currParams->m_WidthtoSizeFilterRatio )
@ -199,29 +202,6 @@ int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks
// Now set priority of teardrops now all teardrops are added
setTeardropPriorities();
// Fill teardrop shapes. This is a rough calculation, just to show a filled
// shape on screen, but most of time this is a good shape.
// Exact shapes can be calculated only on a full zone refill, **much more** time consuming
if( m_createdTdList.size() )
{
int epsilon = pcbIUScale.mmToIU( 0.001 );
for( ZONE* zone: m_createdTdList )
{
int half_min_width = zone->GetMinThickness() / 2;
int numSegs = GetArcToSegmentCount( half_min_width, pcbIUScale.mmToIU( 0.005 ), FULL_CIRCLE );
SHAPE_POLY_SET filledPolys = *zone->Outline();
filledPolys.Deflate( half_min_width - epsilon, numSegs );
// Re-inflate after pruning of areas that don't meet minimum-width criteria
if( half_min_width - epsilon > epsilon )
filledPolys.Inflate( half_min_width - epsilon, numSegs );
zone->SetFilledPolysList( zone->GetFirstLayer(), filledPolys );
}
}
if( count || removed_cnt || track2trackCount )
{
if( aCommitter )
@ -230,6 +210,37 @@ int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks
// Note:
// Refill zones can be made only with clean data, especially connectivity data,
// therefore only after changes are pushed to avoid crashes in some cases
if( aFillAfter )
{
ZONE_FILLER filler( m_board, aCommitter );
filler.Fill( m_board->Zones() );
if( aCommitter )
aCommitter->Push( _( "Refill zones" ) );
}
else
{
// Fill raw teardrop shapes. This is a rough calculation, just to show a filled
// shape on screen without the (potentially large) performance hit of a zone refill
int epsilon = pcbIUScale.mmToIU( 0.001 );
int allowed_error = pcbIUScale.mmToIU( 0.005 );
for( ZONE* zone: m_createdTdList )
{
int half_min_width = zone->GetMinThickness() / 2;
int numSegs = GetArcToSegmentCount( half_min_width, allowed_error, FULL_CIRCLE );
SHAPE_POLY_SET filledPolys = *zone->Outline();
filledPolys.Deflate( half_min_width - epsilon, numSegs );
// Re-inflate after pruning of areas that don't meet minimum-width criteria
if( half_min_width - epsilon > epsilon )
filledPolys.Inflate( half_min_width - epsilon, numSegs );
zone->SetFilledPolysList( zone->GetFirstLayer(), filledPolys );
}
}
}
return count + track2trackCount;

View File

@ -95,10 +95,9 @@ public:
* @param aCommitter is a BOARD_COMMIT reference (can be null)
* @param aFollowTracks = true to use a track connected to the initial track connected
* to a pad / via if this initial track is too short to build the teardrop
* @param aFillAfter = true to performa zone fill at end
*/
int SetTeardrops( BOARD_COMMIT* aCommitter,
bool aFollowTracks = true );
int SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks, bool aFillAfter );
/**
* Remove all teardrops
@ -108,7 +107,7 @@ public:
* false if some other changes must be made and the actual commit postponed
* Can be nullptr
*/
int RemoveTeardrops( BOARD_COMMIT* aCommitter, bool aCommitAfterRemove );
int RemoveTeardrops( BOARD_COMMIT* aCommitter, bool aCommitAfterRemove );
private:
@ -244,11 +243,12 @@ private:
bool aFollowTracks, TRACK_BUFFER& aTrackLookupList ) const;
private:
int m_tolerance; // max distance between a track end point and a pad/via center to
// see them connected to ut a teardrop
BOARD* m_board;
TEARDROP_PARAMETERS_LIST* m_prmsList; // the teardrop parameters list, from the board design settings
std::vector<ZONE*> m_createdTdList; // list of new created teardrops
int m_tolerance; // max dist between track end point and pad/via
// center to see them connected to ut a teardrop
BOARD* m_board;
TOOL_MANAGER* m_toolManager;
TEARDROP_PARAMETERS_LIST* m_prmsList; // the teardrop parameters list, from the board design settings
std::vector<ZONE*> m_createdTdList; // list of new created teardrops
};