mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-19 17:51:41 +00:00
Make pad & via teardrops 1st-class citizens (props of the pad/via)
Change teardrop generation to rely more heavily on BOARD_CONNECTIVITY for improved performance. Add updating of teardrops on BOARD_COMMIT::Push(). Also converts m_CopperItemRTreeCache to std::shared_ptr. We don't copy it around anyway, and having to create a new set of std::unique_ptr's for each operation is likely to be more expensive than std::shared_ptr's overhead.
This commit is contained in:
parent
329025f8a7
commit
8b1fd62d35
common
eeschema/dialogs
dialog_global_edit_text_and_graphics_base.cppdialog_global_edit_text_and_graphics_base.fbpdialog_wire_bus_properties.cpppanel_eeschema_editing_options.cpp
include
pcbnew
CMakeLists.txtboard.cppboard.hboard_commit.cppboard_commit.hboard_connected_item.cppboard_connected_item.hboard_design_settings.cpp
connectivity
dialogs
dialog_board_setup.cppdialog_board_setup.hdialog_copper_zones.cppdialog_global_edit_teardrops.cppdialog_global_edit_teardrops_base.cppdialog_global_edit_teardrops_base.fbpdialog_global_edit_teardrops_base.hdialog_global_edit_text_and_graphics_base.cppdialog_global_edit_text_and_graphics_base.fbpdialog_global_edit_tracks_and_vias.cppdialog_global_edit_tracks_and_vias_base.cppdialog_global_edit_tracks_and_vias_base.fbpdialog_import_settings_base.cppdialog_import_settings_base.fbpdialog_import_settings_base.hdialog_pad_basicshapes_properties.cppdialog_pad_properties.cppdialog_pad_properties.hdialog_pad_properties_base.cppdialog_pad_properties_base.fbpdialog_pad_properties_base.hdialog_rule_area_properties.cppdialog_track_via_properties.cppdialog_track_via_properties.hdialog_track_via_properties_base.cppdialog_track_via_properties_base.fbpdialog_track_via_properties_base.hdialog_track_via_size.cpppanel_setup_constraints.cpppanel_setup_constraints.hpanel_setup_formatting.cpppanel_setup_teardrops.cpppanel_setup_teardrops.hpanel_setup_teardrops_base.cpppanel_setup_teardrops_base.fbppanel_setup_teardrops_base.h
drc
menubar_pcb_editor.cpppad.cpppad.hpcb_edit_frame.cpppcbnew_id.hplugins/kicad
router
teardrop
dialog_teardrop.cppdialog_teardrop_base.cppdialog_teardrop_base.fbpdialog_teardrop_base.hteardrop.cppteardrop.hteardrop_parameters.hteardrop_utils.cpp
tools
global_edit_tool.cppglobal_edit_tool.hpcb_actions.cpppcb_actions.hpcb_selection_tool.cppzone_filler_tool.cpp
zone.cpp@ -194,14 +194,31 @@ CHANGE_TYPE COMMIT::convert( UNDO_REDO aType ) const
|
||||
return CHT_REMOVE;
|
||||
|
||||
default:
|
||||
assert( false );
|
||||
// Can't fall through if the assert fires, so quiet our warning
|
||||
#ifdef NDEBUG
|
||||
wxASSERT( false );
|
||||
KI_FALLTHROUGH;
|
||||
#endif
|
||||
|
||||
case UNDO_REDO::CHANGED:
|
||||
return CHT_MODIFY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNDO_REDO COMMIT::convert( CHANGE_TYPE aType ) const
|
||||
{
|
||||
switch( aType )
|
||||
{
|
||||
case CHT_ADD:
|
||||
return UNDO_REDO::NEWITEM;
|
||||
|
||||
case CHT_REMOVE:
|
||||
return UNDO_REDO::DELETED;
|
||||
|
||||
default:
|
||||
wxASSERT( false );
|
||||
KI_FALLTHROUGH;
|
||||
|
||||
case CHT_MODIFY:
|
||||
return UNDO_REDO::CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
# This program source code file is part of KiCad, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2012 CERN.
|
||||
# Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2019-2023 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
|
||||
@ -31,6 +31,7 @@ allowed
|
||||
allow_missing_courtyard
|
||||
allow_soldermask_bridges
|
||||
allow_soldermask_bridges_in_footprints
|
||||
allow_two_segments
|
||||
anchor
|
||||
angle
|
||||
arc
|
||||
@ -46,6 +47,8 @@ attr
|
||||
autoplace_cost90
|
||||
autoplace_cost180
|
||||
aux_axis_origin
|
||||
best_length_ratio
|
||||
best_width_ratio
|
||||
bevelled
|
||||
blind
|
||||
blind_buried_vias_allowed
|
||||
@ -69,6 +72,7 @@ connect_pads
|
||||
copperpour
|
||||
copper_finish
|
||||
crossbar
|
||||
curve_points
|
||||
custom
|
||||
outline
|
||||
convexhull
|
||||
@ -96,6 +100,7 @@ edge_connector
|
||||
edge_plating
|
||||
edge_width
|
||||
effects
|
||||
enabled
|
||||
end
|
||||
epsilon_r
|
||||
exclude_from_pos_files
|
||||
@ -112,6 +117,7 @@ fill_segments
|
||||
filled_polygon
|
||||
filled_areas_thickness
|
||||
fillet
|
||||
filter_ratio
|
||||
font
|
||||
format
|
||||
footprint
|
||||
@ -171,12 +177,15 @@ layers
|
||||
leader
|
||||
leader_length
|
||||
left
|
||||
legacy_teardrops
|
||||
linear
|
||||
line_spacing
|
||||
links
|
||||
locked
|
||||
loss_tangent
|
||||
max_error
|
||||
max_length
|
||||
max_width
|
||||
material
|
||||
members
|
||||
micro
|
||||
@ -223,6 +232,7 @@ pad_prop_castellated
|
||||
pad_prop_testpoint
|
||||
pad_prop_heatsink
|
||||
padvia
|
||||
prefer_zone_connections
|
||||
private_layers
|
||||
property
|
||||
page
|
||||
@ -281,6 +291,7 @@ target
|
||||
title
|
||||
title_block
|
||||
teardrop
|
||||
teardrops
|
||||
tedit
|
||||
text_frame
|
||||
text_position_mode
|
||||
|
@ -171,7 +171,7 @@ void UNIT_BINDER::onUnitsChanged( wxCommandEvent& aEvent )
|
||||
&& m_units != EDA_UNITS::DEGREES
|
||||
&& m_units != EDA_UNITS::PERCENT )
|
||||
{
|
||||
int temp = (int) GetValue();
|
||||
int temp = GetIntValue();
|
||||
|
||||
SetUnits( provider->GetUserUnits() );
|
||||
m_iuScale = &provider->GetIuScale();
|
||||
|
@ -137,7 +137,7 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_BASE::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_
|
||||
|
||||
fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_selectedFilterOpt = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Only include selected items"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_selectedFilterOpt = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Selected items only"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer2->Add( m_selectedFilterOpt, 0, wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
|
@ -1712,7 +1712,7 @@
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Only include selected items</property>
|
||||
<property name="label">Selected items only</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
@ -187,7 +187,7 @@ bool DIALOG_WIRE_BUS_PROPERTIES::TransferDataFromWindow()
|
||||
{
|
||||
if( !m_wireWidth.IsIndeterminate() )
|
||||
{
|
||||
int width = std::max( (long long int) 0, m_wireWidth.GetValue() );
|
||||
int width = std::max( 0, m_wireWidth.GetIntValue() );
|
||||
|
||||
if( item->Type() == SCH_LINE_T )
|
||||
static_cast<SCH_LINE*>( item )->SetLineWidth( width );
|
||||
|
@ -107,8 +107,8 @@ bool PANEL_EESCHEMA_EDITING_OPTIONS::TransferDataFromWindow()
|
||||
cfg->m_Drawing.default_sheet_border_color = m_borderColorSwatch->GetSwatchColor();
|
||||
cfg->m_Drawing.default_sheet_background_color = m_backgroundColorSwatch->GetSwatchColor();
|
||||
|
||||
cfg->m_Drawing.default_repeat_offset_x = schIUScale.IUToMils( (int) m_hPitch.GetValue() );
|
||||
cfg->m_Drawing.default_repeat_offset_y = schIUScale.IUToMils( (int) m_vPitch.GetValue() );
|
||||
cfg->m_Drawing.default_repeat_offset_x = schIUScale.IUToMils( m_hPitch.GetIntValue() );
|
||||
cfg->m_Drawing.default_repeat_offset_y = schIUScale.IUToMils( m_vPitch.GetIntValue() );
|
||||
cfg->m_Drawing.repeat_label_increment = m_spinLabelRepeatStep->GetValue();
|
||||
|
||||
cfg->m_Drawing.line_mode = m_choiceLineMode->GetSelection();
|
||||
|
@ -182,8 +182,10 @@ protected:
|
||||
virtual EDA_ITEM* makeImage( EDA_ITEM* aItem ) const = 0;
|
||||
|
||||
CHANGE_TYPE convert( UNDO_REDO aType ) const;
|
||||
UNDO_REDO convert( CHANGE_TYPE aType ) const;
|
||||
|
||||
std::set<EDA_ITEM*> m_changedItems;
|
||||
protected:
|
||||
std::set<EDA_ITEM*> m_changedItems;
|
||||
std::vector<COMMIT_LINE> m_changes;
|
||||
};
|
||||
|
||||
|
@ -124,6 +124,8 @@ public:
|
||||
*/
|
||||
virtual long long int GetValue();
|
||||
|
||||
int GetIntValue() { return (int) GetValue(); }
|
||||
|
||||
/**
|
||||
* Return the current value in Internal Units.
|
||||
*
|
||||
|
@ -30,8 +30,6 @@ include_directories(
|
||||
)
|
||||
|
||||
set( PCBNEW_DIALOGS
|
||||
teardrop/dialog_teardrop_base.cpp
|
||||
teardrop/dialog_teardrop.cpp
|
||||
dialogs/dialog_filter_selection.cpp
|
||||
dialogs/dialog_filter_selection_base.cpp
|
||||
dialogs/dialog_board_setup.cpp
|
||||
@ -88,6 +86,8 @@ set( PCBNEW_DIALOGS
|
||||
dialogs/dialog_global_deletion_base.cpp
|
||||
dialogs/dialog_global_edit_tracks_and_vias.cpp
|
||||
dialogs/dialog_global_edit_tracks_and_vias_base.cpp
|
||||
dialogs/dialog_global_edit_teardrops.cpp
|
||||
dialogs/dialog_global_edit_teardrops_base.cpp
|
||||
dialogs/dialog_global_edit_text_and_graphics.cpp
|
||||
dialogs/dialog_global_edit_text_and_graphics_base.cpp
|
||||
dialogs/dialog_global_fp_lib_table_config.cpp
|
||||
@ -171,6 +171,8 @@ set( PCBNEW_DIALOGS
|
||||
dialogs/panel_setup_layers_base.cpp
|
||||
dialogs/panel_setup_rules.cpp
|
||||
dialogs/panel_setup_rules_base.cpp
|
||||
dialogs/panel_setup_teardrops.cpp
|
||||
dialogs/panel_setup_teardrops_base.cpp
|
||||
dialogs/panel_setup_text_and_graphics.cpp
|
||||
dialogs/panel_setup_text_and_graphics_base.cpp
|
||||
dialogs/panel_setup_tracks_and_vias.cpp
|
||||
@ -354,6 +356,7 @@ set( PCBNEW_CLASS_SRCS
|
||||
tools/zone_create_helper.cpp
|
||||
tools/zone_filler_tool.cpp
|
||||
teardrop/teardrop.cpp
|
||||
teardrop/teardrop_parameters.cpp
|
||||
teardrop/teardrop_utils.cpp
|
||||
|
||||
footprint_preview_panel.cpp
|
||||
|
@ -244,7 +244,8 @@ void BOARD::IncrementTimeStamp()
|
||||
|| !m_IntersectsFCourtyardCache.empty()
|
||||
|| !m_IntersectsBCourtyardCache.empty()
|
||||
|| !m_LayerExpressionCache.empty()
|
||||
|| !m_ZoneBBoxCache.empty() )
|
||||
|| !m_ZoneBBoxCache.empty()
|
||||
|| m_CopperItemRTreeCache )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
|
||||
|
||||
@ -257,6 +258,8 @@ void BOARD::IncrementTimeStamp()
|
||||
|
||||
m_ZoneBBoxCache.clear();
|
||||
|
||||
m_CopperItemRTreeCache = nullptr;
|
||||
|
||||
// These are always regenerated before use, but still probably safer to clear them
|
||||
// while we're here.
|
||||
m_DRCMaxClearance = 0;
|
||||
@ -265,12 +268,6 @@ void BOARD::IncrementTimeStamp()
|
||||
m_DRCCopperZones.clear();
|
||||
m_ZoneIsolatedIslandsMap.clear();
|
||||
m_CopperZoneRTreeCache.clear();
|
||||
m_CopperItemRTreeCache = std::make_unique<DRC_RTREE>();
|
||||
}
|
||||
else if( !m_CopperItemRTreeCache )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
|
||||
m_CopperItemRTreeCache = std::make_unique<DRC_RTREE>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1156,6 +1156,9 @@ public:
|
||||
*/
|
||||
GroupLegalOpsField GroupLegalOps( const PCB_SELECTION& selection ) const;
|
||||
|
||||
bool LegacyTeardrops() const { return m_legacyTeardrops; }
|
||||
void SetLegacyTeardrops( bool aFlag ) { m_legacyTeardrops = aFlag; }
|
||||
|
||||
// --------- Item order comparators ---------
|
||||
|
||||
struct cmp_items
|
||||
@ -1177,7 +1180,7 @@ public:
|
||||
std::unordered_map<PTR_PTR_LAYER_CACHE_KEY, bool> m_EnclosedByAreaCache;
|
||||
std::unordered_map< wxString, LSET > m_LayerExpressionCache;
|
||||
std::unordered_map<ZONE*, std::unique_ptr<DRC_RTREE>> m_CopperZoneRTreeCache;
|
||||
std::unique_ptr<DRC_RTREE> m_CopperItemRTreeCache;
|
||||
std::shared_ptr<DRC_RTREE> m_CopperItemRTreeCache;
|
||||
mutable std::unordered_map<const ZONE*, BOX2I> m_ZoneBBoxCache;
|
||||
|
||||
// ------------ DRC caches -------------
|
||||
@ -1249,6 +1252,12 @@ private:
|
||||
*/
|
||||
std::unique_ptr<BOARD_DESIGN_SETTINGS> m_designSettings;
|
||||
|
||||
/**
|
||||
* Teardrops in 7.0 were applied as a post-processing step (rather than from pad and via
|
||||
* properties). If this flag is set, then auto-teardrop-generation will be disabled.
|
||||
*/
|
||||
bool m_legacyTeardrops = false;
|
||||
|
||||
NETINFO_LIST m_NetInfo; // net info list (name, design constraints...
|
||||
|
||||
std::vector<BOARD_LISTENER*> m_listeners;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include <pcb_group.h>
|
||||
#include <pcb_track.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_selection_tool.h>
|
||||
#include <tools/zone_filler_tool.h>
|
||||
@ -35,6 +36,7 @@
|
||||
#include <tools/pcb_tool_base.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <teardrop/teardrop.h>
|
||||
|
||||
#include <functional>
|
||||
using namespace std::placeholders;
|
||||
@ -82,8 +84,9 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
|
||||
aItem->ClearFlags( IS_MODIFIED_CHILD );
|
||||
|
||||
// If aItem belongs a footprint, the full footprint will be saved because undo/redo does
|
||||
// not handle "sub items" modifications. This has implications for auto-zone-refill, so
|
||||
// we need to store a bit more information.
|
||||
// not handle "sub items" modifications. This has implications for some udpate mechanisms,
|
||||
// such as auto-zone-refill and teardrop regeneration, so we need to store a bit more
|
||||
// information.
|
||||
if( aChangeType == CHT_MODIFY )
|
||||
{
|
||||
if( aItem->Type() == PCB_FOOTPRINT_T )
|
||||
@ -93,9 +96,23 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
|
||||
{
|
||||
child->SetFlags( IS_MODIFIED_CHILD );
|
||||
} );
|
||||
|
||||
return COMMIT::Stage( aItem, aChangeType );
|
||||
}
|
||||
else if( aItem->GetParent() && aItem->GetParent()->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( aItem->GetParent() );
|
||||
bool parentFootprintStaged = alg::contains( m_changedItems, parentFootprint );
|
||||
|
||||
if( !parentFootprintStaged )
|
||||
{
|
||||
parentFootprint->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
child->ClearFlags( IS_MODIFIED_CHILD );
|
||||
} );
|
||||
}
|
||||
|
||||
if( aItem->Type() == PCB_GROUP_T )
|
||||
{
|
||||
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
|
||||
@ -109,7 +126,10 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
|
||||
aItem->SetFlags( IS_MODIFIED_CHILD );
|
||||
}
|
||||
|
||||
aItem = aItem->GetParent();
|
||||
if( !parentFootprintStaged )
|
||||
return COMMIT::Stage( parentFootprint, aChangeType );
|
||||
|
||||
return *this;
|
||||
}
|
||||
else if( aItem->Type() == PCB_GROUP_T )
|
||||
{
|
||||
@ -120,6 +140,8 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
|
||||
{
|
||||
COMMIT::Stage( child, aChangeType );
|
||||
} );
|
||||
|
||||
return COMMIT::Stage( aItem, aChangeType );
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,13 +149,15 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
|
||||
}
|
||||
|
||||
|
||||
COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType, BASE_SCREEN* aScreen )
|
||||
COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType,
|
||||
BASE_SCREEN* aScreen )
|
||||
{
|
||||
return COMMIT::Stage( container, aChangeType, aScreen );
|
||||
}
|
||||
|
||||
|
||||
COMMIT& BOARD_COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO aModFlag, BASE_SCREEN* aScreen )
|
||||
COMMIT& BOARD_COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO aModFlag,
|
||||
BASE_SCREEN* aScreen )
|
||||
{
|
||||
return COMMIT::Stage( aItems, aModFlag, aScreen );
|
||||
}
|
||||
@ -201,18 +225,23 @@ void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item, int aChangeType )
|
||||
|
||||
void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||
{
|
||||
// Objects potentially interested in changes:
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||
BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
|
||||
PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() );
|
||||
std::set<EDA_ITEM*> savedModules;
|
||||
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
|
||||
|
||||
// Notification info
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
std::set<EDA_ITEM*> savedModules;
|
||||
bool itemsDeselected = false;
|
||||
bool solderMaskDirty = false;
|
||||
bool autofillZones = false;
|
||||
bool selectedModified = false;
|
||||
|
||||
// Dirty flags and lists
|
||||
bool solderMaskDirty = false;
|
||||
bool autofillZones = false;
|
||||
std::vector<BOARD_ITEM*> staleTeardropPadsAndVias;
|
||||
std::set<PCB_TRACK*> staleTeardropTracks;
|
||||
|
||||
if( Empty() )
|
||||
return;
|
||||
|
||||
@ -279,10 +308,46 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||
}
|
||||
}
|
||||
|
||||
if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
|
||||
|| boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
|
||||
if( m_isBoardEditor )
|
||||
{
|
||||
solderMaskDirty = true;
|
||||
if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
|
||||
|| boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
|
||||
{
|
||||
solderMaskDirty = true;
|
||||
}
|
||||
|
||||
if( !( aCommitFlags & SKIP_TEARDROPS ) )
|
||||
{
|
||||
if( boardItem->Type() == PCB_PAD_T || boardItem->Type() == PCB_VIA_T )
|
||||
{
|
||||
staleTeardropPadsAndVias.push_back( boardItem );
|
||||
}
|
||||
else if( boardItem->Type() == PCB_TRACE_T || boardItem->Type() == PCB_ARC_T )
|
||||
{
|
||||
PCB_TRACK* track = static_cast<PCB_TRACK*>( boardItem );
|
||||
|
||||
staleTeardropTracks.insert( track );
|
||||
|
||||
std::vector<PAD*> connectedPads;
|
||||
std::vector<PCB_VIA*> connectedVias;
|
||||
|
||||
connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
|
||||
|
||||
for( PAD* pad : connectedPads )
|
||||
staleTeardropPadsAndVias.push_back( pad );
|
||||
|
||||
for( PCB_VIA* via : connectedVias )
|
||||
staleTeardropPadsAndVias.push_back( via );
|
||||
}
|
||||
else if( boardItem->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
|
||||
{
|
||||
if( pad->GetFlags() & IS_MODIFIED_CHILD )
|
||||
staleTeardropPadsAndVias.push_back( pad );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( boardItem->IsSelected() )
|
||||
@ -362,6 +427,14 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||
if( autofillZones )
|
||||
dirtyIntersectingZones( boardItem, changeType );
|
||||
|
||||
boardItem->SetFlags( STRUCT_DELETED );
|
||||
|
||||
if( boardItem->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
|
||||
pad->SetFlags( STRUCT_DELETED );
|
||||
}
|
||||
|
||||
switch( boardItem->Type() )
|
||||
{
|
||||
case PCB_TEXT_T:
|
||||
@ -545,19 +618,21 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||
frame->HideSolderMask();
|
||||
}
|
||||
|
||||
// Log undo items for any connectivity changes
|
||||
if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
|
||||
{
|
||||
TEARDROP_MANAGER teardropMgr( board, m_toolMgr );
|
||||
teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
|
||||
}
|
||||
|
||||
// Log undo items for any connectivity or teardrop changes
|
||||
for( size_t i = num_changes; i < m_changes.size(); ++i )
|
||||
{
|
||||
COMMIT_LINE& ent = m_changes[i];
|
||||
|
||||
wxASSERT( ( ent.m_type & CHT_TYPE ) == CHT_MODIFY );
|
||||
|
||||
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
|
||||
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
|
||||
|
||||
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||
{
|
||||
ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
|
||||
wxASSERT( ent.m_copy );
|
||||
ITEM_PICKER itemWrapper( nullptr, boardItem, convert( ent.m_type & CHT_TYPE ) );
|
||||
itemWrapper.SetLink( ent.m_copy );
|
||||
undoList.PushItem( itemWrapper );
|
||||
}
|
||||
@ -567,7 +642,14 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||
}
|
||||
|
||||
if( view )
|
||||
view->Update( boardItem );
|
||||
{
|
||||
if( ( ent.m_type & CHT_TYPE ) == CHT_ADD )
|
||||
view->Add( boardItem );
|
||||
else if( ( ent.m_type & CHT_TYPE ) == CHT_REMOVE )
|
||||
view->Remove( boardItem );
|
||||
else
|
||||
view->Update( boardItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ class TOOL_BASE;
|
||||
#define SKIP_SET_DIRTY 0x0004
|
||||
#define SKIP_CONNECTIVITY 0x0008
|
||||
#define ZONE_FILL_OP 0x0010
|
||||
#define SKIP_TEARDROPS 0x0020
|
||||
|
||||
class BOARD_COMMIT : public COMMIT
|
||||
{
|
||||
|
@ -203,5 +203,89 @@ static struct BOARD_CONNECTED_ITEM_DESC
|
||||
&BOARD_CONNECTED_ITEM::GetNetname ) )
|
||||
.SetIsHiddenFromPropertiesManager()
|
||||
.SetIsHiddenFromLibraryEditors();
|
||||
|
||||
auto supportsTeardrops =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem ) )
|
||||
{
|
||||
if( bci->GetBoard()->LegacyTeardrops() )
|
||||
return false;
|
||||
|
||||
return bci->Type() == PCB_PAD_T || bci->Type() == PCB_VIA_T;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
auto supportsTeardropPreferZoneSetting =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem ) )
|
||||
{
|
||||
if( bci->GetBoard()->LegacyTeardrops() )
|
||||
return false;
|
||||
|
||||
return bci->Type() == PCB_PAD_T;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const wxString groupTeardrops = _HKI( "Teardrops" );
|
||||
|
||||
auto enableTeardrops = new PROPERTY<BOARD_CONNECTED_ITEM, bool>( _HKI( "Enable Teardrops" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropsEnabled,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropsEnabled );
|
||||
enableTeardrops->SetAvailableFunc( supportsTeardrops );
|
||||
propMgr.AddProperty( enableTeardrops, groupTeardrops );
|
||||
|
||||
auto bestLength = new PROPERTY<BOARD_CONNECTED_ITEM, double>( _HKI( "Best Length Ratio" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropBestLengthRatio,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropBestLengthRatio );
|
||||
bestLength->SetAvailableFunc( supportsTeardrops );
|
||||
propMgr.AddProperty( bestLength, groupTeardrops );
|
||||
|
||||
auto maxLength = new PROPERTY<BOARD_CONNECTED_ITEM, int>( _HKI( "Max Length" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropMaxLength,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropMaxLength, PROPERTY_DISPLAY::PT_SIZE );
|
||||
maxLength->SetAvailableFunc( supportsTeardrops );
|
||||
propMgr.AddProperty( maxLength, groupTeardrops );
|
||||
|
||||
auto bestWidth = new PROPERTY<BOARD_CONNECTED_ITEM, double>( _HKI( "Best Width Ratio" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropBestWidthRatio,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropBestWidthRatio );
|
||||
bestWidth->SetAvailableFunc( supportsTeardrops );
|
||||
propMgr.AddProperty( bestWidth, groupTeardrops );
|
||||
|
||||
auto maxWidth = new PROPERTY<BOARD_CONNECTED_ITEM, int>( _HKI( "Max Width" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropMaxWidth,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropMaxWidth, PROPERTY_DISPLAY::PT_SIZE );
|
||||
maxWidth->SetAvailableFunc( supportsTeardrops );
|
||||
propMgr.AddProperty( maxWidth, groupTeardrops );
|
||||
|
||||
auto curvePts = new PROPERTY<BOARD_CONNECTED_ITEM, int>( _HKI( "Curve Points" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropCurvePts,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropCurvePts );
|
||||
curvePts->SetAvailableFunc( supportsTeardrops );
|
||||
propMgr.AddProperty( curvePts, groupTeardrops );
|
||||
|
||||
auto preferZones = new PROPERTY<BOARD_CONNECTED_ITEM, bool>( _HKI( "Prefer zone connections" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropPreferZoneConnections,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropPreferZoneConnections );
|
||||
preferZones->SetAvailableFunc( supportsTeardropPreferZoneSetting );
|
||||
propMgr.AddProperty( preferZones, groupTeardrops );
|
||||
|
||||
auto twoTracks = new PROPERTY<BOARD_CONNECTED_ITEM, bool>( _HKI( "Allow teardrops to span two tracks" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropAllowSpanTwoTracks,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropAllowSpanTwoTracks );
|
||||
twoTracks->SetAvailableFunc( supportsTeardrops );
|
||||
propMgr.AddProperty( twoTracks, groupTeardrops );
|
||||
|
||||
auto maxTrackWidth = new PROPERTY<BOARD_CONNECTED_ITEM, double>( _HKI( "Max Width Ratio" ),
|
||||
&BOARD_CONNECTED_ITEM::SetTeardropMaxTrackWidth,
|
||||
&BOARD_CONNECTED_ITEM::GetTeardropMaxTrackWidth );
|
||||
maxTrackWidth->SetAvailableFunc( supportsTeardrops );
|
||||
propMgr.AddProperty( maxTrackWidth, groupTeardrops );
|
||||
}
|
||||
} _BOARD_CONNECTED_ITEM_DESC;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define BOARD_CONNECTED_ITEM_H
|
||||
|
||||
#include <board_item.h>
|
||||
#include <teardrop/teardrop_parameters.h>
|
||||
|
||||
class NETCLASS;
|
||||
class NETINFO_ITEM;
|
||||
@ -168,22 +169,50 @@ public:
|
||||
*/
|
||||
wxString GetNetClassName() const;
|
||||
|
||||
void SetLocalRatsnestVisible( bool aVisible )
|
||||
{
|
||||
m_localRatsnestVisible = aVisible;
|
||||
}
|
||||
void SetLocalRatsnestVisible( bool aVisible ) { m_localRatsnestVisible = aVisible; }
|
||||
bool GetLocalRatsnestVisible() const { return m_localRatsnestVisible; }
|
||||
|
||||
bool GetLocalRatsnestVisible() const
|
||||
{
|
||||
return m_localRatsnestVisible;
|
||||
}
|
||||
TEARDROP_PARAMETERS& GetTeardropParams() { return m_teardropParams; }
|
||||
const TEARDROP_PARAMETERS& GetTeardropParams() const { return m_teardropParams; }
|
||||
|
||||
void SetTeardropsEnabled( bool aEnable ) { m_teardropParams.m_Enabled = aEnable; }
|
||||
bool GetTeardropsEnabled() const { return m_teardropParams.m_Enabled; }
|
||||
|
||||
void SetTeardropBestLengthRatio( double aRatio ) { m_teardropParams.m_BestLengthRatio = aRatio; }
|
||||
double GetTeardropBestLengthRatio() const { return m_teardropParams.m_BestLengthRatio; }
|
||||
|
||||
void SetTeardropMaxLength( int aMaxLength ) { m_teardropParams.m_TdMaxLen = aMaxLength; }
|
||||
int GetTeardropMaxLength() const { return m_teardropParams.m_TdMaxLen; }
|
||||
|
||||
void SetTeardropBestWidthRatio( double aRatio ) { m_teardropParams.m_BestWidthRatio = aRatio; }
|
||||
double GetTeardropBestWidthRatio() const { return m_teardropParams.m_BestWidthRatio; }
|
||||
|
||||
void SetTeardropMaxWidth( int aMaxWidth ) { m_teardropParams.m_TdMaxWidth = aMaxWidth; }
|
||||
int GetTeardropMaxWidth() const { return m_teardropParams.m_TdMaxWidth; }
|
||||
|
||||
void SetTeardropCurvePts( int aPointCount ) { m_teardropParams.m_CurveSegCount = aPointCount; }
|
||||
int GetTeardropCurvePts() const { return m_teardropParams.m_CurveSegCount; }
|
||||
|
||||
void SetTeardropPreferZoneConnections( bool aPrefer ) { m_teardropParams.m_TdOnPadsInZones = !aPrefer; }
|
||||
bool GetTeardropPreferZoneConnections() const { return !m_teardropParams.m_TdOnPadsInZones; }
|
||||
|
||||
void SetTeardropAllowSpanTwoTracks( bool aAllow ) { m_teardropParams.m_AllowUseTwoTracks = aAllow; }
|
||||
bool GetTeardropAllowSpanTwoTracks() const { return m_teardropParams.m_AllowUseTwoTracks; }
|
||||
|
||||
void SetTeardropMaxTrackWidth( double aRatio ) { m_teardropParams.m_WidthtoSizeFilterRatio = aRatio; }
|
||||
double GetTeardropMaxTrackWidth() const { return m_teardropParams.m_WidthtoSizeFilterRatio; }
|
||||
|
||||
protected:
|
||||
/// Store all information about the net that item belongs to.
|
||||
NETINFO_ITEM* m_netinfo;
|
||||
|
||||
/// Not all BOARD_CONNECTED_ITEMs support teardrops, but we want those that do to share a
|
||||
/// single section in the property inspector.
|
||||
TEARDROP_PARAMETERS m_teardropParams;
|
||||
|
||||
private:
|
||||
bool m_localRatsnestVisible;
|
||||
|
||||
};
|
||||
|
||||
#endif // BOARD_CONNECTED_ITEM_H
|
||||
|
@ -471,9 +471,6 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
|
||||
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;
|
||||
entry["td_on_pad_in_zone"] = m_TeardropParamsList.m_TdOnPadsInZones;
|
||||
|
||||
js.push_back( entry );
|
||||
|
||||
@ -501,14 +498,20 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
|
||||
if( entry.contains( "td_onroundshapesonly" ) )
|
||||
m_TeardropParamsList.m_UseRoundShapesOnly = entry["td_onroundshapesonly"].get<bool>();
|
||||
|
||||
if( entry.contains( "td_allow_use_two_tracks" ) )
|
||||
m_TeardropParamsList.m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
|
||||
// Legacy settings
|
||||
for( int ii = 0; ii < 3; ++ii )
|
||||
{
|
||||
TEARDROP_PARAMETERS* td_prm = m_TeardropParamsList.GetParameters( (TARGET_TD)ii );
|
||||
|
||||
if( entry.contains( "td_curve_segcount" ) )
|
||||
m_TeardropParamsList.m_CurveSegCount = entry["td_curve_segcount"].get<int>();
|
||||
if( entry.contains( "td_allow_use_two_tracks" ) )
|
||||
td_prm->m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
|
||||
|
||||
if( entry.contains( "td_on_pad_in_zone" ) )
|
||||
m_TeardropParamsList.m_TdOnPadsInZones = entry["td_on_pad_in_zone"].get<bool>();
|
||||
if( entry.contains( "td_curve_segcount" ) )
|
||||
td_prm->m_CurveSegCount = entry["td_curve_segcount"].get<int>();
|
||||
|
||||
if( entry.contains( "td_on_pad_in_zone" ) )
|
||||
td_prm->m_TdOnPadsInZones = entry["td_on_pad_in_zone"].get<bool>();
|
||||
}
|
||||
}
|
||||
},
|
||||
{} ) );
|
||||
@ -526,11 +529,14 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
|
||||
|
||||
entry["td_target_name"] = GetTeardropTargetCanonicalName( (TARGET_TD)ii );
|
||||
entry["td_maxlen"] = pcbIUScale.IUTomm( td_prm->m_TdMaxLen );
|
||||
entry["td_maxheight"] = pcbIUScale.IUTomm( td_prm->m_TdMaxHeight );
|
||||
entry["td_length_ratio"] = td_prm->m_LengthRatio;
|
||||
entry["td_height_ratio"] = td_prm->m_HeightRatio;
|
||||
entry["td_maxheight"] = pcbIUScale.IUTomm( td_prm->m_TdMaxWidth );
|
||||
entry["td_length_ratio"] = td_prm->m_BestLengthRatio;
|
||||
entry["td_height_ratio"] = td_prm->m_BestWidthRatio;
|
||||
entry["td_curve_segcount"] = td_prm->m_CurveSegCount;
|
||||
entry["td_width_to_size_filter_ratio"] = td_prm->m_WidthtoSizeFilterRatio;
|
||||
entry["td_allow_use_two_tracks"] = td_prm->m_AllowUseTwoTracks;
|
||||
entry["td_curve_segcount"] = td_prm->m_CurveSegCount;
|
||||
entry["td_on_pad_in_zone"] = td_prm->m_TdOnPadsInZones;
|
||||
|
||||
js.push_back( entry );
|
||||
}
|
||||
@ -560,19 +566,28 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
|
||||
td_prm->m_TdMaxLen = pcbIUScale.mmToIU( entry["td_maxlen"].get<double>() );
|
||||
|
||||
if( entry.contains( "td_maxheight" ) )
|
||||
td_prm->m_TdMaxHeight = pcbIUScale.mmToIU( entry["td_maxheight"].get<double>() );
|
||||
td_prm->m_TdMaxWidth = pcbIUScale.mmToIU( entry["td_maxheight"].get<double>() );
|
||||
|
||||
if( entry.contains( "td_length_ratio" ) )
|
||||
td_prm->m_LengthRatio = entry["td_length_ratio"].get<double>();
|
||||
td_prm->m_BestLengthRatio = entry["td_length_ratio"].get<double>();
|
||||
|
||||
if( entry.contains( "td_height_ratio" ) )
|
||||
td_prm->m_HeightRatio = entry["td_height_ratio"].get<double>();
|
||||
td_prm->m_BestWidthRatio = entry["td_height_ratio"].get<double>();
|
||||
|
||||
if( entry.contains( "td_curve_segcount" ) )
|
||||
td_prm->m_CurveSegCount = entry["td_curve_segcount"].get<int>();
|
||||
|
||||
if( entry.contains( "td_width_to_size_filter_ratio" ) )
|
||||
td_prm->m_WidthtoSizeFilterRatio = entry["td_width_to_size_filter_ratio"].get<double>();
|
||||
|
||||
if( entry.contains( "td_allow_use_two_tracks" ) )
|
||||
td_prm->m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
|
||||
|
||||
if( entry.contains( "td_curve_segcount" ) )
|
||||
td_prm->m_CurveSegCount = entry["td_curve_segcount"].get<int>();
|
||||
|
||||
if( entry.contains( "td_on_pad_in_zone" ) )
|
||||
td_prm->m_TdOnPadsInZones = entry["td_on_pad_in_zone"].get<bool>();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -637,6 +637,28 @@ const
|
||||
}
|
||||
|
||||
|
||||
void CONNECTIVITY_DATA::GetConnectedPadsAndVias( const BOARD_CONNECTED_ITEM* aItem,
|
||||
std::vector<PAD*>* pads,
|
||||
std::vector<PCB_VIA*>* vias )
|
||||
{
|
||||
for( CN_ITEM* citem : m_connAlgo->ItemEntry( aItem ).GetItems() )
|
||||
{
|
||||
for( CN_ITEM* connected : citem->ConnectedItems() )
|
||||
{
|
||||
if( connected->Valid() )
|
||||
{
|
||||
BOARD_CONNECTED_ITEM* parent = connected->Parent();
|
||||
|
||||
if( parent->Type() == PCB_PAD_T )
|
||||
pads->push_back( static_cast<PAD*>( parent ) );
|
||||
else if( parent->Type() == PCB_VIA_T )
|
||||
vias->push_back( static_cast<PCB_VIA*>( parent ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int CONNECTIVITY_DATA::GetNodeCount( int aNet ) const
|
||||
{
|
||||
int sum = 0;
|
||||
|
@ -51,6 +51,7 @@ class ZONE;
|
||||
class RN_DATA;
|
||||
class RN_NET;
|
||||
class PCB_TRACK;
|
||||
class PCB_VIA;
|
||||
class PAD;
|
||||
class FOOTPRINT;
|
||||
class PROGRESS_REPORTER;
|
||||
@ -193,6 +194,9 @@ public:
|
||||
|
||||
void GetConnectedPads( const BOARD_CONNECTED_ITEM* aItem, std::set<PAD*>* pads ) const;
|
||||
|
||||
void GetConnectedPadsAndVias( const BOARD_CONNECTED_ITEM* aItem, std::vector<PAD*>* pads,
|
||||
std::vector<PCB_VIA*>* vias );
|
||||
|
||||
/**
|
||||
* Function GetConnectedItemsAtAnchor()
|
||||
* Returns a list of items connected to a source item aItem at position aAnchor
|
||||
|
@ -228,7 +228,7 @@ const std::vector<CN_ITEM*> CN_LIST::Add( ZONE* zone, PCB_LAYER_ID aLayer )
|
||||
|
||||
zitem->BuildRTree();
|
||||
|
||||
for( VECTOR2I pt : zone->GetFilledPolysList( aLayer )->COutline( j ).CPoints() )
|
||||
for( const VECTOR2I& pt : zone->GetFilledPolysList( aLayer )->COutline( j ).CPoints() )
|
||||
zitem->AddAnchor( pt );
|
||||
|
||||
rv.push_back( Add( zitem ) );
|
||||
|
@ -258,18 +258,22 @@ class CN_ZONE_LAYER : public CN_ITEM
|
||||
public:
|
||||
CN_ZONE_LAYER( ZONE* aParent, PCB_LAYER_ID aLayer, int aSubpolyIndex ) :
|
||||
CN_ITEM( aParent, false ),
|
||||
m_zone( aParent ),
|
||||
m_subpolyIndex( aSubpolyIndex ),
|
||||
m_layer( aLayer )
|
||||
{
|
||||
m_triangulatedPoly = aParent->GetFilledPolysList( aLayer );
|
||||
m_fillPoly = aParent->GetFilledPolysList( aLayer );
|
||||
SetLayers( aLayer );
|
||||
}
|
||||
|
||||
void BuildRTree()
|
||||
{
|
||||
for( unsigned int ii = 0; ii < m_triangulatedPoly->TriangulatedPolyCount(); ++ii )
|
||||
if( m_zone->IsTeardropArea() )
|
||||
return;
|
||||
|
||||
for( unsigned int ii = 0; ii < m_fillPoly->TriangulatedPolyCount(); ++ii )
|
||||
{
|
||||
const auto* triangleSet = m_triangulatedPoly->TriangulatedPolygon( ii );
|
||||
const auto* triangleSet = m_fillPoly->TriangulatedPolygon( ii );
|
||||
|
||||
if( triangleSet->GetSourceOutlineIndex() != m_subpolyIndex )
|
||||
continue;
|
||||
@ -291,6 +295,9 @@ public:
|
||||
|
||||
bool ContainsPoint( const VECTOR2I& p ) const
|
||||
{
|
||||
if( m_zone->IsTeardropArea() )
|
||||
return m_fillPoly->Outline( m_subpolyIndex ).Collide( p ) ;
|
||||
|
||||
int min[2] = { p.x, p.y };
|
||||
int max[2] = { p.x, p.y };
|
||||
bool collision = false;
|
||||
@ -319,11 +326,14 @@ public:
|
||||
|
||||
const SHAPE_LINE_CHAIN& GetOutline() const
|
||||
{
|
||||
return m_triangulatedPoly->Outline( m_subpolyIndex );
|
||||
return m_fillPoly->Outline( m_subpolyIndex );
|
||||
}
|
||||
|
||||
bool Collide( SHAPE* aRefShape ) const
|
||||
{
|
||||
if( m_zone->IsTeardropArea() )
|
||||
return m_fillPoly->Collide( aRefShape );
|
||||
|
||||
BOX2I bbox = aRefShape->BBox();
|
||||
int min[2] = { bbox.GetX(), bbox.GetY() };
|
||||
int max[2] = { bbox.GetRight(), bbox.GetBottom() };
|
||||
@ -349,9 +359,10 @@ public:
|
||||
bool HasSingleConnection();
|
||||
|
||||
private:
|
||||
ZONE* m_zone;
|
||||
int m_subpolyIndex;
|
||||
PCB_LAYER_ID m_layer;
|
||||
std::shared_ptr<SHAPE_POLY_SET> m_triangulatedPoly;
|
||||
std::shared_ptr<SHAPE_POLY_SET> m_fillPoly;
|
||||
RTree<const SHAPE*, int, 2, double> m_rTree;
|
||||
};
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include "dialog_board_setup.h"
|
||||
#include "panel_setup_rules.h"
|
||||
#include "panel_setup_teardrops.h"
|
||||
|
||||
|
||||
std::mutex DIALOG_BOARD_SETUP::g_Mutex;
|
||||
@ -64,6 +65,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
|
||||
m_maskAndPagePage( 0 ),
|
||||
m_constraintsPage( 0 ),
|
||||
m_tracksAndViasPage( 0 ),
|
||||
m_teardropsPage( 0 ),
|
||||
m_netclassesPage( 0 ),
|
||||
m_severitiesPage( 0 )
|
||||
|
||||
@ -149,6 +151,13 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
|
||||
return new PANEL_SETUP_TRACKS_AND_VIAS( aParent, m_frame );
|
||||
}, _( "Pre-defined Sizes" ) );
|
||||
|
||||
m_teardropsPage = m_treebook->GetPageCount();
|
||||
m_treebook->AddLazySubPage(
|
||||
[this]( wxWindow* aParent ) -> wxWindow*
|
||||
{
|
||||
return new PANEL_SETUP_TEARDROPS( aParent, m_frame );
|
||||
}, _( "Teardrops" ) );
|
||||
|
||||
m_netclassesPage = m_treebook->GetPageCount();
|
||||
m_treebook->AddLazySubPage(
|
||||
[this]( wxWindow* aParent ) -> wxWindow*
|
||||
@ -353,6 +362,12 @@ void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
|
||||
m_tracksAndViasPage )->ImportSettingsFrom( otherBoard );
|
||||
}
|
||||
|
||||
if( importDlg.m_TeardropsOpt->GetValue() )
|
||||
{
|
||||
RESOLVE_PAGE( PANEL_SETUP_TEARDROPS,
|
||||
m_teardropsPage )->ImportSettingsFrom( otherBoard );
|
||||
}
|
||||
|
||||
if( importDlg.m_MaskAndPasteOpt->GetValue() )
|
||||
{
|
||||
RESOLVE_PAGE( PANEL_SETUP_MASK_AND_PASTE,
|
||||
|
@ -67,6 +67,7 @@ private:
|
||||
size_t m_maskAndPagePage;
|
||||
size_t m_constraintsPage;
|
||||
size_t m_tracksAndViasPage;
|
||||
size_t m_teardropsPage;
|
||||
size_t m_netclassesPage;
|
||||
size_t m_severitiesPage;
|
||||
};
|
||||
|
@ -479,8 +479,8 @@ bool DIALOG_COPPER_ZONE::TransferDataFromWindow()
|
||||
}
|
||||
|
||||
m_settings.m_HatchOrientation = m_gridStyleRotation.GetAngleValue();
|
||||
m_settings.m_HatchThickness = m_gridStyleThickness.GetValue();
|
||||
m_settings.m_HatchGap = m_gridStyleGap.GetValue();
|
||||
m_settings.m_HatchThickness = m_gridStyleThickness.GetIntValue();
|
||||
m_settings.m_HatchGap = m_gridStyleGap.GetIntValue();
|
||||
m_settings.m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue();
|
||||
m_settings.m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue();
|
||||
|
||||
@ -514,7 +514,7 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aUseExportableSetupOnly )
|
||||
|
||||
if( m_settings.m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
|
||||
{
|
||||
int minThickness = m_minWidth.GetValue();
|
||||
int minThickness = m_minWidth.GetIntValue();
|
||||
|
||||
if( !m_gridStyleThickness.Validate( minThickness, INT_MAX ) )
|
||||
return false;
|
||||
@ -542,15 +542,17 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aUseExportableSetupOnly )
|
||||
pcbIUScale.mmToIU( ZONE_BORDER_HATCH_MAXDIST_MM ) ) )
|
||||
return false;
|
||||
|
||||
m_settings.m_BorderHatchPitch = m_outlineHatchPitch.GetValue();
|
||||
m_settings.m_BorderHatchPitch = m_outlineHatchPitch.GetIntValue();
|
||||
|
||||
m_settings.m_ZoneClearance = m_clearance.GetValue();
|
||||
m_settings.m_ZoneMinThickness = m_minWidth.GetValue();
|
||||
m_settings.m_ZoneClearance = m_clearance.GetIntValue();
|
||||
m_settings.m_ZoneMinThickness = m_minWidth.GetIntValue();
|
||||
|
||||
m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
|
||||
|
||||
m_settings.SetCornerRadius( m_settings.GetCornerSmoothingType() == ZONE_SETTINGS::SMOOTHING_NONE
|
||||
? 0 : m_cornerRadius.GetValue() );
|
||||
if( m_settings.GetCornerSmoothingType() == ZONE_SETTINGS::SMOOTHING_NONE )
|
||||
m_settings.SetCornerRadius( 0 );
|
||||
else
|
||||
m_settings.SetCornerRadius( m_cornerRadius.GetIntValue() );
|
||||
|
||||
m_settings.m_ZonePriority = m_PriorityLevelCtrl->GetValue();
|
||||
|
||||
|
569
pcbnew/dialogs/dialog_global_edit_teardrops.cpp
Normal file
569
pcbnew/dialogs/dialog_global_edit_teardrops.cpp
Normal file
@ -0,0 +1,569 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 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 <widgets/unit_binder.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <pcb_track.h>
|
||||
#include <pcb_group.h>
|
||||
#include <footprint.h>
|
||||
#include <teardrop/teardrop.h>
|
||||
#include <zone_filler.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <pcb_layer_box_selector.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/global_edit_tool.h>
|
||||
#include "dialog_global_edit_teardrops_base.h"
|
||||
|
||||
|
||||
// Globals to remember control settings during a session
|
||||
static bool g_vias = true;
|
||||
static bool g_pthPads = true;
|
||||
static bool g_smdPads = true;
|
||||
static bool g_trackToTrack = false;
|
||||
static bool g_filterByNetclass;
|
||||
static wxString g_netclassFilter;
|
||||
static bool g_filterByNet;
|
||||
static wxString g_netFilter;
|
||||
static bool g_filterByLayer;
|
||||
static int g_layerFilter;
|
||||
static bool g_filterRoundPads = false;
|
||||
static bool g_filterSelected = false;
|
||||
static int g_action = 1;
|
||||
|
||||
|
||||
class DIALOG_GLOBAL_EDIT_TEARDROPS : public DIALOG_GLOBAL_EDIT_TEARDROPS_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_GLOBAL_EDIT_TEARDROPS( PCB_EDIT_FRAME* aParent );
|
||||
~DIALOG_GLOBAL_EDIT_TEARDROPS() override;
|
||||
|
||||
protected:
|
||||
void onSpecifiedValuesUpdateUi( wxUpdateUIEvent& event ) override
|
||||
{
|
||||
event.Enable( m_specifiedValues->GetValue() );
|
||||
}
|
||||
void onCurvedEdgesUpdateUi( wxUpdateUIEvent& event ) override
|
||||
{
|
||||
event.Enable( m_specifiedValues->GetValue() && m_rbCurved->GetValue() );
|
||||
}
|
||||
void onFilterUpdateUi( wxUpdateUIEvent& event ) override
|
||||
{
|
||||
event.Enable( !m_trackToTrack->GetValue() );
|
||||
}
|
||||
|
||||
// We can't use standard wxWidgets radio button processing for these because you must
|
||||
// be able to turn them both off to set a "don't modify" state
|
||||
void onStraightLines( wxMouseEvent& event ) override
|
||||
{
|
||||
if( !m_rbStraightLines->GetValue() )
|
||||
{
|
||||
m_rbStraightLines->SetValue( true );
|
||||
m_rbCurved->SetValue( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rbStraightLines->SetValue( false );
|
||||
}
|
||||
}
|
||||
void onCurvedLines( wxMouseEvent& event ) override
|
||||
{
|
||||
if( !m_rbCurved->GetValue() )
|
||||
{
|
||||
m_rbCurved->SetValue( true );
|
||||
m_rbStraightLines->SetValue( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rbCurved->SetValue( false );
|
||||
}
|
||||
}
|
||||
|
||||
void onTrackToTrack( wxCommandEvent& event ) override
|
||||
{
|
||||
if( event.IsChecked() && m_specifiedValues->GetValue() )
|
||||
{
|
||||
m_specifiedValues->SetValue( false );
|
||||
m_addTeardrops->SetValue( true );
|
||||
}
|
||||
}
|
||||
|
||||
void OnNetclassFilterSelect( wxCommandEvent& event ) override
|
||||
{
|
||||
m_netclassFilterOpt->SetValue( true );
|
||||
}
|
||||
void OnLayerFilterSelect( wxCommandEvent& event ) override
|
||||
{
|
||||
m_layerFilterOpt->SetValue( true );
|
||||
}
|
||||
void OnNetFilterSelect( wxCommandEvent& event )
|
||||
{
|
||||
m_netFilterOpt->SetValue( true );
|
||||
}
|
||||
void OnExistingFilterSelect( wxCommandEvent& event ) override
|
||||
{
|
||||
if( event.IsChecked() )
|
||||
m_specifiedValues->SetLabel( _( "Update teardrops to specified values:" ) );
|
||||
else
|
||||
m_specifiedValues->SetLabel( _( "Add teardrops with specified values:" ) );
|
||||
}
|
||||
|
||||
void setSpecifiedParams( TEARDROP_PARAMETERS* targetParams );
|
||||
void visitItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem );
|
||||
void processItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem );
|
||||
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
|
||||
void onShowBoardSetup( wxHyperlinkEvent& event ) override
|
||||
{
|
||||
m_parent->ShowBoardSetupDialog( _( "Teardrops" ) );
|
||||
}
|
||||
|
||||
void buildFilterLists();
|
||||
|
||||
private:
|
||||
PCB_EDIT_FRAME* m_parent;
|
||||
BOARD* m_brd;
|
||||
PCB_SELECTION m_selection;
|
||||
|
||||
UNIT_BINDER m_teardropHDPercent;
|
||||
UNIT_BINDER m_teardropLenPercent;
|
||||
UNIT_BINDER m_teardropMaxLen;
|
||||
UNIT_BINDER m_teardropHeightPercent;
|
||||
UNIT_BINDER m_teardropMaxHeight;
|
||||
UNIT_BINDER m_curvePoints;
|
||||
};
|
||||
|
||||
|
||||
DIALOG_GLOBAL_EDIT_TEARDROPS::DIALOG_GLOBAL_EDIT_TEARDROPS( PCB_EDIT_FRAME* aParent ) :
|
||||
DIALOG_GLOBAL_EDIT_TEARDROPS_BASE( aParent ),
|
||||
m_teardropHDPercent( aParent, m_stHDRatio, m_tcHDRatio, m_stHDRatioUnits ),
|
||||
m_teardropLenPercent( aParent, m_stLenPercentLabel, m_tcLenPercent, m_stLenPercentUnits ),
|
||||
m_teardropMaxLen( aParent, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
|
||||
m_teardropHeightPercent( aParent, m_stHeightPercentLabel, m_tcHeightPercent, m_stHeightPercentUnits ),
|
||||
m_teardropMaxHeight( aParent, m_stMaxHeight, m_tcMaxHeight, m_stMaxHeightUnits ),
|
||||
m_curvePoints( aParent, m_curvePointsLabel, m_curvePointsCtrl, nullptr )
|
||||
{
|
||||
m_parent = aParent;
|
||||
m_brd = m_parent->GetBoard();
|
||||
|
||||
m_bitmapTeardrop->SetBitmap( KiBitmap( BITMAPS::teardrop_sizes ) );
|
||||
|
||||
m_teardropHDPercent.SetUnits( EDA_UNITS::PERCENT );
|
||||
m_teardropLenPercent.SetUnits( EDA_UNITS::PERCENT );
|
||||
m_teardropHeightPercent.SetUnits( EDA_UNITS::PERCENT );
|
||||
m_curvePoints.SetUnits( EDA_UNITS::UNSCALED );
|
||||
|
||||
m_minTrackWidthHint->SetFont( KIUI::GetInfoFont( this ).Italic() );
|
||||
|
||||
buildFilterLists();
|
||||
|
||||
SetupStandardButtons();
|
||||
|
||||
m_netFilter->Connect( NET_SELECTED,
|
||||
wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS::OnNetFilterSelect ),
|
||||
nullptr, this );
|
||||
|
||||
finishDialogSettings();
|
||||
}
|
||||
|
||||
|
||||
DIALOG_GLOBAL_EDIT_TEARDROPS::~DIALOG_GLOBAL_EDIT_TEARDROPS()
|
||||
{
|
||||
g_vias = m_vias->GetValue();
|
||||
g_pthPads = m_pthPads->GetValue();
|
||||
g_smdPads = m_smdPads->GetValue();
|
||||
g_trackToTrack = m_trackToTrack->GetValue();
|
||||
g_filterByNetclass = m_netclassFilterOpt->GetValue();
|
||||
g_netclassFilter = m_netclassFilter->GetStringSelection();
|
||||
g_filterByNet = m_netFilterOpt->GetValue();
|
||||
g_netFilter = m_netFilter->GetSelectedNetname();
|
||||
g_filterByLayer = m_layerFilterOpt->GetValue();
|
||||
g_layerFilter = m_layerFilter->GetLayerSelection();
|
||||
g_filterRoundPads = m_roundPadsFilter->GetValue();
|
||||
g_filterSelected = m_selectedItemsFilter->GetValue();
|
||||
|
||||
if( m_removeTeardrops->GetValue() )
|
||||
g_action = 0;
|
||||
else if( m_specifiedValues->GetValue() )
|
||||
g_action = 2;
|
||||
else
|
||||
g_action = 1;
|
||||
|
||||
m_netFilter->Disconnect( NET_SELECTED,
|
||||
wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS::OnNetFilterSelect ),
|
||||
nullptr, this );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_GLOBAL_EDIT_TEARDROPS::buildFilterLists()
|
||||
{
|
||||
// Populate the net filter list with net names
|
||||
m_netFilter->SetBoard( m_brd );
|
||||
m_netFilter->SetNetInfo( &m_brd->GetNetInfo() );
|
||||
|
||||
if( !m_brd->GetHighLightNetCodes().empty() )
|
||||
m_netFilter->SetSelectedNetcode( *m_brd->GetHighLightNetCodes().begin() );
|
||||
|
||||
// Populate the netclass filter list with netclass names
|
||||
wxArrayString netclassNames;
|
||||
std::shared_ptr<NET_SETTINGS>& settings = m_brd->GetDesignSettings().m_NetSettings;
|
||||
|
||||
netclassNames.push_back( settings->m_DefaultNetClass->GetName() );
|
||||
|
||||
for( const auto& [ name, netclass ] : settings->m_NetClasses )
|
||||
netclassNames.push_back( name );
|
||||
|
||||
m_netclassFilter->Set( netclassNames );
|
||||
m_netclassFilter->SetStringSelection( m_brd->GetDesignSettings().GetCurrentNetClassName() );
|
||||
|
||||
// Populate the layer filter list
|
||||
m_layerFilter->SetBoardFrame( m_parent );
|
||||
m_layerFilter->SetLayersHotkeys( false );
|
||||
m_layerFilter->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
|
||||
m_layerFilter->Resync();
|
||||
m_layerFilter->SetLayerSelection( m_parent->GetActiveLayer() );
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_GLOBAL_EDIT_TEARDROPS::TransferDataToWindow()
|
||||
{
|
||||
PCB_SELECTION_TOOL* selTool = m_parent->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
|
||||
m_selection = selTool->GetSelection();
|
||||
BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( m_selection.Front() );
|
||||
|
||||
m_vias->SetValue( g_vias );
|
||||
m_pthPads->SetValue( g_pthPads );
|
||||
m_smdPads->SetValue( g_smdPads );
|
||||
m_trackToTrack->SetValue( g_trackToTrack );
|
||||
|
||||
if( g_filterByNetclass && m_netclassFilter->SetStringSelection( g_netclassFilter ) )
|
||||
m_netclassFilterOpt->SetValue( true );
|
||||
else if( item )
|
||||
m_netclassFilter->SetStringSelection( item->GetNet()->GetNetClass()->GetName() );
|
||||
|
||||
if( g_filterByNet && m_brd->FindNet( g_netFilter ) != nullptr )
|
||||
{
|
||||
m_netFilter->SetSelectedNet( g_netFilter );
|
||||
m_netFilterOpt->SetValue( true );
|
||||
}
|
||||
else if( item )
|
||||
{
|
||||
m_netFilter->SetSelectedNetcode( item->GetNetCode() );
|
||||
}
|
||||
|
||||
if( g_filterByLayer && m_layerFilter->SetLayerSelection( g_layerFilter ) != wxNOT_FOUND )
|
||||
{
|
||||
m_layerFilterOpt->SetValue( true );
|
||||
}
|
||||
else if( item )
|
||||
{
|
||||
if( item->Type() == PCB_ZONE_T ) // a zone can be on more than one layer
|
||||
m_layerFilter->SetLayerSelection( static_cast<ZONE*>(item)->GetFirstLayer() );
|
||||
else
|
||||
m_layerFilter->SetLayerSelection( item->GetLayer() );
|
||||
}
|
||||
|
||||
m_roundPadsFilter->SetValue( g_filterRoundPads );
|
||||
m_selectedItemsFilter->SetValue( g_filterSelected );
|
||||
|
||||
if( g_action == 0 )
|
||||
m_removeTeardrops->SetValue( true );
|
||||
else if( g_action == 1 )
|
||||
m_addTeardrops->SetValue( true );
|
||||
else
|
||||
m_specifiedValues->SetValue( true );
|
||||
|
||||
m_cbPreferZoneConnection->Set3StateValue( wxCHK_UNDETERMINED );
|
||||
m_cbTeardropsUseNextTrack->Set3StateValue( wxCHK_UNDETERMINED );
|
||||
m_teardropHDPercent.SetValue( INDETERMINATE_ACTION );
|
||||
m_teardropLenPercent.SetValue( INDETERMINATE_ACTION );
|
||||
m_teardropMaxLen.SetValue( INDETERMINATE_ACTION );
|
||||
m_teardropHeightPercent.SetValue( INDETERMINATE_ACTION );
|
||||
m_teardropMaxHeight.SetValue( INDETERMINATE_ACTION );
|
||||
m_curvePoints.SetValue( INDETERMINATE_ACTION );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_GLOBAL_EDIT_TEARDROPS::setSpecifiedParams( TEARDROP_PARAMETERS* targetParams )
|
||||
{
|
||||
if( m_cbPreferZoneConnection->Get3StateValue() != wxCHK_UNDETERMINED )
|
||||
targetParams->m_TdOnPadsInZones = !m_cbPreferZoneConnection->GetValue();
|
||||
|
||||
if( m_cbTeardropsUseNextTrack->Get3StateValue() != wxCHK_UNDETERMINED )
|
||||
targetParams->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
|
||||
|
||||
if( !m_teardropHDPercent.IsIndeterminate() )
|
||||
targetParams->m_WidthtoSizeFilterRatio = m_teardropHDPercent.GetDoubleValue() / 100.0;
|
||||
|
||||
if( !m_teardropLenPercent.IsIndeterminate() )
|
||||
targetParams->m_BestLengthRatio = m_teardropLenPercent.GetDoubleValue() / 100.0;
|
||||
|
||||
if( !m_teardropMaxLen.IsIndeterminate() )
|
||||
targetParams->m_TdMaxLen = m_teardropMaxLen.GetIntValue();
|
||||
|
||||
if( !m_teardropHeightPercent.IsIndeterminate() )
|
||||
targetParams->m_BestWidthRatio = m_teardropHeightPercent.GetDoubleValue() / 100.0;
|
||||
|
||||
if( !m_teardropMaxHeight.IsIndeterminate() )
|
||||
targetParams->m_TdMaxWidth = m_teardropMaxHeight.GetIntValue();
|
||||
|
||||
if( m_rbStraightLines->GetValue() )
|
||||
{
|
||||
targetParams->m_CurveSegCount = 0;
|
||||
}
|
||||
else if( m_rbCurved->GetValue() )
|
||||
{
|
||||
if( !m_curvePoints.IsIndeterminate() )
|
||||
targetParams->m_CurveSegCount = m_curvePoints.GetIntValue();
|
||||
else if( targetParams->m_CurveSegCount == 0 )
|
||||
targetParams->m_CurveSegCount = 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_GLOBAL_EDIT_TEARDROPS::processItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& brdSettings = m_brd->GetDesignSettings();
|
||||
TEARDROP_PARAMETERS* targetParams = nullptr;
|
||||
|
||||
if( aItem->Type() == PCB_PAD_T )
|
||||
targetParams = &static_cast<PAD*>( aItem )->GetTeardropParams();
|
||||
else if( aItem->Type() == PCB_VIA_T )
|
||||
targetParams = &static_cast<PCB_VIA*>( aItem )->GetTeardropParams();
|
||||
else
|
||||
return;
|
||||
|
||||
aCommit->Stage( aItem, CHT_MODIFY );
|
||||
|
||||
if( m_removeTeardrops->GetValue() )
|
||||
{
|
||||
targetParams->m_Enabled = false;
|
||||
}
|
||||
else if( m_addTeardrops->GetValue() )
|
||||
{
|
||||
if( TEARDROP_MANAGER::IsRound( aItem ) )
|
||||
*targetParams = *brdSettings.GetTeadropParamsList()->GetParameters( TARGET_ROUND );
|
||||
else
|
||||
*targetParams = *brdSettings.GetTeadropParamsList()->GetParameters( TARGET_RECT );
|
||||
|
||||
targetParams->m_Enabled = true;
|
||||
}
|
||||
else if( m_specifiedValues->GetValue() )
|
||||
{
|
||||
setSpecifiedParams( targetParams );
|
||||
|
||||
if( !m_existingFilter->GetValue() )
|
||||
targetParams->m_Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_GLOBAL_EDIT_TEARDROPS::visitItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem )
|
||||
{
|
||||
if( m_selectedItemsFilter->GetValue() )
|
||||
{
|
||||
if( !aItem->IsSelected() )
|
||||
{
|
||||
PCB_GROUP* group = aItem->GetParentGroup();
|
||||
|
||||
while( group && !group->IsSelected() )
|
||||
group = group->GetParentGroup();
|
||||
|
||||
if( !group )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_netFilterOpt->GetValue() && m_netFilter->GetSelectedNetcode() >= 0 )
|
||||
{
|
||||
if( aItem->GetNetCode() != m_netFilter->GetSelectedNetcode() )
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_netclassFilterOpt->GetValue() && !m_netclassFilter->GetStringSelection().IsEmpty() )
|
||||
{
|
||||
if( aItem->GetEffectiveNetClass()->GetName() != m_netclassFilter->GetStringSelection() )
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_layerFilterOpt->GetValue() && m_layerFilter->GetLayerSelection() != UNDEFINED_LAYER )
|
||||
{
|
||||
if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_roundPadsFilter->GetValue() )
|
||||
{
|
||||
if( !TEARDROP_MANAGER::IsRound( aItem ) )
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_existingFilter->GetValue() )
|
||||
{
|
||||
if( aItem->Type() == PCB_PAD_T )
|
||||
{
|
||||
if( !static_cast<PAD*>( aItem )->GetTeardropParams().m_Enabled )
|
||||
return;
|
||||
}
|
||||
else if( aItem->Type() == PCB_VIA_T )
|
||||
{
|
||||
if( !static_cast<PCB_VIA*>( aItem )->GetTeardropParams().m_Enabled )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
processItem( aCommit, aItem );
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_GLOBAL_EDIT_TEARDROPS::TransferDataFromWindow()
|
||||
{
|
||||
m_brd->SetLegacyTeardrops( false );
|
||||
|
||||
BOARD_COMMIT commit( m_parent );
|
||||
wxBusyCursor dummy;
|
||||
|
||||
if( m_vias->GetValue() )
|
||||
{
|
||||
for( PCB_TRACK* track : m_brd->Tracks() )
|
||||
{
|
||||
if ( track->Type() == PCB_VIA_T )
|
||||
visitItem( &commit, track );
|
||||
}
|
||||
}
|
||||
|
||||
for( FOOTPRINT* footprint : m_brd->Footprints() )
|
||||
{
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
{
|
||||
if( m_pthPads->GetValue() && pad->GetAttribute() == PAD_ATTRIB::PTH )
|
||||
{
|
||||
visitItem( &commit, pad );
|
||||
}
|
||||
else if( m_smdPads->GetValue() && ( pad->GetAttribute() == PAD_ATTRIB::SMD
|
||||
|| pad->GetAttribute() == PAD_ATTRIB::CONN ) )
|
||||
{
|
||||
visitItem( &commit, pad );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( m_trackToTrack->GetValue() )
|
||||
{
|
||||
TEARDROP_PARAMETERS_LIST* paramsList = m_brd->GetDesignSettings().GetTeadropParamsList();
|
||||
TEARDROP_PARAMETERS* targetParams = paramsList->GetParameters( TARGET_TRACK );
|
||||
TEARDROP_MANAGER teardropManager( m_brd, m_parent->GetToolManager() );
|
||||
|
||||
teardropManager.DeleteTrackToTrackTeardrops( commit );
|
||||
|
||||
if( m_removeTeardrops->GetValue() )
|
||||
{
|
||||
targetParams->m_Enabled = false; // JEY TODO: how does this get undone/redone?
|
||||
}
|
||||
else if( m_addTeardrops->GetValue() )
|
||||
{
|
||||
targetParams->m_Enabled = true; // JEY TODO: how does this get undone/redone?
|
||||
teardropManager.AddTeardropsOnTracks( commit, nullptr, true );
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no filters then a force-full-update is equivalent, and will be faster.
|
||||
if( !m_netFilterOpt->GetValue()
|
||||
&& !m_netclassFilterOpt->GetValue()
|
||||
&& !m_layerFilterOpt->GetValue()
|
||||
&& !m_roundPadsFilter->GetValue()
|
||||
&& !m_existingFilter->GetValue()
|
||||
&& !m_selectedItemsFilter->GetValue() )
|
||||
{
|
||||
commit.Push( _( "Edit Teardrops" ), SKIP_TEARDROPS );
|
||||
|
||||
TEARDROP_MANAGER teardropMgr( m_brd, m_parent->GetToolManager() );
|
||||
teardropMgr.UpdateTeardrops( commit, nullptr, nullptr, true /* forceFullUpdate */ );
|
||||
commit.Push( _( "Edit Teardrops" ), SKIP_TEARDROPS | APPEND_UNDO );
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.Push( _( "Edit Teardrops" ) );
|
||||
}
|
||||
|
||||
// Showing the unfilled, fully cross-hatched teardrops seems to be working fairly well, and
|
||||
// accurate fills can then be manually generated by doing a zone fill.
|
||||
//
|
||||
// But here's the old code which allowed for either "draft" fills or an automatic full zone
|
||||
// fill in case we decide the current situation isn't good enough:
|
||||
#if 0
|
||||
if( aFillAfter )
|
||||
{
|
||||
ZONE_FILLER filler( m_board, aCommit );
|
||||
|
||||
if( m_reporter )
|
||||
filler.SetProgressReporter( m_reporter );
|
||||
|
||||
filler.Fill( m_board->Zones() );
|
||||
|
||||
if( aCommit )
|
||||
aCommit->Push( _( "Edit Teardrops" ), APPEND_UNDO );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int GLOBAL_EDIT_TOOL::EditTeardrops( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
||||
DIALOG_GLOBAL_EDIT_TEARDROPS dlg( editFrame );
|
||||
|
||||
dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
|
||||
return 0;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user