router: multiple changes

- re-worked PNS_LINE_PLACER and PNS_ROUTER classes a bit, removing duplicate class members
- cleaned up Andrew's blind/buried via fixes
- fixed 'custom via width' dialog bug updating the width even when closed/cancelled
- fixed incorrect radius of drawn microvias
This commit is contained in:
Tomasz Wlostowski 2014-11-14 19:15:58 +01:00 committed by Maciej Suminski
parent 32eb568ec4
commit 80adf9d85b
23 changed files with 744 additions and 704 deletions

View File

@ -23,22 +23,22 @@
*/
#include "dialog_track_via_size.h"
#include <router/pns_routing_settings.h>
#include <base_units.h>
#include <confirm.h>
#include <boost/optional.hpp>
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

View File

@ -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();

View File

@ -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 );
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="11" />
<FileVersion major="1" minor="13" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@ -41,11 +41,11 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="minimum_size">280,240</property>
<property name="name">DIALOG_TRACK_VIA_SIZE_BASE</property>
<property name="pos"></property>
<property name="size">388,162</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="size">-1,-1</property>
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="subclass"></property>
<property name="title">Track width and via size</property>
<property name="tooltip"></property>
@ -147,7 +147,7 @@
<property name="settings"></property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
@ -350,189 +350,28 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxStdDialogButtonSizer" expanded="1">
<property name="Apply">0</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">bButtons</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_OK</property>
<property name="label">OK</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_ok</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onOkClick</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_CANCEL</property>
<property name="label">Cancel</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cancel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onCancelClick</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<property name="name">m_stdButtons</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick"></event>
<event name="OnCancelButtonClick">onCancelClick</event>
<event name="OnContextHelpButtonClick"></event>
<event name="OnHelpButtonClick"></event>
<event name="OnNoButtonClick"></event>
<event name="OnOKButtonClick">onOkClick</event>
<event name="OnSaveButtonClick"></event>
<event name="OnYesButtonClick"></event>
</object>
</object>
</object>

View File

@ -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 <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class DIALOG_SHIM;
#include <wxunittext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
@ -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();
};

View File

@ -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 );

View File

@ -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

View File

@ -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 );

View File

@ -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 );
}

View File

@ -22,6 +22,7 @@
#define __PNS_ITEMSET_H
#include <vector>
#include <boost/foreach.hpp>
#include "pns_item.h"
@ -35,53 +36,96 @@
class PNS_ITEMSET
{
public:
typedef std::vector<PNS_ITEM*> ITEM_VECTOR;
typedef std::vector<PNS_ITEM*> 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

View File

@ -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<PNS_SEGMENT*>( 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;
};

View File

@ -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:

View File

@ -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 );
}
}

View File

@ -26,6 +26,7 @@
#include <geometry/shape.h>
#include <geometry/shape_line_chain.h>
#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

View File

@ -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<PNS_VIA*>( 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();
}

View File

@ -30,6 +30,7 @@
#include <class_undoredo_container.h>
#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<hoverItem> 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

View File

@ -21,6 +21,8 @@
#ifndef __PNS_ROUTING_SETTINGS
#define __PNS_ROUTING_SETTINGS
#include <cstdio>
#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

View File

@ -0,0 +1,159 @@
/*
* KiRouter - a push-and-(sometimes-)shove PCB router
*
* Copyright (C) 2014 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <class_board.h>
#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<PNS_VIA*>( aItem )->Pos();
break;
case PNS_ITEM::SOLID:
p = static_cast<PNS_SOLID*>( aItem )->Pos();
break;
case PNS_ITEM::SEGMENT:
return static_cast<PNS_SEGMENT*>( 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<PNS_SEGMENT*>( 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;
}

View File

@ -0,0 +1,95 @@
/*
* KiRouter - a push-and-(sometimes-)shove PCB router
*
* Copyright (C) 2014 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __PNS_SIZES_SETTINGS_H
#define __PNS_SIZES_SETTINGS_H
#include <map>
#include <boost/optional.hpp>
#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<int> PairedLayer ( int aLayerId )
{
if( m_layerPairs.find(aLayerId) == m_layerPairs.end() )
return boost::optional<int>();
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<int, int> m_layerPairs;
};
#endif // __PNS_SIZES_SETTINGS_H

View File

@ -53,7 +53,7 @@ public:
if( aViaType == VIA_THROUGH )
{
PNS_LAYERSET allLayers( 0, MAX_CU_LAYERS - 1 );
SetLayers( allLayers);
SetLayers( allLayers );
}
}

View File

@ -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 );

View File

@ -32,6 +32,7 @@
#include <macros.h>
#include <pcbnew_id.h>
#include <view/view_controls.h>
#include <pcbcommon.h>
#include <pcb_painter.h>
#include <dialogs/dialog_pns_settings.h>
#include <dialogs/dialog_track_via_size.h>
@ -377,6 +378,9 @@ void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode )
void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
{
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME> ();
BOARD *board = getModel<BOARD> ();
#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<PCB_EDIT_FRAME>(), 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<PCB_EDIT_FRAME>(), m_router->Settings() );
BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>()->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<BOARD>()->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<PCB_EDIT_FRAME>();
int al = frame->GetActiveLayer();
int cl = m_router->GetCurrentLayer();
if( cl != al )
{
m_router->SwitchLayer( al );
}
optional<int> 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> ();
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
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<PCB_EDIT_FRAME>();
bool saveUndoBuffer = true;
VIEW_CONTROLS* ctls = getViewControls();
BOARD* board = getModel<BOARD>();
if( getModel<BOARD>()->GetDesignSettings().m_UseConnectedTrackWidth )
{
int width = getDefaultWidth( m_startItem ? m_startItem->Net() : -1 );
if( m_startItem && m_startItem->OfKind( PNS_ITEM::SEGMENT ) )
width = static_cast<PNS_SEGMENT*>( 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<PCB_EDIT_FRAME>();
BOARD* board = getModel<BOARD>();
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
// Deselect all items
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
getEditFrame<PCB_EDIT_FRAME>()->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<ROUTER_TOOL_MENU> 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<PCB_EDIT_FRAME>()->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;
}

View File

@ -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;