diff --git a/pcbnew/dialogs/dialog_track_via_size.cpp b/pcbnew/dialogs/dialog_track_via_size.cpp index a7522aba70..ab9e1cac37 100644 --- a/pcbnew/dialogs/dialog_track_via_size.cpp +++ b/pcbnew/dialogs/dialog_track_via_size.cpp @@ -23,22 +23,22 @@ */ #include "dialog_track_via_size.h" -#include #include #include #include -DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, PNS_ROUTING_SETTINGS& aSettings ) : +#include "class_board_design_settings.h" + +DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings ) : DIALOG_TRACK_VIA_SIZE_BASE( aParent ), m_settings( aSettings ) { // Load router settings to dialog fields - m_trackWidth->SetValue( To_User_Unit( m_trackWidth->GetUnits(), m_settings.GetTrackWidth() ) ); - m_viaDiameter->SetValue( To_User_Unit( m_viaDiameter->GetUnits(), m_settings.GetViaDiameter() ) ); - m_viaDrill->SetValue( To_User_Unit( m_viaDrill->GetUnits(), m_settings.GetViaDrill() ) ); + m_trackWidth->SetValue( To_User_Unit( m_trackWidth->GetUnits(), m_settings.GetCustomTrackWidth() ) ); + m_viaDiameter->SetValue( To_User_Unit( m_viaDiameter->GetUnits(), m_settings.GetCustomViaSize() ) ); + m_viaDrill->SetValue( To_User_Unit( m_viaDrill->GetUnits(), m_settings.GetCustomViaDrill() ) ); m_trackWidth->SetFocus(); - GetSizer()->SetSizeHints( this ); // Pressing ENTER when any of the text input fields is active applies changes #if wxCHECK_VERSION( 3, 0, 0 ) @@ -46,6 +46,8 @@ DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, PNS_ROUTING_SET #else Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE::onOkClick ), NULL, this ); #endif + + Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_TRACK_VIA_SIZE::onClose ) ); } @@ -56,7 +58,7 @@ bool DIALOG_TRACK_VIA_SIZE::check() return false; // Via drill should be smaller than via diameter - if( *m_viaDrill->GetValue() >= m_viaDiameter->GetValue() ) + if( m_viaDrill->GetValue() >= m_viaDiameter->GetValue() ) return false; return true; @@ -74,9 +76,9 @@ void DIALOG_TRACK_VIA_SIZE::onOkClick( wxCommandEvent& aEvent ) if( check() ) { // Store dialog values to the router settings - m_settings.SetTrackWidth( From_User_Unit( m_trackWidth->GetUnits(), *m_trackWidth->GetValue() ) ); - m_settings.SetViaDiameter( From_User_Unit( m_viaDiameter->GetUnits(), *m_viaDiameter->GetValue() ) ); - m_settings.SetViaDrill( From_User_Unit( m_viaDrill->GetUnits(), *m_viaDrill->GetValue() ) ); + m_settings.SetCustomTrackWidth( From_User_Unit( m_trackWidth->GetUnits(), *m_trackWidth->GetValue() ) ); + m_settings.SetCustomViaSize( From_User_Unit( m_viaDiameter->GetUnits(), *m_viaDiameter->GetValue() ) ); + m_settings.SetCustomViaDrill( From_User_Unit( m_viaDrill->GetUnits(), *m_viaDrill->GetValue() ) ); EndModal( 1 ); } else diff --git a/pcbnew/dialogs/dialog_track_via_size.h b/pcbnew/dialogs/dialog_track_via_size.h index 92a03e8ec6..5db003d7de 100644 --- a/pcbnew/dialogs/dialog_track_via_size.h +++ b/pcbnew/dialogs/dialog_track_via_size.h @@ -19,7 +19,7 @@ */ /** - * Push and Shove router track width and via size dialog. + * Custom track width and via size dialog. */ #ifndef __dialog_track_via_size__ @@ -27,18 +27,18 @@ #include "dialog_track_via_size_base.h" -class PNS_ROUTING_SETTINGS; +class BOARD_DESIGN_SETTINGS; /** Implementing DIALOG_TRACK_VIA_SIZE_BASE */ class DIALOG_TRACK_VIA_SIZE : public DIALOG_TRACK_VIA_SIZE_BASE { public: /** Constructor */ - DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, PNS_ROUTING_SETTINGS& aSettings ); + DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings ); protected: // Routings settings that are modified by the dialog. - PNS_ROUTING_SETTINGS& m_settings; + BOARD_DESIGN_SETTINGS& m_settings; ///> Checks if values given in the dialog are sensible. bool check(); diff --git a/pcbnew/dialogs/dialog_track_via_size_base.cpp b/pcbnew/dialogs/dialog_track_via_size_base.cpp index 0331d8f204..a1bfad0ce4 100644 --- a/pcbnew/dialogs/dialog_track_via_size_base.cpp +++ b/pcbnew/dialogs/dialog_track_via_size_base.cpp @@ -1,61 +1,57 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Nov 6 2013) +// C++ code generated with wxFormBuilder (version Jun 6 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#include "dialog_shim.h" - #include "dialog_track_via_size_base.h" /////////////////////////////////////////////////////////////////////////// DIALOG_TRACK_VIA_SIZE_BASE::DIALOG_TRACK_VIA_SIZE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetSizeHints( wxSize( 280,240 ), wxDefaultSize ); wxBoxSizer* bSizes; bSizes = new wxBoxSizer( wxVERTICAL ); m_trackWidth = new WX_UNIT_TEXT( this, _("Track width:") ); - bSizes->Add( m_trackWidth, 0, wxALL, 5 ); + bSizes->Add( m_trackWidth, 0, wxALL|wxEXPAND, 5 ); m_viaDiameter = new WX_UNIT_TEXT( this, _("Via diameter:") ); - bSizes->Add( m_viaDiameter, 0, wxALL, 5 ); + bSizes->Add( m_viaDiameter, 0, wxALL|wxEXPAND, 5 ); m_viaDrill = new WX_UNIT_TEXT( this, _("Via drill:") ); - bSizes->Add( m_viaDrill, 0, wxALL, 5 ); + bSizes->Add( m_viaDrill, 0, wxALL|wxEXPAND, 5 ); - wxBoxSizer* bButtons; - bButtons = new wxBoxSizer( wxHORIZONTAL ); + m_stdButtons = new wxStdDialogButtonSizer(); + m_stdButtonsOK = new wxButton( this, wxID_OK ); + m_stdButtons->AddButton( m_stdButtonsOK ); + m_stdButtonsCancel = new wxButton( this, wxID_CANCEL ); + m_stdButtons->AddButton( m_stdButtonsCancel ); + m_stdButtons->Realize(); - m_ok = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - bButtons->Add( m_ok, 1, wxALL, 5 ); - - m_cancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bButtons->Add( m_cancel, 1, wxALL, 5 ); - - - bSizes->Add( bButtons, 0, wxEXPAND, 5 ); + bSizes->Add( m_stdButtons, 0, wxEXPAND|wxALL, 5 ); this->SetSizer( bSizes ); this->Layout(); + bSizes->Fit( this ); this->Centre( wxBOTH ); // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onClose ) ); - m_ok->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onOkClick ), NULL, this ); - m_cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onCancelClick ), NULL, this ); + m_stdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onCancelClick ), NULL, this ); + m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onOkClick ), NULL, this ); } DIALOG_TRACK_VIA_SIZE_BASE::~DIALOG_TRACK_VIA_SIZE_BASE() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onClose ) ); - m_ok->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onOkClick ), NULL, this ); - m_cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onCancelClick ), NULL, this ); + m_stdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onCancelClick ), NULL, this ); + m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onOkClick ), NULL, this ); } diff --git a/pcbnew/dialogs/dialog_track_via_size_base.fbp b/pcbnew/dialogs/dialog_track_via_size_base.fbp index f442938f09..c2e3325af7 100644 --- a/pcbnew/dialogs/dialog_track_via_size_base.fbp +++ b/pcbnew/dialogs/dialog_track_via_size_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -41,11 +41,11 @@ 0 wxID_ANY - + 280,240 DIALOG_TRACK_VIA_SIZE_BASE - 388,162 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + -1,-1 + wxDEFAULT_DIALOG_STYLE Track width and via size @@ -147,7 +147,7 @@ 1 - DIALOG_SHIM; dialog_shim.h + 0 @@ -350,189 +350,28 @@ 5 - wxEXPAND + wxEXPAND|wxALL 0 - + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 - bButtons - wxHORIZONTAL - none - - 5 - wxALL - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_OK - OK - - 0 - - - 0 - - 1 - m_ok - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - onOkClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_CANCEL - Cancel - - 0 - - - 0 - - 1 - m_cancel - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - onCancelClick - - - - - - - - - - - - - - - - - - - - - - - - - + m_stdButtons + protected + + onCancelClick + + + + onOkClick + + diff --git a/pcbnew/dialogs/dialog_track_via_size_base.h b/pcbnew/dialogs/dialog_track_via_size_base.h index 0446af107e..3f62c01588 100644 --- a/pcbnew/dialogs/dialog_track_via_size_base.h +++ b/pcbnew/dialogs/dialog_track_via_size_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Nov 6 2013) +// C++ code generated with wxFormBuilder (version Jun 6 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -11,16 +11,14 @@ #include #include #include -class DIALOG_SHIM; - #include #include #include #include #include #include -#include #include +#include #include /////////////////////////////////////////////////////////////////////////// @@ -37,18 +35,19 @@ class DIALOG_TRACK_VIA_SIZE_BASE : public wxDialog WX_UNIT_TEXT* m_trackWidth; WX_UNIT_TEXT* m_viaDiameter; WX_UNIT_TEXT* m_viaDrill; - wxButton* m_ok; - wxButton* m_cancel; + wxStdDialogButtonSizer* m_stdButtons; + wxButton* m_stdButtonsOK; + wxButton* m_stdButtonsCancel; // Virtual event handlers, overide them in your derived class virtual void onClose( wxCloseEvent& event ) { event.Skip(); } - virtual void onOkClick( wxCommandEvent& event ) { event.Skip(); } virtual void onCancelClick( wxCommandEvent& event ) { event.Skip(); } + virtual void onOkClick( wxCommandEvent& event ) { event.Skip(); } public: - DIALOG_TRACK_VIA_SIZE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Track width and via size"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 388,162 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_TRACK_VIA_SIZE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Track width and via size"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE ); ~DIALOG_TRACK_VIA_SIZE_BASE(); }; diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 211260e620..d339e0c7b0 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -387,8 +387,7 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer ) else { double width = ( aVia->GetWidth() - aVia->GetDrillValue() ) / 2.0; - radius -= width / 2.0; - + m_gal->SetLineWidth( width ); m_gal->SetIsFill( true ); m_gal->SetIsStroke( false ); diff --git a/pcbnew/router/CMakeLists.txt b/pcbnew/router/CMakeLists.txt index 411216441f..a69b09118f 100644 --- a/pcbnew/router/CMakeLists.txt +++ b/pcbnew/router/CMakeLists.txt @@ -24,6 +24,7 @@ set( PCBNEW_PNS_SRCS pns_router.cpp pns_routing_settings.cpp pns_shove.cpp + pns_sizes_settings.cpp pns_solid.cpp pns_utils.cpp pns_via.cpp diff --git a/pcbnew/router/pns_dragger.cpp b/pcbnew/router/pns_dragger.cpp index bc43858d95..f1fe58c8d9 100644 --- a/pcbnew/router/pns_dragger.cpp +++ b/pcbnew/router/pns_dragger.cpp @@ -188,7 +188,7 @@ void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& a draggedLine->DragCorner( aP, 0 ); draggedLine->ClearSegmentLinks(); - m_draggedItems.AddOwned( draggedLine ); + m_draggedItems.Add( draggedLine ); // FIXME: mem leak m_lastNode->Remove( &origLine ); m_lastNode->Add( draggedLine ); diff --git a/pcbnew/router/pns_itemset.cpp b/pcbnew/router/pns_itemset.cpp index 20254b94c0..38165e6ccd 100644 --- a/pcbnew/router/pns_itemset.cpp +++ b/pcbnew/router/pns_itemset.cpp @@ -28,28 +28,9 @@ PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem ) m_items.push_back(aInitialItem); } - -PNS_ITEMSET::~PNS_ITEMSET() +PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert ) { - Clear(); -} - - -void PNS_ITEMSET::Clear() -{ - BOOST_FOREACH(PNS_ITEM* item, m_ownedItems) - { - delete item; - } - - m_items.clear(); - m_ownedItems.clear(); -} - - -PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd ) -{ - ITEM_VECTOR newItems; + ITEMS newItems; PNS_LAYERSET l; if( aEnd < 0 ) @@ -59,7 +40,7 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd ) BOOST_FOREACH( PNS_ITEM* item, m_items ) - if( item->Layers().Overlaps( l ) ) + if( item->Layers().Overlaps( l ) ^ aInvert ) newItems.push_back( item ); m_items = newItems; @@ -68,13 +49,13 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd ) } -PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask ) +PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask, bool aInvert ) { - ITEM_VECTOR newItems; + ITEMS newItems; BOOST_FOREACH( PNS_ITEM* item, m_items ) { - if( item->OfKind ( aKindMask ) ) + if( item->OfKind ( aKindMask ) ^ aInvert ) newItems.push_back( item ); } @@ -84,13 +65,28 @@ PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask ) } -PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet ) +PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert ) { - ITEM_VECTOR newItems; + ITEMS newItems; BOOST_FOREACH( PNS_ITEM* item, m_items ) { - if( item->Net() == aNet ) + if( (item->Net() == aNet) ^ aInvert ) + newItems.push_back( item ); + } + + m_items = newItems; + + return *this; +} + +PNS_ITEMSET& PNS_ITEMSET::ExcludeItem ( const PNS_ITEM *aItem ) +{ + ITEMS newItems; + + BOOST_FOREACH( PNS_ITEM* item, m_items ) + { + if( item != aItem ) newItems.push_back( item ); } diff --git a/pcbnew/router/pns_itemset.h b/pcbnew/router/pns_itemset.h index 44fe9c3c92..ec73f66177 100644 --- a/pcbnew/router/pns_itemset.h +++ b/pcbnew/router/pns_itemset.h @@ -22,6 +22,7 @@ #define __PNS_ITEMSET_H #include +#include #include "pns_item.h" @@ -35,53 +36,96 @@ class PNS_ITEMSET { public: - typedef std::vector ITEM_VECTOR; + typedef std::vector ITEMS; PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL ); PNS_ITEMSET( const PNS_ITEMSET& aOther ) { m_items = aOther.m_items; - m_ownedItems = ITEM_VECTOR(); } const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther ) { m_items = aOther.m_items; - m_ownedItems = ITEM_VECTOR(); - return *this; } - ~PNS_ITEMSET(); + int Count(int aKindMask = -1) const + { + int n = 0; + BOOST_FOREACH ( PNS_ITEM *item, m_items ) + { + if( item->Kind() & aKindMask ) + n++; + } + return n; + } - ITEM_VECTOR& Items() { return m_items; } - const ITEM_VECTOR& CItems() const { return m_items; } + ITEMS& Items() { return m_items; } + const ITEMS& CItems() const { return m_items; } - PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1 ); - PNS_ITEMSET& FilterKinds( int aKindMask ); - PNS_ITEMSET& FilterNet( int aNet ); + PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false ); + PNS_ITEMSET& FilterKinds( int aKindMask, bool aInvert = false ); + PNS_ITEMSET& FilterNet( int aNet, bool aInvert = false ); - int Size() { return m_items.size(); } + PNS_ITEMSET& ExcludeLayers( int aStart, int aEnd = -1 ) + { + return FilterLayers( aStart, aEnd, true ); + } + + PNS_ITEMSET& ExcludeKinds( int aKindMask ) + { + return FilterKinds ( aKindMask, true ); + } + + PNS_ITEMSET& ExcludeNet( int aNet ) + { + return FilterNet ( aNet, true ); + } + + PNS_ITEMSET& ExcludeItem ( const PNS_ITEM *aItem ); + + int Size() const + { + return m_items.size(); + } void Add( PNS_ITEM* aItem ) { - m_items.push_back( aItem ); + m_items.push_back ( aItem ); } - PNS_ITEM* Get( int index ) const { return m_items[index]; } + PNS_ITEM* Get( int index ) const + { + return m_items[index]; + } - void Clear(); - - void AddOwned( PNS_ITEM *aItem ) + PNS_ITEM* operator[] (int index ) const { - m_items.push_back( aItem ); - m_ownedItems.push_back( aItem ); + return m_items[index]; + } + + void Clear() + { + m_items.clear(); + } + + bool Contains ( const PNS_ITEM *aItem ) const + { + return std::find ( m_items.begin(), m_items.end(), aItem ) != m_items.end(); + } + + void Erase ( const PNS_ITEM *aItem ) + { + ITEMS::iterator f = std::find (m_items.begin(), m_items.end(), aItem ); + + if( f != m_items.end() ) + m_items.erase ( f ); } private: - ITEM_VECTOR m_items; - ITEM_VECTOR m_ownedItems; + ITEMS m_items; }; #endif diff --git a/pcbnew/router/pns_joint.h b/pcbnew/router/pns_joint.h index bcac27d356..bb396d0c8c 100644 --- a/pcbnew/router/pns_joint.h +++ b/pcbnew/router/pns_joint.h @@ -28,6 +28,7 @@ #include "pns_item.h" #include "pns_segment.h" +#include "pns_itemset.h" /** * Class PNS_JOINT @@ -81,7 +82,7 @@ public: /// segments of the same net, on the same layer. bool IsLineCorner() const { - if( m_linkedItems.size() != 2 ) + if( m_linkedItems.Size() != 2 ) return false; if( m_linkedItems[0]->Kind() != SEGMENT || m_linkedItems[1]->Kind() != SEGMENT ) @@ -97,24 +98,18 @@ public: ///> Links the joint to a given board item (when it's added to the PNS_NODE) void Link( PNS_ITEM* aItem ) { - LINKED_ITEMS::iterator f = std::find( m_linkedItems.begin(), m_linkedItems.end(), aItem ); - - if( f != m_linkedItems.end() ) + if (m_linkedItems.Contains( aItem )) return; - m_linkedItems.push_back( aItem ); + m_linkedItems.Add ( aItem ); } ///> Unlinks a given board item from the joint (upon its removal from a PNS_NODE) ///> Returns true if the joint became dangling after unlinking. bool Unlink( PNS_ITEM* aItem ) { - LINKED_ITEMS::iterator f = std::find( m_linkedItems.begin(), m_linkedItems.end(), aItem ); - - if( f != m_linkedItems.end() ) - f = m_linkedItems.erase( f ); - - return m_linkedItems.size() == 0; + m_linkedItems.Erase ( aItem ); + return m_linkedItems.Size() == 0; } ///> For trivial joints, returns the segment adjacent to (aCurrent). For non-trival ones, returns @@ -127,16 +122,6 @@ public: return static_cast( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] ); } - PNS_VIA* Via() - { - for( LINKED_ITEMS::iterator i = m_linkedItems.begin(); i != m_linkedItems.end(); ++i ) - { - if( (*i)->Kind() == PNS_ITEM::VIA ) - return (PNS_VIA*)( *i ); - } - - return NULL; - } /// trivial accessors const HASH_TAG& Tag() const @@ -154,26 +139,27 @@ public: return m_tag.net; } - LINKED_ITEMS& LinkList() + const LINKED_ITEMS& LinkList() const { - return m_linkedItems; + return m_linkedItems.CItems(); + } + + const PNS_ITEMSET& CLinks() const + { + return m_linkedItems; + } + + PNS_ITEMSET Links() const + { + return m_linkedItems; } - ///> Returns the number of linked items of types listed in aMask. int LinkCount( int aMask = -1 ) const { - int n = 0; - - for( LINKED_ITEMS::const_iterator i = m_linkedItems.begin(); - i != m_linkedItems.end(); ++i ) - { - if( (*i)->Kind() & aMask ) - n++; - } - - return n; + return m_linkedItems.Count( aMask ); } + void Dump() const; bool operator==( const PNS_JOINT& rhs ) const @@ -188,11 +174,9 @@ public: m_layers.Merge( aJoint.m_layers ); - // fixme: duplicate links (?) - for( LINKED_ITEMS::const_iterator i = aJoint.m_linkedItems.begin(); - i != aJoint.m_linkedItems.end(); ++i ) + BOOST_FOREACH ( PNS_ITEM *item, aJoint.LinkList() ) { - m_linkedItems.push_back( *i ); + m_linkedItems.Add (item); } } @@ -207,7 +191,7 @@ private: HASH_TAG m_tag; ///> list of items linked to this joint - LINKED_ITEMS m_linkedItems; + PNS_ITEMSET m_linkedItems; }; diff --git a/pcbnew/router/pns_layerset.h b/pcbnew/router/pns_layerset.h index aed8761365..c319ea3969 100644 --- a/pcbnew/router/pns_layerset.h +++ b/pcbnew/router/pns_layerset.h @@ -108,7 +108,7 @@ public: ///> Shortcut for comparisons/overlap tests static PNS_LAYERSET All() { - return PNS_LAYERSET( 0, 64 ); + return PNS_LAYERSET( 0, 256 ); // fixme: use layer IDs header } private: diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp index 933be48750..f56b66c793 100644 --- a/pcbnew/router/pns_line_placer.cpp +++ b/pcbnew/router/pns_line_placer.cpp @@ -40,10 +40,10 @@ PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) : PNS_ALGO_BASE ( aRouter ) { m_initial_direction = DIRECTION_45::N; - m_iteration = 0; m_world = NULL; m_shove = NULL; m_currentNode = NULL; + m_idle = true; } @@ -59,52 +59,22 @@ void PNS_LINE_PLACER::setWorld ( PNS_NODE* aWorld ) m_world = aWorld; } - -void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill, VIATYPE_T aType ) +const PNS_VIA PNS_LINE_PLACER::makeVia ( const VECTOR2I& aP ) +{ + const PNS_LAYERSET layers( m_sizes.GetLayerTop(), m_sizes.GetLayerBottom() ); + + return PNS_VIA ( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), -1, m_sizes.ViaType() ); +} + + +void PNS_LINE_PLACER::ToggleVia( bool aEnabled ) { - m_viaDiameter = aDiameter; - m_viaDrill = aDrill; m_placingVia = aEnabled; - m_viaType = aType; + if(!m_idle) + Move ( m_currentEnd, NULL ); } -void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet, int aWidth, int aLayer ) -{ - assert( m_world != NULL ); - - m_direction = m_initial_direction; - TRACE( 1, "world %p, initial-direction %s layer %d\n", - m_world % m_direction.Format().c_str() % aLayer ); - m_head.SetNet( aNet ); - m_tail.SetNet( aNet ); - m_head.SetWidth( aWidth ); - m_tail.SetWidth( aWidth ); - m_head.Line().Clear(); - m_tail.Line().Clear(); - m_head.SetLayer( aLayer ); - m_tail.SetLayer( aLayer ); - m_iteration = 0; - m_p_start = aStart; - - m_lastNode = NULL; - m_currentNode = m_world; - - m_currentMode = Settings().Mode(); - - if( m_shove ) - delete m_shove; - - m_shove = NULL; - - if( m_currentMode == RM_Shove || m_currentMode == RM_Smart ) - { - m_shove = new PNS_SHOVE( m_world->Branch(), Router() ); - } - - m_placingVia = false; -} - void PNS_LINE_PLACER::setInitialDirection( const DIRECTION_45& aDirection ) { @@ -380,8 +350,9 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead ) if( !m_placingVia ) return true; - PNS_LAYERSET layers( Settings().GetLayerTop(), Settings().GetLayerBottom() ); - PNS_VIA v( aHead.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, aHead.Net(), m_viaType ); + PNS_VIA v ( makeVia ( aHead.CPoint( -1 ) ) ); + v.SetNet ( aHead.Net() ); + VECTOR2I force; VECTOR2I lead = aHead.CPoint( -1 ) - aHead.CPoint( 0 ); @@ -440,9 +411,7 @@ bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead ) } else if( m_placingVia && viaOk ) { - PNS_LAYERSET layers( Settings().GetLayerTop(), Settings().GetLayerBottom() ); - PNS_VIA v1( walkFull.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, -1, m_viaType ); - walkFull.AppendVia( v1 ); + walkFull.AppendVia( makeVia ( walkFull.CPoint( -1 ) ) ); } PNS_OPTIMIZER::Optimize( &walkFull, effort, m_currentNode ); @@ -465,9 +434,7 @@ bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead ) if( m_placingVia ) { - PNS_LAYERSET layers( Settings().GetLayerTop(), Settings().GetLayerBottom() ); - PNS_VIA v1( m_head.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, -1, m_viaType ); - m_head.AppendVia( v1 ); + m_head.AppendVia( makeVia ( m_head.CPoint( -1 ) ) ); } aNewHead = m_head; @@ -508,9 +475,8 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) if( m_placingVia ) { - PNS_LAYERSET layers( Settings().GetLayerTop(), Settings().GetLayerBottom() ); - PNS_VIA v1( l.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, -1, m_viaType ); - PNS_VIA v2( l2.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, -1, m_viaType ); + PNS_VIA v1( makeVia ( l.CPoint( -1 ) ) ); + PNS_VIA v2( makeVia ( l2.CPoint( -1 ) ) ); l.AppendVia( v1 ); l2.AppendVia( v2 ); @@ -759,15 +725,24 @@ void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, co } -void PNS_LINE_PLACER::SetLayer( int aLayer ) +bool PNS_LINE_PLACER::SetLayer( int aLayer ) { - m_currentLayer = aLayer; + if(m_idle) + { + m_currentLayer = aLayer; + return true; + } else if (m_chainedPlacement) { + return false; + } else if (!m_startItem || (m_startItem->OfKind(PNS_ITEM::VIA) && m_startItem->Layers().Overlaps( aLayer ))) { + m_currentLayer = aLayer; + initPlacement ( ); + Move ( m_currentEnd, NULL ); + return true; + } - m_head.SetLayer( aLayer ); - m_tail.SetLayer( aLayer ); + return false; } - void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) { VECTOR2I p( aP ); @@ -775,10 +750,6 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) static int unknowNetIdx = 0; // -10000; int net = -1; - m_lastNode = NULL; - m_placingVia = false; - m_startsOnVia = false; - bool splitSeg = false; if( Router()->SnappingEnabled() ) @@ -789,19 +760,60 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) else net = aStartItem->Net(); - m_currentStart = p; - m_originalStart = p; + m_currentStart = p; m_currentEnd = p; m_currentNet = net; + m_startItem = aStartItem; + m_placingVia = false; + m_chainedPlacement = false; - PNS_NODE* rootNode = Router()->GetWorld()->Branch(); - - if( splitSeg ) - splitAdjacentSegments( rootNode, aStartItem, p ); - - setWorld( rootNode ); setInitialDirection( Settings().InitialDirection() ); - startPlacement( p, m_currentNet, m_currentWidth, m_currentLayer ); + + initPlacement( splitSeg ); +} + +void PNS_LINE_PLACER::initPlacement( bool aSplitSeg ) +{ + m_idle = false; + + m_head.Line().Clear(); + m_tail.Line().Clear(); + m_head.SetNet( m_currentNet ); + m_tail.SetNet( m_currentNet ); + m_head.SetLayer( m_currentLayer ); + m_tail.SetLayer( m_currentLayer ); + m_head.SetWidth( m_sizes.TrackWidth() ); + m_tail.SetWidth( m_sizes.TrackWidth() ); + + m_p_start = m_currentStart; + m_direction = m_initial_direction; + + PNS_NODE *world = Router()->GetWorld(); + + world->KillChildren(); + PNS_NODE* rootNode = world->Branch(); + + if( aSplitSeg ) + splitAdjacentSegments( rootNode, m_startItem, m_currentStart ); + + setWorld( rootNode ); + + TRACE( 1, "world %p, intitial-direction %s layer %d\n", + m_world % m_direction.Format().c_str() % aLayer ); + + m_lastNode = NULL; + m_currentNode = m_world; + m_currentMode = Settings().Mode(); + + if( m_shove ) + delete m_shove; + + m_shove = NULL; + + if( m_currentMode == RM_Shove || m_currentMode == RM_Smart ) + { + m_shove = new PNS_SHOVE( m_world->Branch(), Router() ); + } } @@ -902,25 +914,13 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) if( !realEnd ) { setInitialDirection( d_last ); - VECTOR2I p_start = m_placingVia ? p_last : p_pre_last; - - if( m_placingVia ) - { - int layerTop = Router()->Settings().GetLayerTop(); - int layerBottom = Router()->Settings().GetLayerBottom(); - - // Change the current layer to the other side of the board - if( m_currentLayer == layerTop ) - m_currentLayer = layerBottom; - else - m_currentLayer = layerTop; - } - - setWorld( Router()->GetWorld()->Branch() ); - startPlacement( p_start, m_head.Net(), m_head.Width(), m_currentLayer ); - - m_startsOnVia = m_placingVia; + m_currentStart = m_placingVia ? p_last : p_pre_last; + m_startItem = NULL; m_placingVia = false; + m_chainedPlacement = !pl.EndsWithVia(); + initPlacement(); + } else { + m_idle = true; } return realEnd; @@ -995,16 +995,14 @@ void PNS_LINE_PLACER::simplifyNewLine( PNS_NODE* aNode, PNS_SEGMENT* aLatest ) } -void PNS_LINE_PLACER::UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings ) +void PNS_LINE_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes ) { - int trackWidth = aSettings.GetTrackWidth(); - - m_head.SetWidth( trackWidth ); - m_tail.SetWidth( trackWidth ); - - m_currentWidth = trackWidth; - m_viaDiameter = aSettings.GetViaDiameter(); - m_viaDrill = aSettings.GetViaDrill(); + m_sizes = aSizes; + if( !m_idle ) + { + initPlacement ( ); + Move ( m_currentEnd, NULL ); + } } diff --git a/pcbnew/router/pns_line_placer.h b/pcbnew/router/pns_line_placer.h index dfbb1bb619..487dd1c99c 100644 --- a/pcbnew/router/pns_line_placer.h +++ b/pcbnew/router/pns_line_placer.h @@ -26,6 +26,7 @@ #include #include +#include "pns_sizes_settings.h" #include "pns_node.h" #include "pns_via.h" #include "pns_line.h" @@ -35,6 +36,9 @@ class PNS_ROUTER; class PNS_SHOVE; class PNS_OPTIMIZER; class PNS_ROUTER_BASE; +class PNS_VIA; +class PNS_SIZES_SETTINGS; + /** * Class PNS_LINE_PLACER @@ -78,29 +82,19 @@ public: bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ); /** - * Function AddVia() + * Function ToggleVia() * * Enables/disables a via at the end of currently routed trace. - * @param aEnabled if true, a via is attached during placement - * @param aDiameter diameter of the via - * @param aDrill drill of the via - * @param aType Type of the via */ - void AddVia( bool aEnabled, int aDiameter, int aDrill, VIATYPE_T aType ); + void ToggleVia( bool aEnabled ); /** * Function SetLayer() * * Sets the current routing layer. */ - void SetLayer( int aLayer ); + bool SetLayer( int aLayer ); - /** - * Function SetWidth() - * - * Sets the current track width. - */ - void SetWidth( int aWidth ); /** * Function Head() @@ -184,8 +178,9 @@ public: * a settings class. Used to dynamically change these parameters as * the track is routed. */ - void UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings ); + void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes ); + bool IsPlacingVia() const { return m_placingVia; } private: /** * Function route() @@ -220,7 +215,7 @@ private: * * Initializes placement of a new line with given parameters. */ - void startPlacement( const VECTOR2I& aStart, int aNet, int aWidth, int aLayer ); + void initPlacement( bool aSplitSeg = false ); /** * Function setInitialDirection() @@ -346,7 +341,9 @@ private: ///> route step, mark obstacles mode bool rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead ); - + + const PNS_VIA makeVia ( const VECTOR2I& aP ); + ///> current routing direction DIRECTION_45 m_direction; @@ -378,6 +375,8 @@ private: ///> Postprocessed world state (including marked collisions & removed loops) PNS_NODE* m_lastNode; + PNS_SIZES_SETTINGS m_sizes; + ///> Are we placing a via? bool m_placingVia; @@ -387,9 +386,6 @@ private: ///> current via drill int m_viaDrill; - ///> current via type - VIATYPE_T m_viaType; - ///> current track width int m_currentWidth; @@ -398,10 +394,14 @@ private: bool m_startsOnVia; - VECTOR2I m_originalStart, m_currentEnd, m_currentStart; + VECTOR2I m_currentEnd, m_currentStart; PNS_LINE m_currentTrace; PNS_MODE m_currentMode; + PNS_ITEM *m_startItem; + + bool m_idle; + bool m_chainedPlacement; }; #endif // __PNS_LINE_PLACER_H diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 4dbde1ebbf..4a0d8be6c5 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -121,7 +121,6 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) switch( aPad->GetAttribute() ) { case PAD_STANDARD: - layers = PNS_LAYERSET( 0, MAX_CU_LAYERS - 1 ); // TODO necessary? it is already initialized break; case PAD_SMD: @@ -249,31 +248,6 @@ void PNS_ROUTER::SetBoard( BOARD* aBoard ) TRACE( 1, "m_board = %p\n", m_board ); } - -int PNS_ROUTER::NextCopperLayer( bool aUp ) -{ - LSET mask = m_board->GetEnabledLayers() & m_board->GetVisibleLayers(); - LAYER_NUM l = m_currentLayer; - - do - { - l += ( aUp ? 1 : -1 ); - - if( l >= MAX_CU_LAYERS ) - l = 0; - - if( l < 0 ) - l = MAX_CU_LAYERS - 1; - - if( mask[l] ) - return l; - } - while( l != m_currentLayer ); - - return l; -} - - void PNS_ROUTER::SyncWorld() { if( !m_board ) @@ -324,10 +298,6 @@ PNS_ROUTER::PNS_ROUTER() m_clearanceFunc = NULL; - m_currentLayer = 1; - m_placingVia = false; - m_startsOnVia = false; - m_currentNet = -1; m_state = IDLE; m_world = NULL; m_placer = NULL; @@ -483,51 +453,21 @@ bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem ) return true; } - -bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem ) +bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLayer ) { - m_state = ROUTE_TRACK; - m_placer = new PNS_LINE_PLACER( this ); - m_placer->SetLayer( m_currentLayer ); - - const BOARD_DESIGN_SETTINGS& dsnSettings = m_board->GetDesignSettings(); - - if( dsnSettings.UseNetClassTrack() && aStartItem != NULL ) // netclass value - { - m_settings.SetTrackWidth( aStartItem->Parent()->GetNetClass()->GetTrackWidth() ); - } - else - { - m_settings.SetTrackWidth( dsnSettings.GetCurrentTrackWidth() ); - } - - if( dsnSettings.UseNetClassVia() && aStartItem != NULL ) // netclass value - { - m_settings.SetViaDiameter( aStartItem->Parent()->GetNetClass()->GetViaDiameter() ); - m_settings.SetViaDrill( aStartItem->Parent()->GetNetClass()->GetViaDrill() ); - } - else - { - m_settings.SetViaDiameter( dsnSettings.GetCurrentViaSize() ); - m_settings.SetViaDrill( dsnSettings.GetCurrentViaDrill() ); - } - - m_placer->UpdateSizes( m_settings ); + + m_placer->UpdateSizes ( m_sizes ); + m_placer->SetLayer( aLayer ); m_placer->Start( aP, aStartItem ); + m_currentEnd = aP; m_currentEndItem = NULL; + m_state = ROUTE_TRACK; return true; } - -const VECTOR2I PNS_ROUTER::CurrentEnd() const -{ - return m_currentEnd; -} - - void PNS_ROUTER::eraseView() { BOOST_FOREACH( BOARD_ITEM* item, m_hiddenItems ) @@ -689,13 +629,14 @@ void PNS_ROUTER::updateView( PNS_NODE* aNode, PNS_ITEMSET& aCurrent ) } -void PNS_ROUTER::ApplySettings() +void PNS_ROUTER::UpdateSizes ( const PNS_SIZES_SETTINGS& aSizes ) { + m_sizes = aSizes; + // Change track/via size settings if( m_state == ROUTE_TRACK) { - m_placer->UpdateSizes( m_settings ); - m_placer->Move( m_currentEnd, m_currentEndItem ); + m_placer->UpdateSizes( m_sizes ); movePlacing( m_currentEnd, m_currentEndItem ); } } @@ -791,26 +732,6 @@ void PNS_ROUTER::CommitRouting( PNS_NODE* aNode ) } -PNS_VIA* PNS_ROUTER::checkLoneVia( PNS_JOINT* aJoint ) const -{ - PNS_VIA* theVia = NULL; - PNS_LAYERSET l; - - BOOST_FOREACH( PNS_ITEM* item, aJoint->LinkList() ) - { - if( item->Kind() == PNS_ITEM::VIA ) - theVia = static_cast( item ); - - l.Merge( item->Layers() ); - } - - if( l.Start() == l.End() ) - return theVia; - - return NULL; -} - - bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) { bool rv = false; @@ -819,8 +740,6 @@ bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) { case ROUTE_TRACK: rv = m_placer->FixRoute( aP, aEndItem ); - m_startsOnVia = m_placingVia; - m_placingVia = false; break; case DRAG_SEGMENT: @@ -841,7 +760,17 @@ bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) void PNS_ROUTER::StopRouting() { // Update the ratsnest with new changes - m_board->GetRatsnest()->Recalculate( m_currentNet ); + if(m_placer) + { + int n = m_placer->CurrentNet(); + + if( n >= 0) + { + // Update the ratsnest with new changes + m_board->GetRatsnest()->Recalculate( n ); + } + } + if( !RoutingInProgress() ) return; @@ -868,7 +797,7 @@ void PNS_ROUTER::FlipPosture() if( m_state == ROUTE_TRACK ) { m_placer->FlipPosture(); - m_placer->Move( m_currentEnd, m_currentEndItem ); + movePlacing ( m_currentEnd, m_currentEndItem ); } } @@ -877,80 +806,42 @@ void PNS_ROUTER::SwitchLayer( int aLayer ) { switch( m_state ) { - case IDLE: - m_currentLayer = aLayer; - break; - - case ROUTE_TRACK: - if( m_startsOnVia ) - { - m_currentLayer = aLayer; + case ROUTE_TRACK: m_placer->SetLayer( aLayer ); - } - break; - - default: - break; + break; + default: + break; } } -void PNS_ROUTER::ToggleViaPlacement(VIATYPE_T type) +void PNS_ROUTER::ToggleViaPlacement() { - const int layercount = m_board->GetDesignSettings().GetCopperLayerCount(); - - // Cannot place microvias or blind vias if not allowed (obvious) - if( ( type == VIA_BLIND_BURIED ) && ( !m_board->GetDesignSettings().m_BlindBuriedViaAllowed ) ) - return; - if( ( type == VIA_MICROVIA ) && ( !m_board->GetDesignSettings().m_MicroViasAllowed ) ) - return; - - //Can only place through vias on 2-layer boards - if( ( type != VIA_THROUGH ) && ( layercount <= 2 ) ) - return; - - //Can only place microvias if we're on an outer layer, or directly adjacent to one - if( ( type == VIA_MICROVIA ) && ( m_currentLayer > In1_Cu ) && ( m_currentLayer < layercount-2 ) ) - return; - - //Cannot place blind vias with front/back as the layer pair, this doesn't make sense - if( ( type == VIA_BLIND_BURIED ) && ( Settings().GetLayerTop() == F_Cu ) && ( Settings().GetLayerBottom() == B_Cu ) ) - return; - - if( m_state == ROUTE_TRACK ) + if( m_state == ROUTE_TRACK ) { - m_placingVia = !m_placingVia; - m_placer->AddVia( m_placingVia, m_settings.GetViaDiameter(), m_settings.GetViaDrill(), type ); + bool toggle = !m_placer->IsPlacingVia(); + m_placer->ToggleVia( toggle ); } } int PNS_ROUTER::GetCurrentNet() const { - switch( m_state ) - { - case ROUTE_TRACK: - return m_placer->CurrentNet(); - - default: - return m_currentNet; - } + if(m_placer) + return m_placer->CurrentNet(); + return -1; } int PNS_ROUTER::GetCurrentLayer() const { - switch( m_state ) - { - case ROUTE_TRACK: - return m_placer->CurrentLayer(); - - default: - return m_currentLayer; - } + if( m_placer ) + return m_placer->CurrentLayer(); + return -1; } + void PNS_ROUTER::DumpLog() { PNS_LOGGER* logger = NULL; @@ -968,3 +859,11 @@ void PNS_ROUTER::DumpLog() if( logger ) logger->Save( "/tmp/shove.log" ); } + +bool PNS_ROUTER::IsPlacingVia() const +{ + if(!m_placer) + return NULL; + return m_placer->IsPlacingVia(); +} + diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index dd6c6b9694..0b381d828a 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -30,6 +30,7 @@ #include #include "pns_routing_settings.h" +#include "pns_sizes_settings.h" #include "pns_item.h" #include "pns_itemset.h" #include "pns_node.h" @@ -86,13 +87,12 @@ public: void SetView( KIGFX::VIEW* aView ); bool RoutingInProgress() const; - bool StartRouting( const VECTOR2I& aP, PNS_ITEM* aItem ); + bool StartRouting( const VECTOR2I& aP, PNS_ITEM* aItem, int aLayer ); void Move( const VECTOR2I& aP, PNS_ITEM* aItem ); bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aItem ); void StopRouting(); - const VECTOR2I CurrentEnd() const; int GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const; @@ -112,7 +112,7 @@ public: void SwitchLayer( int layer ); - void ToggleViaPlacement( VIATYPE_T type = VIA_NOT_DEFINED ); + void ToggleViaPlacement(); int GetCurrentLayer() const; int GetCurrentNet() const; @@ -123,15 +123,7 @@ public: { return m_clearanceFunc; } - - bool IsPlacingVia() const - { - return m_placingVia; - } - - int NextCopperLayer( bool aUp ); - - // typedef boost::optional optHoverItem; + bool IsPlacingVia() const; const PNS_ITEMSET QueryHoverItems( const VECTOR2I& aP ); const VECTOR2I SnapToItem( PNS_ITEM* aItem, VECTOR2I aP, bool& aSplitsSegment ); @@ -175,7 +167,7 @@ public: * Applies stored settings. * @see Settings() */ - void ApplySettings(); + void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes ); /** * Changes routing settings to ones passed in the parameter. @@ -184,8 +176,6 @@ public: void LoadSettings( const PNS_ROUTING_SETTINGS& aSettings ) { m_settings = aSettings; - - ApplySettings(); } void EnableSnapping( bool aEnable ) @@ -198,6 +188,11 @@ public: return m_snappingEnabled; } + PNS_SIZES_SETTINGS& Sizes() + { + return m_sizes; + } + private: void movePlacing( const VECTOR2I& aP, PNS_ITEM* aItem ); void moveDragging( const VECTOR2I& aP, PNS_ITEM* aItem ); @@ -211,7 +206,6 @@ private: PNS_ITEM* pickSingleItem( PNS_ITEMSET& aItems ) const; void splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP ); - PNS_VIA* checkLoneVia( PNS_JOINT* aJoint ) const; PNS_ITEM* syncPad( D_PAD* aPad ); PNS_ITEM* syncTrack( TRACK* aTrack ); @@ -225,9 +219,7 @@ private: void markViolations( PNS_NODE* aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ITEM_VECTOR& aRemoved ); - int m_currentLayer; - int m_currentNet; - + VECTOR2I m_currentEnd; RouterState m_state; BOARD* m_board; @@ -235,9 +227,7 @@ private: PNS_NODE* m_lastNode; PNS_LINE_PLACER* m_placer; PNS_DRAGGER* m_dragger; - PNS_LINE* m_draggedLine; PNS_SHOVE* m_shove; - int m_draggedSegmentIndex; int m_iterLimit; bool m_showInterSteps; int m_snapshotIter; @@ -247,11 +237,6 @@ private: PNS_ITEM* m_currentEndItem; - VECTOR2I m_currentEnd; - VECTOR2I m_currentStart; - VECTOR2I m_originalStart; - bool m_placingVia; - bool m_startsOnVia; bool m_snappingEnabled; bool m_violation; @@ -264,6 +249,7 @@ private: ///> Stores list of modified items in the current operation PICKED_ITEMS_LIST m_undoBuffer; + PNS_SIZES_SETTINGS m_sizes; }; #endif diff --git a/pcbnew/router/pns_routing_settings.h b/pcbnew/router/pns_routing_settings.h index a1261f7155..1a7030be21 100644 --- a/pcbnew/router/pns_routing_settings.h +++ b/pcbnew/router/pns_routing_settings.h @@ -21,6 +21,8 @@ #ifndef __PNS_ROUTING_SETTINGS #define __PNS_ROUTING_SETTINGS +#include + #include "time_limit.h" class DIRECTION_45; @@ -112,13 +114,6 @@ public: bool CanViolateDRC() const { return m_canViolateDRC; } void SetCanViolateDRC( bool aViolate ) { m_canViolateDRC = aViolate; } - void SetTrackWidth( int aWidth ) { m_trackWidth = aWidth; } - int GetTrackWidth() const { return m_trackWidth; } - void SetViaDiameter( int aDiameter ) { m_viaDiameter = aDiameter; } - int GetViaDiameter() const { return m_viaDiameter; } - void SetViaDrill( int aDrill ) { m_viaDrill = aDrill; } - int GetViaDrill() const { return m_viaDrill; } - const DIRECTION_45 InitialDirection() const; int ShoveIterationLimit() const; @@ -127,22 +122,6 @@ public: int WalkaroundIterationLimit() const { return m_walkaroundIterationLimit; }; TIME_LIMIT WalkaroundTimeLimit() const; - void SetLayerPair( int aLayer1, int aLayer2 ) - { - if( aLayer1 < aLayer2 ) - { - m_layerTop = aLayer1; - m_layerBottom = aLayer2; - } - else - { - m_layerBottom = aLayer1; - m_layerTop = aLayer2; - } - } - - int GetLayerTop() const { return m_layerTop; } - int GetLayerBottom() const { return m_layerBottom; } private: bool m_shoveVias; @@ -158,19 +137,11 @@ private: PNS_MODE m_routingMode; PNS_OPTIMIZATION_EFFORT m_optimizerEffort; - int m_trackWidth; - int m_viaDiameter; - int m_viaDrill; - int m_preferredLayer; int m_walkaroundIterationLimit; int m_shoveIterationLimit; TIME_LIMIT m_shoveTimeLimit; TIME_LIMIT m_walkaroundTimeLimit; - - // Routing layers pair - int m_layerTop; - int m_layerBottom; }; #endif diff --git a/pcbnew/router/pns_sizes_settings.cpp b/pcbnew/router/pns_sizes_settings.cpp new file mode 100644 index 0000000000..f2ab01a3be --- /dev/null +++ b/pcbnew/router/pns_sizes_settings.cpp @@ -0,0 +1,159 @@ +/* + * KiRouter - a push-and-(sometimes-)shove PCB router + * + * Copyright (C) 2014 CERN + * Author: Tomasz Wlostowski + * + * 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 3 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, see . + */ + +#include + +#include "pns_item.h" +#include "pns_via.h" +#include "pns_solid.h" +#include "pns_node.h" +#include "pns_sizes_settings.h" + +int PNS_SIZES_SETTINGS::inheritTrackWidth( PNS_ITEM* aItem ) +{ + VECTOR2I p; + + assert( aItem->Owner() != NULL ); + + switch( aItem->Kind() ) + { + case PNS_ITEM::VIA: + p = static_cast( aItem )->Pos(); + break; + + case PNS_ITEM::SOLID: + p = static_cast( aItem )->Pos(); + break; + + case PNS_ITEM::SEGMENT: + return static_cast( aItem )->Width(); + + default: + return 0; + } + + PNS_JOINT* jt = aItem->Owner()->FindJoint( p, aItem ); + + assert( jt != NULL ); + + int mval = INT_MAX; + + PNS_ITEMSET linkedSegs = jt->Links().ExcludeItem( aItem ).FilterKinds( PNS_ITEM::SEGMENT ); + + BOOST_FOREACH( PNS_ITEM* item, linkedSegs.Items() ) + { + int w = static_cast( item )->Width(); + mval = std::min( w, mval ); + } + + return ( mval == INT_MAX ? 0 : mval ); +} + +void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet ) +{ + BOARD_DESIGN_SETTINGS &bds = aBoard->GetDesignSettings(); + + NETCLASSPTR netClass; + int net = aNet; + + if( aStartItem ) + net = aStartItem->Net(); + + if( net >= 0 ) + { + NETINFO_ITEM* ni = aBoard->FindNet( net ); + + if( ni ) + { + wxString netClassName = ni->GetClassName(); + netClass = bds.m_NetClasses.Find( netClassName ); + } + } + + if( !netClass ) + netClass = bds.GetDefault(); + + m_trackWidth = 0; + + if( bds.m_UseConnectedTrackWidth && aStartItem != NULL ) + { + m_trackWidth = inheritTrackWidth( aStartItem ); + } + + if( !m_trackWidth && ( bds.UseNetClassTrack() && netClass != NULL ) ) // netclass value + { + m_trackWidth = netClass->GetTrackWidth(); + } + + if( !m_trackWidth ) + { + m_trackWidth = bds.GetCurrentTrackWidth(); + } + + if( bds.UseNetClassVia() && netClass != NULL ) // netclass value + { + m_viaDiameter = netClass->GetViaDiameter(); + m_viaDrill = netClass->GetViaDrill(); + } + else + { + m_viaDiameter = bds.GetCurrentViaSize(); + m_viaDrill = bds.GetCurrentViaDrill(); + } + + m_layerPairs.clear(); +} + +void PNS_SIZES_SETTINGS::ClearLayerPairs() +{ + m_layerPairs.clear(); +} + +void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 ) +{ + int top = std::min( aL1, aL2 ); + int bottom = std::max( aL1, aL2 ); + + m_layerPairs[bottom] = top; + m_layerPairs[top] = bottom; +} + +void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings ) +{ + m_trackWidth = aSettings.GetCurrentTrackWidth(); + m_viaDiameter = aSettings.GetCurrentViaSize(); + m_viaDrill = aSettings.GetCurrentViaDrill(); +} + +int PNS_SIZES_SETTINGS::GetLayerTop() const +{ + if( m_layerPairs.empty() ) + return F_Cu; + else + return m_layerPairs.begin()->first; +} + +int PNS_SIZES_SETTINGS::GetLayerBottom() const +{ + if( m_layerPairs.empty() ) + return B_Cu; + else + return m_layerPairs.begin()->second; +} diff --git a/pcbnew/router/pns_sizes_settings.h b/pcbnew/router/pns_sizes_settings.h new file mode 100644 index 0000000000..db8d3b3a74 --- /dev/null +++ b/pcbnew/router/pns_sizes_settings.h @@ -0,0 +1,95 @@ +/* + * KiRouter - a push-and-(sometimes-)shove PCB router + * + * Copyright (C) 2014 CERN + * Author: Tomasz Wlostowski + * + * 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 3 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, see . + */ + +#ifndef __PNS_SIZES_SETTINGS_H +#define __PNS_SIZES_SETTINGS_H + +#include +#include + +#include "../class_track.h" // for VIATYPE_T + +class BOARD; +class BOARD_DESIGN_SETTINGS; +class PNS_ITEM; + +class PNS_SIZES_SETTINGS { + +public: + PNS_SIZES_SETTINGS() : + m_trackWidth( 100000 ), + m_diffPairWidth( 100000 ), + m_diffPairGap( 125000 ), + m_viaDiameter( 500000 ), + m_viaDrill( 200000 ), + m_viaType( VIA_THROUGH ) + {}; + + ~PNS_SIZES_SETTINGS() {}; + + void Init( BOARD* aBoard, PNS_ITEM* aStartItem = NULL, int aNet = -1 ); + void ImportCurrent ( BOARD_DESIGN_SETTINGS& aSettings ); + + void ClearLayerPairs(); + void AddLayerPair( int aL1, int aL2 ); + + int TrackWidth() const { return m_trackWidth; } + void SetTrackWidth( int aWidth ) { m_trackWidth = aWidth; } + + int DiffPairWidth() const { return m_diffPairWidth; } + + int DiffPairGap() const { return m_diffPairGap; } + + int ViaDiameter() const { return m_viaDiameter; } + void SetViaDiameter( int aDiameter) { m_viaDiameter = aDiameter; } + + int ViaDrill() const { return m_viaDrill; } + void SetViaDrill( int aDrill ) { m_viaDrill = aDrill; } + + boost::optional PairedLayer ( int aLayerId ) + { + if( m_layerPairs.find(aLayerId) == m_layerPairs.end() ) + return boost::optional(); + + return m_layerPairs [ aLayerId ]; + } + + int GetLayerTop() const; + int GetLayerBottom() const; + + void SetViaType( VIATYPE_T aViaType ) { m_viaType = aViaType; } + VIATYPE_T ViaType() const { return m_viaType; } + +private: + + int inheritTrackWidth( PNS_ITEM *aItem ); + + int m_trackWidth; + int m_diffPairWidth; + int m_diffPairGap; + int m_viaDiameter; + int m_viaDrill; + + VIATYPE_T m_viaType; + + std::map m_layerPairs; +}; + +#endif // __PNS_SIZES_SETTINGS_H diff --git a/pcbnew/router/pns_via.h b/pcbnew/router/pns_via.h index 86dc2c0503..91bcd79ca9 100644 --- a/pcbnew/router/pns_via.h +++ b/pcbnew/router/pns_via.h @@ -53,7 +53,7 @@ public: if( aViaType == VIA_THROUGH ) { PNS_LAYERSET allLayers( 0, MAX_CU_LAYERS - 1 ); - SetLayers( allLayers); + SetLayers( allLayers ); } } diff --git a/pcbnew/router/router_preview_item.cpp b/pcbnew/router/router_preview_item.cpp index 83e0a2f3a2..e375a8d7e5 100644 --- a/pcbnew/router/router_preview_item.cpp +++ b/pcbnew/router/router_preview_item.cpp @@ -81,6 +81,7 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem ) } case PNS_ITEM::VIA: + m_originLayer = m_layer = ITEM_GAL_LAYER( VIAS_VISIBLE ); m_type = PR_SHAPE; m_width = 0; m_color = COLOR4D( 0.7, 0.7, 0.7, 0.8 ); diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index bbf758be5a..c88ec52d98 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -377,6 +378,9 @@ void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode ) void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent ) { + PCB_EDIT_FRAME* frame = getEditFrame (); + BOARD *board = getModel (); + #ifdef DEBUG if( aEvent.IsKeyPressed() ) { @@ -392,36 +396,32 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent ) #endif if( aEvent.IsAction( &ACT_RouterOptions ) ) { - DIALOG_PNS_SETTINGS settingsDlg( getEditFrame(), m_router->Settings() ); + DIALOG_PNS_SETTINGS settingsDlg( frame, m_router->Settings() ); if( settingsDlg.ShowModal() ) - m_router->ApplySettings(); + { + // FIXME: do we need an explicit update? + } } else if( aEvent.IsAction( &ACT_CustomTrackWidth ) ) { - DIALOG_TRACK_VIA_SIZE sizeDlg( getEditFrame(), m_router->Settings() ); - BOARD_DESIGN_SETTINGS& bds = getModel()->GetDesignSettings(); + BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); + DIALOG_TRACK_VIA_SIZE sizeDlg( frame, bds ); - sizeDlg.ShowModal(); - - // TODO it should be changed, router settings won't keep track & via sizes in the future - bds.SetCustomTrackWidth( m_router->Settings().GetTrackWidth() ); - bds.SetCustomViaSize( m_router->Settings().GetViaDiameter() ); - bds.SetCustomViaDrill( m_router->Settings().GetViaDrill() ); - bds.UseCustomTrackViaSize( true ); - - m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); + if ( sizeDlg.ShowModal() ) + { + bds.UseCustomTrackViaSize( true ); + m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); + } } else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) ) { - BOARD_DESIGN_SETTINGS& bds = getModel()->GetDesignSettings(); - m_router->Settings().SetTrackWidth( bds.GetCurrentTrackWidth() ); - m_router->Settings().SetViaDiameter( bds.GetCurrentViaSize() ); - m_router->Settings().SetViaDrill( bds.GetCurrentViaDrill() ); - m_router->ApplySettings(); + PNS_SIZES_SETTINGS sizes; + sizes.ImportCurrent ( board->GetDesignSettings() ); + m_router->UpdateSizes ( sizes ); } } @@ -459,10 +459,10 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent ) ctls->ForceCursorPosition( false ); } - if( startItem->Layers().IsMultilayer() ) - m_startLayer = tl; - else - m_startLayer = startItem->Layers().Start(); +// if( startItem->Layers().IsMultilayer() ) +// m_startLayer = tl; +// else +// m_startLayer = startItem->Layers().Start(); m_startItem = startItem; } @@ -470,7 +470,6 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent ) { m_startItem = NULL; m_startSnapPoint = cp; - m_startLayer = tl; ctls->ForceCursorPosition( false ); } } @@ -521,25 +520,99 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent ) TRACE( 0, "%s, layer : %d", m_endItem->KindStr().c_str() % m_endItem->Layers().Start() ); } +int ROUTER_TOOL::getStartLayer( const PNS_ITEM *aItem ) +{ + int tl = getView()->GetTopLayer(); + + if (m_startItem) + { + const PNS_LAYERSET& ls = m_startItem->Layers(); + + if(ls.Overlaps( tl )) + return tl; + else + return ls.Start(); + } + + return tl; +} +void ROUTER_TOOL::switchLayerOnViaPlacement() +{ + PCB_EDIT_FRAME* frame = getEditFrame(); + + int al = frame->GetActiveLayer(); + int cl = m_router->GetCurrentLayer(); + + if( cl != al ) + { + m_router->SwitchLayer( al ); + } + + optional newLayer = m_router->Sizes().PairedLayer( cl ); + + if( newLayer ) + { + m_router->SwitchLayer ( *newLayer ); + frame->SetActiveLayer ( ToLAYER_ID( *newLayer ) ); + } +} + +bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType ) +{ + BOARD *board = getModel (); + BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); + PCB_EDIT_FRAME* frame = getEditFrame(); + + const int layerCount = bds.GetCopperLayerCount(); + int currentLayer = m_router->GetCurrentLayer(); + + PNS_SIZES_SETTINGS sizes = m_router->Sizes(); + + sizes.ClearLayerPairs(); + sizes.AddLayerPair( frame->GetScreen()->m_Route_Layer_TOP, + frame->GetScreen()->m_Route_Layer_BOTTOM ); + + if (!m_router->IsPlacingVia()) + { + // Cannot place microvias or blind vias if not allowed (obvious) + if( ( aType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) ) + return false; + if( ( aType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) ) + return false; + + //Can only place through vias on 2-layer boards + if( ( aType != VIA_THROUGH ) && ( layerCount <= 2 ) ) + return false; + + //Can only place microvias if we're on an outer layer, or directly adjacent to one + if( ( aType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount-2 ) ) + return false; + + //Cannot place blind vias with front/back as the layer pair, this doesn't make sense + if( ( aType == VIA_BLIND_BURIED ) && ( sizes.GetLayerTop() == F_Cu ) && ( sizes.GetLayerBottom() == B_Cu ) ) + return false; + } + + + sizes.SetViaType ( aType ); + m_router->ToggleViaPlacement( ); + m_router->UpdateSizes( sizes ); + + m_router->Move( m_endSnapPoint, m_endItem ); // refresh + + return false; +} void ROUTER_TOOL::performRouting() { PCB_EDIT_FRAME* frame = getEditFrame(); bool saveUndoBuffer = true; VIEW_CONTROLS* ctls = getViewControls(); + BOARD* board = getModel(); - if( getModel()->GetDesignSettings().m_UseConnectedTrackWidth ) - { - int width = getDefaultWidth( m_startItem ? m_startItem->Net() : -1 ); - - if( m_startItem && m_startItem->OfKind( PNS_ITEM::SEGMENT ) ) - width = static_cast( m_startItem )->Width(); - - m_router->Settings().SetTrackWidth( width ); - } - - m_router->SwitchLayer( m_startLayer ); - frame->SetActiveLayer( ToLAYER_ID( m_startLayer ) ); + int routingLayer = getStartLayer ( m_startItem ); + frame->SetActiveLayer( ToLAYER_ID ( routingLayer ) ); + // fixme: switch on invisible layer if( m_startItem && m_startItem->Net() >= 0 ) { @@ -553,7 +626,13 @@ void ROUTER_TOOL::performRouting() ctls->ForceCursorPosition( false ); ctls->SetAutoPan( true ); - m_router->StartRouting( m_startSnapPoint, m_startItem ); + PNS_SIZES_SETTINGS sizes; + sizes.Init ( board, m_startItem ); + sizes.AddLayerPair ( frame->GetScreen()->m_Route_Layer_TOP, + frame->GetScreen()->m_Route_Layer_BOTTOM ); + m_router->UpdateSizes( sizes ); + + m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ); m_endItem = NULL; m_endSnapPoint = m_startSnapPoint; @@ -575,10 +654,16 @@ void ROUTER_TOOL::performRouting() else if( evt->IsClick( BUT_LEFT ) ) { updateEndItem( *evt ); + bool needLayerSwitch = m_router->IsPlacingVia(); if( m_router->FixRoute( m_endSnapPoint, m_endItem ) ) break; + if(needLayerSwitch) + { + switchLayerOnViaPlacement(); + } + // Synchronize the indicated layer frame->SetActiveLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) ); @@ -586,24 +671,15 @@ void ROUTER_TOOL::performRouting() } else if( evt->IsAction( &ACT_PlaceThroughVia ) ) { - m_router->Settings().SetLayerPair( frame->GetScreen()->m_Route_Layer_TOP, - frame->GetScreen()->m_Route_Layer_BOTTOM ); - m_router->ToggleViaPlacement( VIA_THROUGH ); - m_router->Move( m_endSnapPoint, m_endItem ); // refresh + onViaCommand ( VIA_THROUGH ); } else if( evt->IsAction( &ACT_PlaceBlindVia ) ) { - m_router->Settings().SetLayerPair( frame->GetScreen()->m_Route_Layer_TOP, - frame->GetScreen()->m_Route_Layer_BOTTOM ); - m_router->ToggleViaPlacement( VIA_BLIND_BURIED ); - m_router->Move( m_endSnapPoint, m_endItem ); // refresh + onViaCommand ( VIA_BLIND_BURIED ); } else if( evt->IsAction( &ACT_PlaceMicroVia ) ) { - m_router->Settings().SetLayerPair( frame->GetScreen()->m_Route_Layer_TOP, - frame->GetScreen()->m_Route_Layer_BOTTOM ); - m_router->ToggleViaPlacement( VIA_MICROVIA ); - m_router->Move( m_endSnapPoint, m_endItem ); // refresh + onViaCommand ( VIA_MICROVIA ); } else if( evt->IsAction( &ACT_SwitchPosture ) ) { @@ -649,26 +725,19 @@ void ROUTER_TOOL::performRouting() int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) { VIEW_CONTROLS* ctls = getViewControls(); + PCB_EDIT_FRAME* frame = getEditFrame(); BOARD* board = getModel(); - BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); // Deselect all items m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); - getEditFrame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, - _( "Interactive Router" ) ); + frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Interactive Router" ) ); ctls->SetSnapping( true ); ctls->ShowCursor( true ); - // Set current track widths & via size - m_router->Settings().SetTrackWidth( bds.GetCurrentTrackWidth() ); - m_router->Settings().SetViaDiameter( bds.GetCurrentViaSize() ); - m_router->Settings().SetViaDrill( bds.GetCurrentViaDrill() ); - - ROUTER_TOOL_MENU* ctxMenu = new ROUTER_TOOL_MENU( board ); - - SetContextMenu ( ctxMenu ); + std::auto_ptr ctxMenu ( new ROUTER_TOOL_MENU( board ) ); + SetContextMenu ( ctxMenu.get() ); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -704,11 +773,10 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) // Restore the default settings ctls->SetAutoPan( false ); ctls->ShowCursor( false ); - getEditFrame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); // Store routing settings till the next invocation m_settings = m_router->Settings(); - delete ctxMenu; return 0; } diff --git a/pcbnew/router/router_tool.h b/pcbnew/router/router_tool.h index 06dc75b7fe..fd98843c01 100644 --- a/pcbnew/router/router_tool.h +++ b/pcbnew/router/router_tool.h @@ -57,9 +57,12 @@ private: void updateEndItem( TOOL_EVENT& aEvent ); void getNetclassDimensions( int aNetCode, int& aWidth, int& aViaDiameter, int& aViaDrill ); - void handleCommonEvents( TOOL_EVENT& evt ); + int getStartLayer( const PNS_ITEM *aItem ); + void switchLayerOnViaPlacement(); + bool onViaCommand( VIATYPE_T aType ); + MSG_PANEL_ITEMS m_panelItems; PNS_ROUTER* m_router;