KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_global_edit_teardrops.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <algorithm>
25
26#include <widgets/unit_binder.h>
27#include <pcb_edit_frame.h>
28#include <board.h>
30#include <pcb_track.h>
31#include <pcb_group.h>
32#include <footprint.h>
33#include <teardrop/teardrop.h>
34#include <zone_filler.h>
37#include <tool/tool_manager.h>
40
41// Globals to remember filters during a session
42static wxString g_netclassFilter;
43static wxString g_netFilter;
44
45
47{
48public:
51
52protected:
53 void onSpecifiedValuesUpdateUi( wxUpdateUIEvent& event ) override
54 {
55 event.Enable( m_specifiedValues->GetValue() );
56 }
57 void onFilterUpdateUi( wxUpdateUIEvent& event ) override
58 {
59 event.Enable( !m_trackToTrack->GetValue() );
60 }
61
62 // Track-to-track teardrops always follow the document-wide settings (there are no teardrop
63 // properties on individual track segments as they're too ephemeral). Therefore we disable
64 // Set-to-specified-values when track-to-track is selected.
65 void onTrackToTrack( wxCommandEvent& event ) override
66 {
67 if( event.IsChecked() && m_specifiedValues->GetValue() )
68 {
69 m_specifiedValues->SetValue( false );
70 m_addTeardrops->SetValue( true );
71 }
72 }
73
74 // These just improve usability so that you don't have to click twice to enable a filter.
75 void OnNetclassFilterSelect( wxCommandEvent& event ) override
76 {
77 m_netclassFilterOpt->SetValue( true );
78 }
79 void OnLayerFilterSelect( wxCommandEvent& event ) override
80 {
81 m_layerFilterOpt->SetValue( true );
82 }
83 void OnNetFilterSelect( wxCommandEvent& event )
84 {
85 m_netFilterOpt->SetValue( true );
86 }
87
88 // Remove "add" terminology when updating only existing teardrops.
89 void OnExistingFilterSelect( wxCommandEvent& event ) override
90 {
91 if( event.IsChecked() )
92 {
93 m_addTeardrops->SetLabel( _( "Set teardrops to default values for shape" ) );
94 m_specifiedValues->SetLabel( _( "Set teardrops to specified values:" ) );
95 }
96 else
97 {
98 m_addTeardrops->SetLabel( _( "Add teardrops with default values for shape" ) );
99 m_specifiedValues->SetLabel( _( "Add teardrops with specified values:" ) );
100 }
101 }
102
103 void setSpecifiedParams( TEARDROP_PARAMETERS* targetParams );
104 void visitItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem,bool aSelectAlways );
105 void processItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem );
106
107 bool TransferDataToWindow() override;
108 bool TransferDataFromWindow() override;
109
110
111 void onShowBoardSetup( wxHyperlinkEvent& event ) override
112 {
113 m_parent->ShowBoardSetupDialog( _( "Teardrops" ) );
114 }
115
116 void buildFilterLists();
117
118private:
122
128};
129
130
133 m_teardropHDPercent( aParent, m_stHDRatio, m_tcHDRatio, m_stHDRatioUnits ),
134 m_teardropLenPercent( aParent, m_stLenPercentLabel, m_tcLenPercent, nullptr ),
135 m_teardropMaxLen( aParent, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
136 m_teardropHeightPercent( aParent, m_stHeightPercentLabel, m_tcHeightPercent, nullptr ),
137 m_teardropMaxHeight( aParent, m_stMaxHeight, m_tcMaxHeight, m_stMaxHeightUnits )
138{
139 m_parent = aParent;
141
142 m_bitmapTeardrop->SetBitmap( KiBitmapBundle( BITMAPS::teardrop_sizes ) );
143
144 m_teardropHDPercent.SetUnits( EDA_UNITS::PERCENT );
145 m_teardropLenPercent.SetUnits( EDA_UNITS::PERCENT );
146 m_teardropHeightPercent.SetUnits( EDA_UNITS::PERCENT );
147
148 m_minTrackWidthHint->SetFont( KIUI::GetStatusFont( this ).Italic() );
149
151
152 SetupStandardButtons( { { wxID_OK, _( "Apply and Close" ) },
153 { wxID_CANCEL, _( "Close" ) } } );
154
155 m_netFilter->Connect( FILTERED_ITEM_SELECTED,
157 nullptr, this );
158
160}
161
162
164{
165 g_netclassFilter = m_netclassFilter->GetStringSelection();
167
168 m_netFilter->Disconnect( FILTERED_ITEM_SELECTED,
170 nullptr, this );
171}
172
173
175{
176 // Populate the net filter list with net names
178
179 if( !m_brd->GetHighLightNetCodes().empty() )
181
182 // Populate the netclass filter list with netclass names
183 wxArrayString netclassNames;
184 std::shared_ptr<NET_SETTINGS>& settings = m_brd->GetDesignSettings().m_NetSettings;
185
186 netclassNames.push_back( settings->GetDefaultNetclass()->GetName() );
187
188 for( const auto& [name, netclass] : settings->GetNetclasses() )
189 netclassNames.push_back( name );
190
191 m_netclassFilter->Set( netclassNames );
193
194 // Populate the layer filter list
200}
201
202
204{
206
211
212 m_netclassFilter->SetStringSelection( g_netclassFilter );
214
215 m_cbPreferZoneConnection->Set3StateValue( wxCHK_UNDETERMINED );
216 m_cbTeardropsUseNextTrack->Set3StateValue( wxCHK_UNDETERMINED );
222 m_curvedEdges->Set3StateValue( wxCHK_UNDETERMINED );
223
224 return true;
225}
226
227
229{
230 if( m_cbPreferZoneConnection->Get3StateValue() != wxCHK_UNDETERMINED )
231 targetParams->m_TdOnPadsInZones = !m_cbPreferZoneConnection->GetValue();
232
233 if( m_cbTeardropsUseNextTrack->Get3StateValue() != wxCHK_UNDETERMINED )
234 targetParams->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
235
238
240 targetParams->m_BestLengthRatio = m_teardropLenPercent.GetDoubleValue() / 100.0;
241
243 targetParams->m_TdMaxLen = m_teardropMaxLen.GetIntValue();
244
247
250
251 if( m_curvedEdges->Get3StateValue() != wxCHK_UNDETERMINED )
252 targetParams->m_CurvedEdges = m_curvedEdges->GetValue();
253}
254
255
257{
259 TEARDROP_PARAMETERS* targetParams = nullptr;
260
261 if( aItem->Type() == PCB_PAD_T )
262 targetParams = &static_cast<PAD*>( aItem )->GetTeardropParams();
263 else if( aItem->Type() == PCB_VIA_T )
264 targetParams = &static_cast<PCB_VIA*>( aItem )->GetTeardropParams();
265 else
266 return;
267
268 aCommit->Stage( aItem, CHT_MODIFY );
269
270 if( m_removeTeardrops->GetValue() || m_removeAllTeardrops->GetValue() )
271 {
272 targetParams->m_Enabled = false;
273 }
274 else if( m_addTeardrops->GetValue() )
275 {
276 // NOTE: This ignores possible padstack shape variation.
278 *targetParams = *brdSettings.GetTeadropParamsList()->GetParameters( TARGET_ROUND );
279 else
280 *targetParams = *brdSettings.GetTeadropParamsList()->GetParameters( TARGET_RECT );
281
282 targetParams->m_Enabled = true;
283 }
284 else if( m_specifiedValues->GetValue() )
285 {
286 setSpecifiedParams( targetParams );
287
288 if( !m_existingFilter->GetValue() )
289 targetParams->m_Enabled = true;
290 }
291}
292
293
295 bool aSelectAlways )
296{
297 if( m_selectedItemsFilter->GetValue() )
298 {
299 if( !aItem->IsSelected() )
300 {
301 EDA_GROUP* group = aItem->GetParentGroup();
302
303 while( group && !group->AsEdaItem()->IsSelected() )
304 group = group->AsEdaItem()->GetParentGroup();
305
306 if( !group )
307 return;
308 }
309 }
310
311 if( aSelectAlways )
312 {
313 processItem( aCommit, aItem );
314 return;
315 }
316
317
318 if( m_netFilterOpt->GetValue() && m_netFilter->GetSelectedNetcode() >= 0 )
319 {
320 if( aItem->GetNetCode() != m_netFilter->GetSelectedNetcode() )
321 return;
322 }
323
324 if( m_netclassFilterOpt->GetValue() && !m_netclassFilter->GetStringSelection().IsEmpty() )
325 {
326 wxString filterNetclass = m_netclassFilter->GetStringSelection();
327 NETCLASS* netclass = aItem->GetEffectiveNetClass();
328
329 if( !netclass->ContainsNetclassWithName( filterNetclass ) )
330 return;
331 }
332
334 {
335 if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
336 return;
337 }
338
339 if( m_roundPadsFilter->GetValue() )
340 {
341 // TODO(JE) padstacks -- teardrops needs to support per-layer pad handling
343 return;
344 }
345
346 if( m_existingFilter->GetValue() )
347 {
348 if( aItem->Type() == PCB_PAD_T )
349 {
350 if( !static_cast<PAD*>( aItem )->GetTeardropParams().m_Enabled )
351 return;
352 }
353 else if( aItem->Type() == PCB_VIA_T )
354 {
355 if( !static_cast<PCB_VIA*>( aItem )->GetTeardropParams().m_Enabled )
356 return;
357 }
358 }
359
360 processItem( aCommit, aItem );
361}
362
363
365{
366 m_brd->SetLegacyTeardrops( false );
367
368 BOARD_COMMIT commit( m_parent );
369 wxBusyCursor dummy;
370
371 // Save some dialog options
373
374 bds.m_TeardropParamsList.m_TargetVias = m_vias->GetValue();
379
380 bool remove_all = m_removeAllTeardrops->GetValue();
381
382 if( m_vias->GetValue() || remove_all )
383 {
384 for( PCB_TRACK* track : m_brd->Tracks() )
385 {
386 if ( track->Type() == PCB_VIA_T )
387 visitItem( &commit, track, remove_all );
388 }
389 }
390
391 for( FOOTPRINT* footprint : m_brd->Footprints() )
392 {
393 for( PAD* pad : footprint->Pads() )
394 {
395 if( remove_all )
396 {
397 visitItem( &commit, pad, true );
398 continue;
399 }
400
401 if( m_pthPads->GetValue() && pad->GetAttribute() == PAD_ATTRIB::PTH )
402 {
403 visitItem( &commit, pad, false );
404 }
405 else if( m_smdPads->GetValue() && ( pad->GetAttribute() == PAD_ATTRIB::SMD
406 || pad->GetAttribute() == PAD_ATTRIB::CONN ) )
407 {
408 visitItem( &commit, pad, false );
409 }
410 }
411 }
412
413 if( m_trackToTrack->GetValue() )
414 {
416 TEARDROP_PARAMETERS* targetParams = paramsList->GetParameters( TARGET_TRACK );
417 TEARDROP_MANAGER teardropManager( m_brd, m_parent->GetToolManager() );
418
419 teardropManager.DeleteTrackToTrackTeardrops( commit );
420
421 if( m_removeTeardrops->GetValue() || m_removeAllTeardrops->GetValue() )
422 {
423 targetParams->m_Enabled = false; // JEY TODO: how does this get undone/redone?
424 }
425 else if( m_addTeardrops->GetValue() )
426 {
427 targetParams->m_Enabled = true; // JEY TODO: how does this get undone/redone?
428 teardropManager.AddTeardropsOnTracks( commit, nullptr, true );
429 }
430 }
431
432 // If there are no filters then a force-full-update is equivalent, and will be faster.
433 if( !m_netFilterOpt->GetValue()
434 && !m_netclassFilterOpt->GetValue()
435 && !m_layerFilterOpt->GetValue()
436 && !m_roundPadsFilter->GetValue()
437 && !m_existingFilter->GetValue()
438 && !m_selectedItemsFilter->GetValue() )
439 {
440 commit.Push( _( "Edit Teardrops" ), SKIP_TEARDROPS );
441
443 teardropMgr.UpdateTeardrops( commit, nullptr, nullptr, true /* forceFullUpdate */ );
444 commit.Push( _( "Edit Teardrops" ), SKIP_TEARDROPS | APPEND_UNDO );
445 }
446 else
447 {
448 commit.Push( _( "Edit Teardrops" ) );
449 }
450
451 // Showing the unfilled, fully cross-hatched teardrops seems to be working fairly well, and
452 // accurate fills can then be manually generated by doing a zone fill.
453 //
454 // But here's the old code which allowed for either "draft" fills or an automatic full zone
455 // fill in case we decide the current situation isn't good enough:
456#if 0
457 if( aFillAfter )
458 {
459 ZONE_FILLER filler( m_board, aCommit );
460
461 if( m_reporter )
462 filler.SetProgressReporter( m_reporter );
463
464 filler.Fill( m_board->Zones() );
465
466 if( aCommit )
467 aCommit->Push( _( "Edit Teardrops" ), APPEND_UNDO );
468 }
469 else
470 {
471 // Fill raw teardrop shapes. This is a rough calculation, just to show a filled
472 // shape on screen without the (potentially large) performance hit of a zone refill
473 int epsilon = pcbIUScale.mmToIU( 0.001 );
474 int allowed_error = pcbIUScale.mmToIU( 0.005 );
475
476 for( ZONE* zone: m_createdTdList )
477 {
478 int half_min_width = zone->GetMinThickness() / 2;
479 int numSegs = GetArcToSegmentCount( half_min_width, allowed_error, FULL_CIRCLE );
480 SHAPE_POLY_SET filledPolys = *zone->Outline();
481
482 filledPolys.Deflate( half_min_width - epsilon, numSegs );
483
484 // Re-inflate after pruning of areas that don't meet minimum-width criteria
485 if( half_min_width - epsilon > epsilon )
486 filledPolys.Inflate( half_min_width - epsilon, numSegs );
487
488 zone->SetFilledPolysList( zone->GetFirstLayer(), filledPolys );
489 }
490 }
491#endif
492
493 m_parent->Refresh();
494 return true;
495}
496
497
499{
500 PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
501 DIALOG_GLOBAL_EDIT_TEARDROPS dlg( editFrame );
502
503 dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
504 return 0;
505}
506
const char * name
Definition: DXF_plotter.cpp:62
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:112
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition: bitmap.cpp:110
#define SKIP_TEARDROPS
Definition: board_commit.h:46
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE) override
Add a change of the item aItem of type aChangeType to the change list.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual NETCLASS * GetEffectiveNetClass() const
Return the NETCLASS for this item.
TEARDROP_PARAMETERS & GetTeardropParams()
Container for design settings for a BOARD object.
TEARDROP_PARAMETERS_LIST * GetTeadropParamsList()
std::shared_ptr< NET_SETTINGS > m_NetSettings
const wxString & GetCurrentNetClassName() const
TEARDROP_PARAMETERS_LIST m_TeardropParamsList
The parameters of teardrops for the different teardrop targets (via/pad, track end).
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:232
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:934
const std::set< int > & GetHighLightNetCodes() const
Definition: board.h:579
const FOOTPRINTS & Footprints() const
Definition: board.h:358
const TRACKS & Tracks() const
Definition: board.h:356
void SetLegacyTeardrops(bool aFlag)
Definition: board.h:1320
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:1024
Class DIALOG_GLOBAL_EDIT_TEARDROPS_BASE.
void processItem(BOARD_COMMIT *aCommit, BOARD_CONNECTED_ITEM *aItem)
void visitItem(BOARD_COMMIT *aCommit, BOARD_CONNECTED_ITEM *aItem, bool aSelectAlways)
void OnNetFilterSelect(wxCommandEvent &event)
void setSpecifiedParams(TEARDROP_PARAMETERS *targetParams)
void OnNetclassFilterSelect(wxCommandEvent &event) override
DIALOG_GLOBAL_EDIT_TEARDROPS(PCB_EDIT_FRAME *aParent)
void onTrackToTrack(wxCommandEvent &event) override
void onSpecifiedValuesUpdateUi(wxUpdateUIEvent &event) override
void OnExistingFilterSelect(wxCommandEvent &event) override
void onShowBoardSetup(wxHyperlinkEvent &event) override
void onFilterUpdateUi(wxUpdateUIEvent &event) override
void OnLayerFilterSelect(wxCommandEvent &event) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowQuasiModal()
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
A set of EDA_ITEMs (i.e., without duplicates).
Definition: eda_group.h:46
virtual EDA_GROUP * GetParentGroup() const
Definition: eda_item.h:116
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
bool IsSelected() const
Definition: eda_item.h:127
int EditTeardrops(const TOOL_EVENT &aEvent)
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:610
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:45
bool ContainsNetclassWithName(const wxString &netclass) const
Determines if the given netclass name is a constituent of this (maybe aggregate) netclass.
Definition: netclass.cpp:278
void SetNetInfo(const NETINFO_LIST *aNetInfoList)
int GetSelectedNetcode()
void SetSelectedNetcode(int aNetcode)
void SetSelectedNet(const wxString &aNetname)
wxString GetSelectedNetname()
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition: padstack.h:145
Definition: pad.h:54
virtual PCB_LAYER_ID GetActiveLayer() const
BOARD * GetBoard() const
The main frame for Pcbnew.
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString)
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetNotAllowedLayerSet(const LSET &aMask)
Represent a set of closed polygons.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
void Deflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError)
TEARDROP_MANAGER manage and build teardrop areas A teardrop area is a polygonal area (a copper ZONE) ...
Definition: teardrop.h:95
static bool IsRound(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
void UpdateTeardrops(BOARD_COMMIT &aCommit, const std::vector< BOARD_ITEM * > *dirtyPadsAndVias, const std::set< PCB_TRACK * > *dirtyTracks, bool aForceFullUpdate=false)
Update teardrops on a list of items.
Definition: teardrop.cpp:180
void AddTeardropsOnTracks(BOARD_COMMIT &aCommit, const std::set< PCB_TRACK * > *aTracks, bool aForceFullUpdate=false)
Add teardrop on tracks of different sizes connected by their end.
Definition: teardrop.cpp:375
void DeleteTrackToTrackTeardrops(BOARD_COMMIT &aCommit)
Definition: teardrop.cpp:323
TEARDROP_PARAMETERS_LIST is a helper class to handle the list of TEARDROP_PARAMETERS needed to build ...
bool m_UseRoundShapesOnly
True to create teardrops for round shapes only.
bool m_TargetVias
True to create teardrops for vias.
bool m_TargetPTHPads
True to create teardrops for pads with holes.
bool m_TargetTrack2Track
True to create teardrops at the end of a track connected to the end of another track having a differe...
TEARDROP_PARAMETERS * GetParameters(TARGET_TD aTdType)
bool m_TargetSMDPads
True to create teardrops for pads SMD, edge connectors,.
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_TdOnPadsInZones
A filter to exclude pads inside zone fills.
bool m_Enabled
Flag to enable teardrops.
bool m_CurvedEdges
True if the teardrop should be curved.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Generic, UI-independent tool event.
Definition: tool_event.h:168
int GetIntValue()
Definition: unit_binder.h:134
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
virtual double GetDoubleValue()
Return the current value in Internal Units.
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
bool Fill(const std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
Handle a list of polygons defining a copper zone.
Definition: zone.h:74
@ CHT_MODIFY
Definition: commit.h:45
static wxString g_netclassFilter
static wxString g_netFilter
#define _(s)
static constexpr EDA_ANGLE FULL_CIRCLE
Definition: eda_angle.h:409
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
Definition: ui_common.cpp:132
Class to handle a set of BOARD_ITEMs.
const double epsilon
#define APPEND_UNDO
Definition: sch_commit.h:42
std::vector< FAB_LAYER_COLOR > dummy
constexpr int mmToIU(double mm) const
Definition: base_units.h:92
@ TARGET_ROUND
@ TARGET_RECT
@ TARGET_TRACK
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
#define INDETERMINATE_ACTION
Definition: ui_common.h:47