Code formatting.

This commit is contained in:
Maciej Suminski 2015-02-18 17:53:46 +01:00
parent 112adccbcb
commit 4fb9bce354
100 changed files with 3005 additions and 4238 deletions

View File

@ -35,7 +35,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const
{ {
VECTOR2I d = B - A; VECTOR2I d = B - A;
ecoord dist_sq = (ecoord) aDist * aDist; ecoord dist_sq = (ecoord) aDist * aDist;
ecoord dist_sq_thr = (ecoord) (aDist + 1) * (aDist + 1); ecoord dist_sq_thr = (ecoord) ( aDist + 1 ) * ( aDist + 1 );
SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord l_squared = d.Dot( d );
SEG::ecoord t = d.Dot( aP - A ); SEG::ecoord t = d.Dot( aP - A );

View File

@ -29,35 +29,37 @@
#include <wx_status_popup.h> #include <wx_status_popup.h>
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
WX_STATUS_POPUP::WX_STATUS_POPUP ( PCB_EDIT_FRAME *parent ) : WX_STATUS_POPUP::WX_STATUS_POPUP( PCB_EDIT_FRAME* aParent ) :
wxPopupWindow ( parent ) wxPopupWindow( aParent )
{ {
m_panel = new wxPanel( this, wxID_ANY ); m_panel = new wxPanel( this, wxID_ANY );
m_panel->SetBackgroundColour( *wxLIGHT_GREY ); m_panel->SetBackgroundColour( *wxLIGHT_GREY );
m_topSizer = new wxBoxSizer( wxVERTICAL ); m_topSizer = new wxBoxSizer( wxVERTICAL );
m_panel->SetSizer( m_topSizer ); m_panel->SetSizer( m_topSizer );
} }
void WX_STATUS_POPUP::updateSize() void WX_STATUS_POPUP::updateSize()
{ {
m_topSizer->Fit( m_panel ); m_topSizer->Fit( m_panel );
SetClientSize( m_panel->GetSize( ) ); SetClientSize( m_panel->GetSize() );
} }
WX_STATUS_POPUP::~WX_STATUS_POPUP() WX_STATUS_POPUP::~WX_STATUS_POPUP()
{ {
} }
void WX_STATUS_POPUP::Popup(wxWindow *focus)
void WX_STATUS_POPUP::Popup( wxWindow* )
{ {
Show(true); Show( true );
Raise(); Raise();
} }
void WX_STATUS_POPUP::Move( const wxPoint& aWhere ) void WX_STATUS_POPUP::Move( const wxPoint& aWhere )
{ {
SetPosition ( aWhere ); SetPosition ( aWhere );
} }

View File

@ -35,14 +35,14 @@
#include "wx_unit_binder.h" #include "wx_unit_binder.h"
WX_UNIT_BINDER::WX_UNIT_BINDER( wxWindow* aParent, wxTextCtrl *aTextInput, wxStaticText *aUnitLabel, wxSpinButton *aSpinButton ) WX_UNIT_BINDER::WX_UNIT_BINDER( wxWindow* aParent, wxTextCtrl* aTextInput, wxStaticText* aUnitLabel, wxSpinButton* aSpinButton )
{ {
// Use the currently selected units // Use the currently selected units
m_units = g_UserUnit; m_units = g_UserUnit;
m_textCtrl = aTextInput; m_textCtrl = aTextInput;
m_textCtrl->SetValue ( wxT("0") ); m_textCtrl->SetValue( wxT( "0" ) );
m_unitLabel = aUnitLabel; m_unitLabel = aUnitLabel;
m_unitLabel->SetLabel ( GetAbbreviatedUnitsLabel (m_units)); m_unitLabel->SetLabel( GetAbbreviatedUnitsLabel( m_units ) );
} }
@ -50,15 +50,17 @@ WX_UNIT_BINDER::~WX_UNIT_BINDER()
{ {
} }
void WX_UNIT_BINDER::SetValue( int aValue ) void WX_UNIT_BINDER::SetValue( int aValue )
{ {
wxString s = StringFromValue( m_units, aValue, false ); wxString s = StringFromValue( m_units, aValue, false );
m_textCtrl->SetValue ( s ); m_textCtrl->SetValue( s );
m_unitLabel->SetLabel ( GetAbbreviatedUnitsLabel (m_units)); m_unitLabel->SetLabel( GetAbbreviatedUnitsLabel( m_units ) );
} }
int WX_UNIT_BINDER::GetValue() const int WX_UNIT_BINDER::GetValue() const
{ {
wxString s = m_textCtrl->GetValue(); wxString s = m_textCtrl->GetValue();
@ -66,8 +68,9 @@ int WX_UNIT_BINDER::GetValue() const
return ValueFromString( m_units, s ); return ValueFromString( m_units, s );
} }
void WX_UNIT_BINDER::Enable ( bool aEnable )
void WX_UNIT_BINDER::Enable( bool aEnable )
{ {
m_textCtrl->Enable ( aEnable ); m_textCtrl->Enable( aEnable );
m_unitLabel->Enable ( aEnable ); m_unitLabel->Enable( aEnable );
} }

View File

@ -134,7 +134,7 @@ public:
* removes the item aItem (if exists in the collector). * removes the item aItem (if exists in the collector).
* @param aItem the item to be removed. * @param aItem the item to be removed.
*/ */
void Remove( const EDA_ITEM *aItem ) void Remove( const EDA_ITEM* aItem )
{ {
for( size_t i = 0; i < m_List.size(); i++ ) for( size_t i = 0; i < m_List.size(); i++ )
{ {
@ -257,7 +257,6 @@ public:
return cnt; return cnt;
} }
/** /**
* Function Collect * Function Collect
* scans an EDA_ITEM using this class's Inspector method, which does * scans an EDA_ITEM using this class's Inspector method, which does

View File

@ -50,7 +50,7 @@ public:
/** /**
* Function GetSize() * Function GetSize()
* Returns information about number of vertices stored. * Returns information about number of vertices stored.
* @param Number of vertices. * @return Number of vertices.
*/ */
inline unsigned int GetSize() const inline unsigned int GetSize() const
{ {

View File

@ -206,7 +206,7 @@ public:
return sqrt( SquaredDistance( aP ) ); return sqrt( SquaredDistance( aP ) );
} }
void CanonicalCoefs ( ecoord& qA, ecoord& qB, ecoord& qC) const void CanonicalCoefs( ecoord& qA, ecoord& qB, ecoord& qC ) const
{ {
qA = A.y - B.y; qA = A.y - B.y;
qB = B.x - A.x; qB = B.x - A.x;
@ -223,7 +223,7 @@ public:
bool Collinear( const SEG& aSeg ) const bool Collinear( const SEG& aSeg ) const
{ {
ecoord qa, qb, qc; ecoord qa, qb, qc;
CanonicalCoefs ( qa, qb, qc ); CanonicalCoefs( qa, qb, qc );
ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc ); ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc );
ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc ); ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
@ -234,23 +234,23 @@ public:
bool ApproxCollinear( const SEG& aSeg ) const bool ApproxCollinear( const SEG& aSeg ) const
{ {
ecoord p, q, r; ecoord p, q, r;
CanonicalCoefs ( p, q, r ); CanonicalCoefs( p, q, r );
ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q ); ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q );
ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q ); ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q );
return std::abs(dist1) <= 1 && std::abs(dist2) <= 1; return std::abs( dist1 ) <= 1 && std::abs( dist2 ) <= 1;
} }
bool ApproxParallel ( const SEG& aSeg ) const bool ApproxParallel ( const SEG& aSeg ) const
{ {
ecoord p, q, r; ecoord p, q, r;
CanonicalCoefs ( p, q, r ); CanonicalCoefs( p, q, r );
ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q ); ecoord dist1 = ( p * aSeg.A.x + q * aSeg.A.y + r ) / sqrt( p * p + q * q );
ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q ); ecoord dist2 = ( p * aSeg.B.x + q * aSeg.B.y + r ) / sqrt( p * p + q * q );
return std::abs(dist1 - dist2) <= 1; return std::abs( dist1 - dist2 ) <= 1;
} }
@ -291,7 +291,7 @@ public:
return ( A - B ).SquaredEuclideanNorm(); return ( A - B ).SquaredEuclideanNorm();
} }
ecoord TCoef ( const VECTOR2I& aP ) const; ecoord TCoef( const VECTOR2I& aP ) const;
/** /**
* Function Index() * Function Index()
@ -310,7 +310,7 @@ public:
void Reverse() void Reverse()
{ {
std::swap ( A, B ); std::swap( A, B );
} }
private: private:
@ -320,7 +320,6 @@ private:
int m_index; int m_index;
}; };
inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
{ {
VECTOR2I d = B - A; VECTOR2I d = B - A;
@ -337,7 +336,6 @@ inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
return A + VECTOR2I( xp, yp ); return A + VECTOR2I( xp, yp );
} }
inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
{ {
ecoord p = A.y - B.y; ecoord p = A.y - B.y;
@ -349,10 +347,10 @@ inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
return aDetermineSide ? dist : abs( dist ); return aDetermineSide ? dist : abs( dist );
} }
inline SEG::ecoord SEG::TCoef ( const VECTOR2I& aP ) const inline SEG::ecoord SEG::TCoef( const VECTOR2I& aP ) const
{ {
VECTOR2I d = B - A; VECTOR2I d = B - A;
return d.Dot ( aP - A); return d.Dot( aP - A);
} }
inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
@ -376,7 +374,6 @@ inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
return A + VECTOR2I( xp, yp ); return A + VECTOR2I( xp, yp );
} }
inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg ) inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg )
{ {
aStream << "[ " << aSeg.A << " - " << aSeg.B << " ]"; aStream << "[ " << aSeg.A << " - " << aSeg.B << " ]";

View File

@ -85,7 +85,6 @@ public:
HIDDEN = 0x02 /// Item is temporarily hidden (e.g. being used by a tool). Overrides VISIBLE flag. HIDDEN = 0x02 /// Item is temporarily hidden (e.g. being used by a tool). Overrides VISIBLE flag.
}; };
VIEW_ITEM() : m_view( NULL ), m_flags( VISIBLE ), m_requiredUpdate( ALL ), VIEW_ITEM() : m_view( NULL ), m_flags( VISIBLE ), m_requiredUpdate( ALL ),
m_groups( NULL ), m_groupsSize( 0 ) {} m_groups( NULL ), m_groupsSize( 0 ) {}
@ -144,10 +143,11 @@ public:
if( cur_visible != aIsVisible ) if( cur_visible != aIsVisible )
{ {
if(aIsVisible) if( aIsVisible )
m_flags |= VISIBLE; m_flags |= VISIBLE;
else else
m_flags &= ~VISIBLE; m_flags &= ~VISIBLE;
ViewUpdate( APPEARANCE | COLOR ); ViewUpdate( APPEARANCE | COLOR );
} }
} }
@ -158,12 +158,12 @@ public:
* *
* @param aHide: whether the item is hidden (on all layers), or not. * @param aHide: whether the item is hidden (on all layers), or not.
*/ */
void ViewHide ( bool aHide = true ) void ViewHide( bool aHide = true )
{ {
if(! (m_flags & VISIBLE) ) if( !( m_flags & VISIBLE ) )
return; return;
if(aHide) if( aHide )
m_flags |= HIDDEN; m_flags |= HIDDEN;
else else
m_flags &= ~HIDDEN; m_flags &= ~HIDDEN;

View File

@ -41,18 +41,18 @@ class PCB_EDIT_FRAME;
class WX_STATUS_POPUP: public wxPopupWindow class WX_STATUS_POPUP: public wxPopupWindow
{ {
public: public:
WX_STATUS_POPUP ( PCB_EDIT_FRAME *parent ); WX_STATUS_POPUP( PCB_EDIT_FRAME* aParent );
virtual ~WX_STATUS_POPUP(); virtual ~WX_STATUS_POPUP();
virtual void Popup(wxWindow *focus = NULL); virtual void Popup(wxWindow* aFocus = NULL);
virtual void Move( const wxPoint &aWhere ); virtual void Move( const wxPoint &aWhere );
protected: protected:
void updateSize(); void updateSize();
wxPanel *m_panel; wxPanel* m_panel;
wxBoxSizer *m_topSizer; wxBoxSizer* m_topSizer;
}; };
#endif /* __WX_STATUS_POPUP_H_*/ #endif /* __WX_STATUS_POPUP_H_*/

View File

@ -43,7 +43,7 @@ public:
* @param aUnitLabel is the units label displayed next to the text field. * @param aUnitLabel is the units label displayed next to the text field.
* @param aSpinButton is an optional spin button (for adjusting the input value) * @param aSpinButton is an optional spin button (for adjusting the input value)
*/ */
WX_UNIT_BINDER( wxWindow* aParent, wxTextCtrl *aTextInput, wxStaticText *aUnitLabel, wxSpinButton *aSpinButton = NULL ); WX_UNIT_BINDER( wxWindow* aParent, wxTextCtrl* aTextInput, wxStaticText* aUnitLabel, wxSpinButton* aSpinButton = NULL );
virtual ~WX_UNIT_BINDER(); virtual ~WX_UNIT_BINDER();
@ -64,11 +64,11 @@ public:
* Function Enable * Function Enable
* Enables/diasables the binded widgets * Enables/diasables the binded widgets
*/ */
void Enable ( bool aEnable ); void Enable( bool aEnable );
protected: protected:
void onTextChanged ( wxEvent& aEvent ); void onTextChanged( wxEvent& aEvent );
///> Text input control. ///> Text input control.
wxTextCtrl* m_textCtrl; wxTextCtrl* m_textCtrl;

View File

@ -69,7 +69,7 @@ public:
/// skip the linked list stuff, and parent /// skip the linked list stuff, and parent
const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs ); const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs );
static inline bool ClassOf( const EDA_ITEM *aItem ) static inline bool ClassOf( const EDA_ITEM* aItem )
{ {
return aItem && PCB_LINE_T == aItem->Type(); return aItem && PCB_LINE_T == aItem->Type();
} }

View File

@ -815,12 +815,14 @@ void MODULE::RunOnChildren( boost::function<void (BOARD_ITEM*)> aFunction )
} }
} }
const BOX2I MODULE::ViewBBox() const const BOX2I MODULE::ViewBBox() const
{ {
return BOX2I( VECTOR2I( GetFootprintRect().GetOrigin() ), return BOX2I( VECTOR2I( GetFootprintRect().GetOrigin() ),
VECTOR2I( GetFootprintRect().GetSize() ) ); VECTOR2I( GetFootprintRect().GetSize() ) );
} }
void MODULE::ViewUpdate( int aUpdateFlags ) void MODULE::ViewUpdate( int aUpdateFlags )
{ {
if( !m_view ) if( !m_view )
@ -1115,6 +1117,7 @@ void MODULE::SetOrientation( double newangle )
CalculateBoundingBox(); CalculateBoundingBox();
} }
double MODULE::PadCoverageRatio() const double MODULE::PadCoverageRatio() const
{ {
double padArea = 0.0; double padArea = 0.0;
@ -1128,5 +1131,5 @@ double MODULE::PadCoverageRatio() const
double ratio = padArea / moduleArea; double ratio = padArea / moduleArea;
return std::min(ratio, 1.0); return std::min( ratio, 1.0 );
} }

View File

@ -262,7 +262,8 @@ public:
m_ModuleStatus &= ~MODULE_to_PLACE; m_ModuleStatus &= ~MODULE_to_PLACE;
} }
bool PadsLocked() const { return (m_ModuleStatus & MODULE_PADS_LOCKED ); } bool PadsLocked() const { return ( m_ModuleStatus & MODULE_PADS_LOCKED ); }
void SetPadsLocked( bool aPadsLocked ) void SetPadsLocked( bool aPadsLocked )
{ {
if( aPadsLocked ) if( aPadsLocked )

View File

@ -94,7 +94,7 @@ public:
///< used for edge board connectors ///< used for edge board connectors
static LSET UnplatedHoleMask(); ///< layer set for a mechanical unplated through hole pad static LSET UnplatedHoleMask(); ///< layer set for a mechanical unplated through hole pad
static inline bool ClassOf( const EDA_ITEM *aItem ) static inline bool ClassOf( const EDA_ITEM* aItem )
{ {
return aItem && PCB_PAD_T == aItem->Type(); return aItem && PCB_PAD_T == aItem->Type();
} }

View File

@ -49,7 +49,7 @@ public:
~TEXTE_PCB(); ~TEXTE_PCB();
static inline bool ClassOf( const EDA_ITEM *aItem ) static inline bool ClassOf( const EDA_ITEM* aItem )
{ {
return aItem && PCB_TEXT_T == aItem->Type(); return aItem && PCB_TEXT_T == aItem->Type();
} }

View File

@ -313,9 +313,9 @@ void DIALOG_MODULE_BOARD_EDITOR::InitModeditProperties()
break; break;
} }
if (m_CurrentModule->IsLocked() ) if( m_CurrentModule->IsLocked() )
m_AutoPlaceCtrl->SetSelection( 2 ); m_AutoPlaceCtrl->SetSelection( 2 );
else if (m_CurrentModule->PadsLocked() ) else if( m_CurrentModule->PadsLocked() )
m_AutoPlaceCtrl->SetSelection( 1 ); m_AutoPlaceCtrl->SetSelection( 1 );
else else
m_AutoPlaceCtrl->SetSelection( 0 ); m_AutoPlaceCtrl->SetSelection( 0 );

View File

@ -27,23 +27,22 @@
DIALOG_PNS_DIFF_PAIR_DIMENSIONS::DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes ) : DIALOG_PNS_DIFF_PAIR_DIMENSIONS::DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes ) :
DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE( aParent ), DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE( aParent ),
m_traceWidth ( this, m_traceWidthText, m_traceWidthUnit ), m_traceWidth( this, m_traceWidthText, m_traceWidthUnit ),
m_traceGap (this, m_traceGapText, m_traceGapUnit ), m_traceGap( this, m_traceGapText, m_traceGapUnit ),
m_viaGap ( this, m_viaGapText, m_viaGapUnit ), m_viaGap( this, m_viaGapText, m_viaGapUnit ),
m_sizes( aSizes ) m_sizes( aSizes )
{ {
m_traceWidth.SetValue ( aSizes.DiffPairWidth() ); m_traceWidth.SetValue( aSizes.DiffPairWidth() );
m_traceGap.SetValue ( aSizes.DiffPairGap() ); m_traceGap.SetValue( aSizes.DiffPairGap() );
m_viaGap.SetValue ( aSizes.DiffPairViaGap() ); m_viaGap.SetValue( aSizes.DiffPairViaGap() );
m_viaTraceGapEqual->SetValue ( m_sizes.DiffPairViaGapSameAsTraceGap() ); m_viaTraceGapEqual->SetValue( m_sizes.DiffPairViaGapSameAsTraceGap() );
updateCheckbox(); updateCheckbox();
} }
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::updateCheckbox() void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::updateCheckbox()
{ {
printf("Checked: %d", m_viaTraceGapEqual->GetValue());
if( m_viaTraceGapEqual->GetValue() ) if( m_viaTraceGapEqual->GetValue() )
{ {
m_sizes.SetDiffPairViaGapSameAsTraceGap( true ); m_sizes.SetDiffPairViaGapSameAsTraceGap( true );
@ -58,6 +57,7 @@ void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::updateCheckbox()
} }
} }
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnClose( wxCloseEvent& aEvent ) void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnClose( wxCloseEvent& aEvent )
{ {
// Do nothing, it is result of ESC pressing // Do nothing, it is result of ESC pressing
@ -83,6 +83,7 @@ void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnCancelClick( wxCommandEvent& aEvent )
EndModal( 0 ); EndModal( 0 );
} }
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnViaTraceGapEqualCheck( wxCommandEvent& event ) void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnViaTraceGapEqualCheck( wxCommandEvent& event )
{ {
event.Skip(); event.Skip();

View File

@ -33,7 +33,7 @@ class PNS_SIZES_SETTINGS;
class DIALOG_PNS_DIFF_PAIR_DIMENSIONS : public DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE class DIALOG_PNS_DIFF_PAIR_DIMENSIONS : public DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE
{ {
public: public:
DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes ); DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes );
virtual void OnClose( wxCloseEvent& aEvent ); virtual void OnClose( wxCloseEvent& aEvent );
@ -41,9 +41,8 @@ class DIALOG_PNS_DIFF_PAIR_DIMENSIONS : public DIALOG_PNS_DIFF_PAIR_DIMENSIONS_B
virtual void OnCancelClick( wxCommandEvent& aEvent ); virtual void OnCancelClick( wxCommandEvent& aEvent );
virtual void OnViaTraceGapEqualCheck( wxCommandEvent& event ); virtual void OnViaTraceGapEqualCheck( wxCommandEvent& event );
private:
private: void updateCheckbox();
void updateCheckbox( );
WX_UNIT_BINDER m_traceWidth; WX_UNIT_BINDER m_traceWidth;
WX_UNIT_BINDER m_traceGap; WX_UNIT_BINDER m_traceGap;

View File

@ -27,47 +27,43 @@
DIALOG_PNS_LENGTH_TUNING_SETTINGS::DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode ) : DIALOG_PNS_LENGTH_TUNING_SETTINGS::DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode ) :
DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE( aParent ), DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE( aParent ),
m_minAmpl ( this, m_minAmplText, m_minAmplUnit ), m_minAmpl( this, m_minAmplText, m_minAmplUnit ),
m_maxAmpl (this, m_maxAmplText, m_maxAmplUnit ), m_maxAmpl( this, m_maxAmplText, m_maxAmplUnit ),
m_spacing ( this, m_spacingText, m_spacingUnit ), m_spacing( this, m_spacingText, m_spacingUnit ),
m_targetLength ( this, m_targetLengthText, m_targetLengthUnit ), m_targetLength( this, m_targetLengthText, m_targetLengthUnit ),
m_settings( aSettings ), m_settings( aSettings ),
m_mode ( aMode ) m_mode( aMode )
{ {
m_miterStyle->Enable( false );
m_miterStyle->Enable ( false ); m_radiusText->Enable( aMode != PNS_MODE_TUNE_DIFF_PAIR );
m_radiusText->Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR );
//m_minAmpl.Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR_SKEW ); //m_minAmpl.Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR_SKEW );
m_minAmpl.SetValue ( m_settings.m_minAmplitude ); m_minAmpl.SetValue( m_settings.m_minAmplitude );
m_maxAmpl.SetValue ( m_settings.m_maxAmplitude ); m_maxAmpl.SetValue( m_settings.m_maxAmplitude );
m_spacing.SetValue ( m_settings.m_spacing ); m_spacing.SetValue( m_settings.m_spacing );
m_radiusText->SetValue ( wxString::Format(wxT("%i"), m_settings.m_cornerRadiusPercentage) ); m_radiusText->SetValue( wxString::Format( wxT( "%i" ), m_settings.m_cornerRadiusPercentage ) );
m_miterStyle->SetSelection( m_settings.m_cornerType == PNS_MEANDER_SETTINGS::ROUND ? 1 : 0 );
m_miterStyle->SetSelection ( m_settings.m_cornerType == PNS_MEANDER_SETTINGS::ROUND ? 1 : 0 );
switch( aMode ) switch( aMode )
{ {
case PNS_MODE_TUNE_SINGLE: case PNS_MODE_TUNE_SINGLE:
SetTitle ( _("Single track length tuning") ); SetTitle( _( "Single track length tuning" ) );
m_legend->SetBitmap( KiBitmap( tune_single_track_length_legend_xpm ) ); m_legend->SetBitmap( KiBitmap( tune_single_track_length_legend_xpm ) );
m_targetLength.SetValue ( m_settings.m_targetLength ); m_targetLength.SetValue( m_settings.m_targetLength );
break; break;
case PNS_MODE_TUNE_DIFF_PAIR: case PNS_MODE_TUNE_DIFF_PAIR:
SetTitle ( _("Differential pair length tuning") ); SetTitle( _( "Differential pair length tuning" ) );
m_legend->SetBitmap( KiBitmap( tune_diff_pair_length_legend_xpm ) ); m_legend->SetBitmap( KiBitmap( tune_diff_pair_length_legend_xpm ) );
m_targetLength.SetValue ( m_settings.m_targetLength ); m_targetLength.SetValue( m_settings.m_targetLength );
break; break;
case PNS_MODE_TUNE_DIFF_PAIR_SKEW: case PNS_MODE_TUNE_DIFF_PAIR_SKEW:
SetTitle ( _("Differential pair skew tuning") ); SetTitle( _( "Differential pair skew tuning" ) );
m_legend->SetBitmap( KiBitmap( tune_diff_pair_skew_legend_xpm ) ); m_legend->SetBitmap( KiBitmap( tune_diff_pair_skew_legend_xpm ) );
m_targetLengthLabel->SetLabel( _("Target skew: ") ); m_targetLengthLabel->SetLabel( _( "Target skew: " ) );
m_targetLength.SetValue ( m_settings.m_targetSkew ); m_targetLength.SetValue ( m_settings.m_targetSkew );
break; break;
@ -76,7 +72,7 @@ DIALOG_PNS_LENGTH_TUNING_SETTINGS::DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow*
} }
m_stdButtonsOK->SetDefault(); m_stdButtonsOK->SetDefault();
m_targetLengthText->SetSelection(-1, -1); m_targetLengthText->SetSelection( -1, -1 );
m_targetLengthText->SetFocus(); m_targetLengthText->SetFocus();
} }
@ -90,7 +86,6 @@ void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnClose( wxCloseEvent& aEvent )
void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnOkClick( wxCommandEvent& aEvent ) void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
{ {
// fixme: use validators and TransferDataFromWindow // fixme: use validators and TransferDataFromWindow
m_settings.m_minAmplitude = m_minAmpl.GetValue(); m_settings.m_minAmplitude = m_minAmpl.GetValue();
m_settings.m_maxAmplitude = m_maxAmpl.GetValue(); m_settings.m_maxAmplitude = m_maxAmpl.GetValue();
@ -98,18 +93,15 @@ void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
m_settings.m_cornerRadiusPercentage = wxAtoi( m_radiusText->GetValue() ); m_settings.m_cornerRadiusPercentage = wxAtoi( m_radiusText->GetValue() );
if (m_mode == PNS_MODE_TUNE_DIFF_PAIR_SKEW) if( m_mode == PNS_MODE_TUNE_DIFF_PAIR_SKEW )
m_settings.m_targetSkew = m_targetLength.GetValue(); m_settings.m_targetSkew = m_targetLength.GetValue();
else else
m_settings.m_targetLength = m_targetLength.GetValue(); m_settings.m_targetLength = m_targetLength.GetValue();
if ( m_settings.m_maxAmplitude < m_settings.m_minAmplitude ) if( m_settings.m_maxAmplitude < m_settings.m_minAmplitude )
m_settings.m_maxAmplitude = m_settings.m_maxAmplitude; m_settings.m_maxAmplitude = m_settings.m_maxAmplitude;
m_settings.m_cornerType = m_miterStyle->GetSelection() ? PNS_MEANDER_SETTINGS::CHAMFER : PNS_MEANDER_SETTINGS::ROUND;
m_settings.m_cornerType = m_miterStyle->GetSelection( ) ? PNS_MEANDER_SETTINGS::CHAMFER : PNS_MEANDER_SETTINGS::ROUND;
EndModal( 1 ); EndModal( 1 );
} }

View File

@ -35,15 +35,14 @@ class PNS_MEANDER_SETTINGS;
class DIALOG_PNS_LENGTH_TUNING_SETTINGS : public DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE class DIALOG_PNS_LENGTH_TUNING_SETTINGS : public DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE
{ {
public: public:
DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode ); DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode );
virtual void OnClose( wxCloseEvent& aEvent ); virtual void OnClose( wxCloseEvent& aEvent );
virtual void OnOkClick( wxCommandEvent& aEvent ); virtual void OnOkClick( wxCommandEvent& aEvent );
virtual void OnCancelClick( wxCommandEvent& aEvent ); virtual void OnCancelClick( wxCommandEvent& aEvent );
private: private:
WX_UNIT_BINDER m_minAmpl; WX_UNIT_BINDER m_minAmpl;
WX_UNIT_BINDER m_maxAmpl; WX_UNIT_BINDER m_maxAmpl;
WX_UNIT_BINDER m_spacing; WX_UNIT_BINDER m_spacing;

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SE
m_viaDrill.SetValue( m_settings.GetCustomViaDrill() ); m_viaDrill.SetValue( m_settings.GetCustomViaDrill() );
m_trackWidthText->SetFocus(); m_trackWidthText->SetFocus();
m_trackWidthText->SetSelection(-1, -1); m_trackWidthText->SetSelection( -1, -1 );
m_stdButtonsOK->SetDefault(); m_stdButtonsOK->SetDefault();
// Pressing ENTER when any of the text input fields is active applies changes // Pressing ENTER when any of the text input fields is active applies changes

View File

@ -34,12 +34,11 @@ class BOARD_DESIGN_SETTINGS;
/** Implementing DIALOG_TRACK_VIA_SIZE_BASE */ /** Implementing DIALOG_TRACK_VIA_SIZE_BASE */
class DIALOG_TRACK_VIA_SIZE : public DIALOG_TRACK_VIA_SIZE_BASE class DIALOG_TRACK_VIA_SIZE : public DIALOG_TRACK_VIA_SIZE_BASE
{ {
public: public:
/** Constructor */ /** Constructor */
DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings ); DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings );
protected: protected:
WX_UNIT_BINDER m_trackWidth; WX_UNIT_BINDER m_trackWidth;
WX_UNIT_BINDER m_viaDiameter; WX_UNIT_BINDER m_viaDiameter;
WX_UNIT_BINDER m_viaDrill; WX_UNIT_BINDER m_viaDrill;

View File

@ -63,7 +63,7 @@ static void DisplayCmpDoc( wxString& aName, void* aData );
static FOOTPRINT_LIST MList; static FOOTPRINT_LIST MList;
static void clearModuleItemFlags ( BOARD_ITEM *aItem ) static void clearModuleItemFlags( BOARD_ITEM* aItem )
{ {
aItem->ClearFlags(); aItem->ClearFlags();
} }

View File

@ -515,7 +515,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
_( "Configure Interactive Routing." ), _( "Configure Interactive Routing." ),
KiBitmap( add_tracks_xpm ) ); // fixme: icon KiBitmap( add_tracks_xpm ) ); // fixme: icon
//--- dimensions submenu ------------------------------------------------------ //--- dimensions submenu ------------------------------------------------------
wxMenu* dimensionsMenu = new wxMenu; wxMenu* dimensionsMenu = new wxMenu;

View File

@ -70,7 +70,6 @@
#include <tool/tool_dispatcher.h> #include <tool/tool_dispatcher.h>
#include <tools/common_actions.h> #include <tools/common_actions.h>
#include <scripting/python_console_frame.h> #include <scripting/python_console_frame.h>
#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON) #if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
@ -537,7 +536,7 @@ void PCB_EDIT_FRAME::setupTools()
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
// Register tools // Register tools
registerAllTools ( m_toolManager ); registerAllTools( m_toolManager );
m_toolManager->ResetTools( TOOL_BASE::RUN ); m_toolManager->ResetTools( TOOL_BASE::RUN );

View File

@ -49,7 +49,6 @@ enum pcbnew_ids
ID_MENU_DIFF_PAIR_DIMENSIONS, ID_MENU_DIFF_PAIR_DIMENSIONS,
ID_MENU_INTERACTIVE_ROUTER_SETTINGS, ID_MENU_INTERACTIVE_ROUTER_SETTINGS,
ID_PCB_MASK_CLEARANCE, ID_PCB_MASK_CLEARANCE,
ID_PCB_LAYERS_SETUP, ID_PCB_LAYERS_SETUP,

View File

@ -1,7 +1,7 @@
/* /*
* KiRouter - a push-and-(sometimes-)shove PCB router * KiRouter - a push-and-(sometimes-)shove PCB router
* *
* Copyright (C) 2013-2014 CERN * Copyright (C) 2013-2015 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
@ -320,7 +320,8 @@ private:
* Function construct() * Function construct()
* Calculates the direction from a vector. If the vector's angle is not a multiple of 45 * Calculates the direction from a vector. If the vector's angle is not a multiple of 45
* degrees, the direction is rounded to the nearest octant. * degrees, the direction is rounded to the nearest octant.
* @param aVec our vector */ * @param aVec our vector
*/
void construct_( const VECTOR2I& aVec ) void construct_( const VECTOR2I& aVec )
{ {
m_dir = UNDEFINED; m_dir = UNDEFINED;
@ -347,32 +348,6 @@ private:
m_dir = (Directions) dir; m_dir = (Directions) dir;
return; return;
if( aVec.y < 0 )
{
if( aVec.x > 0 )
m_dir = NE;
else if( aVec.x < 0 )
m_dir = NW;
else
m_dir = N;
}
else if( aVec.y == 0 )
{
if( aVec.x > 0 )
m_dir = E;
else
m_dir = W;
}
else // aVec.y>0
{
if( aVec.x > 0 )
m_dir = SE;
else if( aVec.x < 0 )
m_dir = SW;
else
m_dir = S;
}
} }
///> our actual direction ///> our actual direction

View File

@ -106,6 +106,7 @@ LENGTH_TUNER_TOOL::~LENGTH_TUNER_TOOL()
delete m_router; delete m_router;
} }
void LENGTH_TUNER_TOOL::Reset( RESET_REASON aReason ) void LENGTH_TUNER_TOOL::Reset( RESET_REASON aReason )
{ {
PNS_TOOL_BASE::Reset( aReason ); PNS_TOOL_BASE::Reset( aReason );
@ -128,9 +129,9 @@ void LENGTH_TUNER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent )
} }
} }
PNS_MEANDER_PLACER_BASE *placer = static_cast <PNS_MEANDER_PLACER_BASE *> ( m_router->Placer() ); PNS_MEANDER_PLACER_BASE* placer = static_cast<PNS_MEANDER_PLACER_BASE*>( m_router->Placer() );
if (!placer) if( !placer )
return; return;
if( aEvent.IsAction( &ACT_Settings ) ) if( aEvent.IsAction( &ACT_Settings ) )
@ -143,15 +144,16 @@ void LENGTH_TUNER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent )
placer->UpdateSettings ( settings ); placer->UpdateSettings ( settings );
} }
m_savedMeanderSettings = placer->MeanderSettings( ); m_savedMeanderSettings = placer->MeanderSettings();
} }
} }
void LENGTH_TUNER_TOOL::performTuning() void LENGTH_TUNER_TOOL::performTuning()
{ {
bool saveUndoBuffer = true; bool saveUndoBuffer = true;
if(m_startItem) if( m_startItem )
{ {
m_frame->SetActiveLayer( ToLAYER_ID ( m_startItem->Layers().Start() ) ); m_frame->SetActiveLayer( ToLAYER_ID ( m_startItem->Layers().Start() ) );
@ -162,22 +164,21 @@ void LENGTH_TUNER_TOOL::performTuning()
m_ctls->ForceCursorPosition( false ); m_ctls->ForceCursorPosition( false );
m_ctls->SetAutoPan( true ); m_ctls->SetAutoPan( true );
if ( !m_router->StartRouting( m_startSnapPoint, m_startItem, 0 ) ) if( !m_router->StartRouting( m_startSnapPoint, m_startItem, 0 ) )
{ {
wxMessageBox ( m_router->FailureReason(), _("Error") ); wxMessageBox( m_router->FailureReason(), _( "Error" ) );
highlightNet ( false ); highlightNet( false );
return; return;
} }
PNS_TUNE_STATUS_POPUP statusPopup ( m_frame ); PNS_TUNE_STATUS_POPUP statusPopup( m_frame );
statusPopup.Popup(); statusPopup.Popup();
PNS_MEANDER_PLACER *placer = static_cast <PNS_MEANDER_PLACER *> ( m_router->Placer() ); PNS_MEANDER_PLACER* placer = static_cast<PNS_MEANDER_PLACER*>( m_router->Placer() );
VECTOR2I end; VECTOR2I end;
placer->UpdateSettings( m_savedMeanderSettings ); placer->UpdateSettings( m_savedMeanderSettings );
while( OPT_TOOL_EVENT evt = Wait() ) while( OPT_TOOL_EVENT evt = Wait() )
{ {
if( evt->IsCancel() || evt->IsActivate() ) if( evt->IsCancel() || evt->IsActivate() )
@ -194,10 +195,10 @@ void LENGTH_TUNER_TOOL::performTuning()
wxPoint p = wxGetMousePosition(); wxPoint p = wxGetMousePosition();
p.x+=20; p.x += 20;
p.y+=20; p.y += 20;
statusPopup.Update ( m_router ); statusPopup.Update( m_router );
statusPopup.Move( p ); statusPopup.Move( p );
} }
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
@ -209,16 +210,24 @@ void LENGTH_TUNER_TOOL::performTuning()
{ {
if( m_router->FixRoute( end, NULL ) ) if( m_router->FixRoute( end, NULL ) )
break; break;
} else if (evt->IsAction ( &ACT_AmplDecrease ) ) { }
else if( evt->IsAction( &ACT_AmplDecrease ) )
{
placer->AmplitudeStep( -1 ); placer->AmplitudeStep( -1 );
m_router->Move( end, NULL ); m_router->Move( end, NULL );
} else if (evt->IsAction ( &ACT_AmplIncrease ) ) { }
else if( evt->IsAction( &ACT_AmplIncrease ) )
{
placer->AmplitudeStep( 1 ); placer->AmplitudeStep( 1 );
m_router->Move( end, NULL ); m_router->Move( end, NULL );
} else if (evt->IsAction ( &ACT_SpacingDecrease ) ) { }
else if(evt->IsAction( &ACT_SpacingDecrease ) )
{
placer->SpacingStep( -1 ); placer->SpacingStep( -1 );
m_router->Move( end, NULL ); m_router->Move( end, NULL );
} else if (evt->IsAction ( &ACT_SpacingIncrease ) ) { }
else if( evt->IsAction( &ACT_SpacingIncrease ) )
{
placer->SpacingStep( 1 ); placer->SpacingStep( 1 );
m_router->Move( end, NULL ); m_router->Move( end, NULL );
} }
@ -244,22 +253,24 @@ void LENGTH_TUNER_TOOL::performTuning()
m_ctls->SetAutoPan( false ); m_ctls->SetAutoPan( false );
m_ctls->ForceCursorPosition( false ); m_ctls->ForceCursorPosition( false );
highlightNet( false ); highlightNet( false );
} }
int LENGTH_TUNER_TOOL::TuneSingleTrace ( const TOOL_EVENT& aEvent )
int LENGTH_TUNER_TOOL::TuneSingleTrace( const TOOL_EVENT& aEvent )
{ {
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Trace Length" ) ); m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Trace Length" ) );
return mainLoop( PNS_MODE_TUNE_SINGLE ); return mainLoop( PNS_MODE_TUNE_SINGLE );
} }
int LENGTH_TUNER_TOOL::TuneDiffPair ( const TOOL_EVENT& aEvent )
int LENGTH_TUNER_TOOL::TuneDiffPair( const TOOL_EVENT& aEvent )
{ {
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Diff Pair Length" ) ); m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Diff Pair Length" ) );
return mainLoop( PNS_MODE_TUNE_DIFF_PAIR ); return mainLoop( PNS_MODE_TUNE_DIFF_PAIR );
} }
int LENGTH_TUNER_TOOL::TuneDiffPairSkew ( const TOOL_EVENT& aEvent )
int LENGTH_TUNER_TOOL::TuneDiffPairSkew( const TOOL_EVENT& aEvent )
{ {
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Diff Pair Skew" ) ); m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Diff Pair Skew" ) );
return mainLoop( PNS_MODE_TUNE_DIFF_PAIR_SKEW ); return mainLoop( PNS_MODE_TUNE_DIFF_PAIR_SKEW );
@ -273,13 +284,13 @@ int LENGTH_TUNER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
Activate(); Activate();
m_router->SetMode ( aMode ); m_router->SetMode( aMode );
m_ctls->SetSnapping( true ); m_ctls->SetSnapping( true );
m_ctls->ShowCursor( true ); m_ctls->ShowCursor( true );
std::auto_ptr<TUNER_TOOL_MENU> ctxMenu ( new TUNER_TOOL_MENU( m_board ) ); std::auto_ptr<TUNER_TOOL_MENU> ctxMenu( new TUNER_TOOL_MENU( m_board ) );
SetContextMenu ( ctxMenu.get() ); SetContextMenu( ctxMenu.get() );
// Main loop: keep receiving events // Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() ) while( OPT_TOOL_EVENT evt = Wait() )

View File

@ -35,16 +35,15 @@ public:
void Reset( RESET_REASON aReason ); void Reset( RESET_REASON aReason );
int TuneSingleTrace ( const TOOL_EVENT& aEvent ); int TuneSingleTrace( const TOOL_EVENT& aEvent );
int TuneDiffPair ( const TOOL_EVENT& aEvent ); int TuneDiffPair( const TOOL_EVENT& aEvent );
int TuneDiffPairSkew ( const TOOL_EVENT& aEvent ); int TuneDiffPairSkew( const TOOL_EVENT& aEvent );
int ClearMeanders ( const TOOL_EVENT& aEvent ); int ClearMeanders( const TOOL_EVENT& aEvent );
private: private:
void performTuning( ); void performTuning( );
int mainLoop( PNS_ROUTER_MODE aMode ); int mainLoop( PNS_ROUTER_MODE aMode );
void handleCommonEvents( const TOOL_EVENT& evt ); void handleCommonEvents( const TOOL_EVENT& aEvent );
PNS_MEANDER_SETTINGS m_savedMeanderSettings; PNS_MEANDER_SETTINGS m_savedMeanderSettings;
}; };

View File

@ -33,13 +33,12 @@ class PNS_LOGGER;
* *
* Base class for all P&S algorithms (shoving, walkaround, line placement, dragging, etc.) * Base class for all P&S algorithms (shoving, walkaround, line placement, dragging, etc.)
* Holds a bunch of objects commonly used by all algorithms (P&S settings, parent router instance, logging) * Holds a bunch of objects commonly used by all algorithms (P&S settings, parent router instance, logging)
**/ */
class PNS_ALGO_BASE class PNS_ALGO_BASE
{ {
public: public:
PNS_ALGO_BASE( PNS_ROUTER *aRouter ) : PNS_ALGO_BASE( PNS_ROUTER* aRouter ) :
m_router ( aRouter ) m_router( aRouter )
{} {}
virtual ~PNS_ALGO_BASE() {} virtual ~PNS_ALGO_BASE() {}
@ -56,7 +55,6 @@ public:
///> Returns the logger object, allowing to dump geometry to a file. ///> Returns the logger object, allowing to dump geometry to a file.
virtual PNS_LOGGER* Logger(); virtual PNS_LOGGER* Logger();
private: private:
PNS_ROUTER* m_router; PNS_ROUTER* m_router;
}; };

View File

@ -39,44 +39,48 @@
class PNS_LINE; class PNS_LINE;
PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR ( PNS_ITEM *aPrimP, PNS_ITEM *aPrimN ) PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( PNS_ITEM* aPrimP, PNS_ITEM* aPrimN )
{ {
m_primP = aPrimP->Clone(); m_primP = aPrimP->Clone();
m_primN = aPrimN->Clone(); m_primN = aPrimN->Clone();
m_anchorP = m_primP->Anchor(0); m_anchorP = m_primP->Anchor( 0 );
m_anchorN = m_primN->Anchor(0); m_anchorN = m_primN->Anchor( 0 );
} }
void PNS_DP_PRIMITIVE_PAIR::SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN ) void PNS_DP_PRIMITIVE_PAIR::SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN )
{ {
m_anchorP = aAnchorP; m_anchorP = aAnchorP;
m_anchorN = aAnchorN; m_anchorN = aAnchorN;
} }
PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR ( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN )
PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN )
{ {
m_anchorP = aAnchorP; m_anchorP = aAnchorP;
m_anchorN = aAnchorN; m_anchorN = aAnchorN;
m_primP = m_primN = NULL; m_primP = m_primN = NULL;
} }
PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR ( const PNS_DP_PRIMITIVE_PAIR& aOther )
PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( const PNS_DP_PRIMITIVE_PAIR& aOther )
{ {
if(aOther.m_primP) if( aOther.m_primP )
m_primP = aOther.m_primP->Clone(); m_primP = aOther.m_primP->Clone();
if(aOther.m_primN) if( aOther.m_primN )
m_primN = aOther.m_primN->Clone(); m_primN = aOther.m_primN->Clone();
m_anchorP = aOther.m_anchorP; m_anchorP = aOther.m_anchorP;
m_anchorN = aOther.m_anchorN; m_anchorN = aOther.m_anchorN;
} }
PNS_DP_PRIMITIVE_PAIR& PNS_DP_PRIMITIVE_PAIR::operator= ( const PNS_DP_PRIMITIVE_PAIR& aOther )
PNS_DP_PRIMITIVE_PAIR& PNS_DP_PRIMITIVE_PAIR::operator=( const PNS_DP_PRIMITIVE_PAIR& aOther )
{ {
if(aOther.m_primP) if( aOther.m_primP )
m_primP = aOther.m_primP->Clone(); m_primP = aOther.m_primP->Clone();
if(aOther.m_primN) if( aOther.m_primN )
m_primN = aOther.m_primN->Clone(); m_primN = aOther.m_primN->Clone();
m_anchorP = aOther.m_anchorP; m_anchorP = aOther.m_anchorP;
@ -92,98 +96,107 @@ PNS_DP_PRIMITIVE_PAIR::~PNS_DP_PRIMITIVE_PAIR()
delete m_primN; delete m_primN;
} }
bool PNS_DP_PRIMITIVE_PAIR::Directional() const bool PNS_DP_PRIMITIVE_PAIR::Directional() const
{ {
if (!m_primP) if( !m_primP )
return false; return false;
return m_primP->OfKind(PNS_ITEM::SEGMENT); return m_primP->OfKind( PNS_ITEM::SEGMENT );
} }
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::anchorDirection ( PNS_ITEM *aItem, const VECTOR2I& aP ) const
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::anchorDirection( PNS_ITEM* aItem, const VECTOR2I& aP ) const
{ {
if( !aItem->OfKind ( PNS_ITEM::SEGMENT ) ) if( !aItem->OfKind ( PNS_ITEM::SEGMENT ) )
return DIRECTION_45(); return DIRECTION_45();
PNS_SEGMENT *s = static_cast<PNS_SEGMENT *> (aItem); PNS_SEGMENT* s = static_cast<PNS_SEGMENT*>( aItem );
if(s->Seg().A == aP) if( s->Seg().A == aP )
return DIRECTION_45 ( s->Seg().A - s->Seg().B ); return DIRECTION_45( s->Seg().A - s->Seg().B );
else else
return DIRECTION_45 ( s->Seg().B - s->Seg().A ); return DIRECTION_45( s->Seg().B - s->Seg().A );
} }
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirP () const
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirP() const
{ {
return anchorDirection ( m_primP, m_anchorP ); return anchorDirection( m_primP, m_anchorP );
} }
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirN () const
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirN() const
{ {
return anchorDirection ( m_primN, m_anchorN ); return anchorDirection( m_primN, m_anchorN );
} }
static void drawGw ( VECTOR2I p, int color )
static void drawGw( VECTOR2I p, int color )
{ {
SHAPE_LINE_CHAIN l; SHAPE_LINE_CHAIN l;
l.Append ( p - VECTOR2I(-50000, -50000) ); l.Append( p - VECTOR2I( -50000, -50000 ) );
l.Append ( p + VECTOR2I(-50000, -50000) ); l.Append( p + VECTOR2I( -50000, -50000 ) );
//printf("router @ %p\n", PNS_ROUTER::GetInstance()); //printf("router @ %p\n", PNS_ROUTER::GetInstance());
// PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 ); // PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 );
l.Clear(); l.Clear();
l.Append ( p - VECTOR2I(50000, -50000) ); l.Append( p - VECTOR2I( 50000, -50000 ) );
l.Append ( p + VECTOR2I(50000, -50000) ); l.Append( p + VECTOR2I( 50000, -50000 ) );
// PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 ); // PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 );
} }
static DIRECTION_45::AngleType angle ( const VECTOR2I &a, const VECTOR2I &b ) static DIRECTION_45::AngleType angle( const VECTOR2I &a, const VECTOR2I &b )
{ {
DIRECTION_45 dir_a(a); DIRECTION_45 dir_a( a );
DIRECTION_45 dir_b(b); DIRECTION_45 dir_b( b );
return dir_a.Angle(dir_b);
return dir_a.Angle( dir_b );
} }
static bool checkGap ( const SHAPE_LINE_CHAIN &p, const SHAPE_LINE_CHAIN &n, int gap )
static bool checkGap( const SHAPE_LINE_CHAIN &p, const SHAPE_LINE_CHAIN &n, int gap )
{ {
int i, j; int i, j;
for (i = 0; i < p.SegmentCount() ;i++) for( i = 0; i < p.SegmentCount(); i++ )
for (j = 0; j < n.SegmentCount() ; j++)
{ {
int dist = p.CSegment(i).Distance (n.CSegment(j)); for( j = 0; j < n.SegmentCount() ; j++ )
if (dist < gap - 100) {
int dist = p.CSegment( i ).Distance( n.CSegment( j ) );
if( dist < gap - 100 )
return false; return false;
} }
}
return true; return true;
} }
void PNS_DP_GATEWAY::Reverse() void PNS_DP_GATEWAY::Reverse()
{ {
m_entryN = m_entryN.Reverse(); m_entryN = m_entryN.Reverse();
m_entryP = m_entryP.Reverse(); m_entryP = m_entryP.Reverse();
} }
bool PNS_DIFF_PAIR::BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal )
bool PNS_DIFF_PAIR::BuildInitial( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal )
{ {
SHAPE_LINE_CHAIN p = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorP(), aTarget.AnchorP(), aPrefDiagonal ); SHAPE_LINE_CHAIN p = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorP(), aTarget.AnchorP(), aPrefDiagonal );
SHAPE_LINE_CHAIN n = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorN(), aTarget.AnchorN(), aPrefDiagonal ); SHAPE_LINE_CHAIN n = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorN(), aTarget.AnchorN(), aPrefDiagonal );
if(!checkGap ( p, n, m_gapConstraint )) if( !checkGap ( p, n, m_gapConstraint ) )
return false; return false;
if (p.SelfIntersecting() || n.SelfIntersecting() ) if( p.SelfIntersecting() || n.SelfIntersecting() )
return false; return false;
if(p.Intersects(n)) if( p.Intersects( n ) )
return false; return false;
int mask = aEntry.AllowedAngles() | DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_OBTUSE; int mask = aEntry.AllowedAngles() | DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_OBTUSE;
@ -194,13 +207,16 @@ bool PNS_DIFF_PAIR::BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarg
if( aEntry.HasEntryLines() ) if( aEntry.HasEntryLines() )
{ {
if ( !aEntry.Entry().CheckConnectionAngle( *this, mask ) ) if( !aEntry.Entry().CheckConnectionAngle( *this, mask ) )
return false; return false;
sum_p = aEntry.Entry().CP(); sum_p = aEntry.Entry().CP();
sum_n = aEntry.Entry().CN(); sum_n = aEntry.Entry().CN();
sum_p.Append(p); sum_p.Append( p );
sum_n.Append(n); sum_n.Append( n );
} else { }
else
{
sum_p = p; sum_p = p;
sum_n = n; sum_n = n;
} }
@ -220,7 +236,6 @@ bool PNS_DIFF_PAIR::BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarg
sum_p.Append( t.Entry().CP() ); sum_p.Append( t.Entry().CP() );
sum_n.Append( t.Entry().CN() ); sum_n.Append( t.Entry().CN() );
} }
m_p = sum_p; m_p = sum_p;
@ -229,89 +244,92 @@ bool PNS_DIFF_PAIR::BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarg
return true; return true;
} }
bool PNS_DIFF_PAIR::CheckConnectionAngle ( const PNS_DIFF_PAIR &aOther, int allowedAngles ) const
bool PNS_DIFF_PAIR::CheckConnectionAngle( const PNS_DIFF_PAIR& aOther, int aAllowedAngles ) const
{ {
bool checkP, checkN; bool checkP, checkN;
if( m_p.SegmentCount() == 0 || aOther.m_p.SegmentCount() == 0 )
if( m_p.SegmentCount() == 0 || aOther.m_p.SegmentCount() == 0)
checkP = true; checkP = true;
else { else
DIRECTION_45 p0 ( m_p.CSegment(-1) ); {
DIRECTION_45 p1 ( aOther.m_p.CSegment(0) ); DIRECTION_45 p0( m_p.CSegment( -1 ) );
DIRECTION_45 p1( aOther.m_p.CSegment( 0 ) );
checkP = (p0.Angle(p1) & allowedAngles) != 0; checkP = ( p0.Angle( p1 ) & aAllowedAngles ) != 0;
} }
if( m_n.SegmentCount() == 0 || aOther.m_n.SegmentCount() == 0 )
if( m_n.SegmentCount() == 0 || aOther.m_n.SegmentCount() == 0)
checkN = true; checkN = true;
else { else
DIRECTION_45 n0 ( m_n.CSegment(-1) ); {
DIRECTION_45 n1 ( aOther.m_n.CSegment(0) ); DIRECTION_45 n0( m_n.CSegment( -1 ) );
DIRECTION_45 n1( aOther.m_n.CSegment( 0 ) );
checkN = (n0.Angle(n1) & allowedAngles) != 0; checkN = ( n0.Angle( n1 ) & aAllowedAngles ) != 0;
} }
return checkP && checkN; return checkP && checkN;
} }
const PNS_DIFF_PAIR PNS_DP_GATEWAY::Entry() const const PNS_DIFF_PAIR PNS_DP_GATEWAY::Entry() const
{ {
return PNS_DIFF_PAIR(m_entryP, m_entryN, 0); return PNS_DIFF_PAIR( m_entryP, m_entryN, 0 );
} }
void PNS_DP_GATEWAYS::BuildOrthoProjections ( PNS_DP_GATEWAYS& aEntries, const VECTOR2I& aCursorPos, int aOrthoScore )
void PNS_DP_GATEWAYS::BuildOrthoProjections( PNS_DP_GATEWAYS& aEntries,
const VECTOR2I& aCursorPos, int aOrthoScore )
{ {
BOOST_FOREACH(PNS_DP_GATEWAY g, aEntries.Gateways()) BOOST_FOREACH( PNS_DP_GATEWAY g, aEntries.Gateways() )
{ {
VECTOR2I dir = (g.AnchorP() - g.AnchorN()).Perpendicular(); VECTOR2I dir = ( g.AnchorP() - g.AnchorN() ).Perpendicular();
VECTOR2I midpoint ( ( g.AnchorP() + g.AnchorN() ) / 2); VECTOR2I midpoint( ( g.AnchorP() + g.AnchorN() ) / 2 );
SEG guide ( midpoint, midpoint + dir ); SEG guide( midpoint, midpoint + dir );
VECTOR2I proj = guide.LineProject(aCursorPos); VECTOR2I proj = guide.LineProject( aCursorPos );
PNS_DP_GATEWAYS targets( m_gap );
PNS_DP_GATEWAYS targets(m_gap);
targets.m_viaGap = m_viaGap; targets.m_viaGap = m_viaGap;
targets.m_viaDiameter = m_viaDiameter; targets.m_viaDiameter = m_viaDiameter;
targets.m_fitVias = m_fitVias; targets.m_fitVias = m_fitVias;
targets.BuildForCursor ( proj ); targets.BuildForCursor( proj );
BOOST_FOREACH ( PNS_DP_GATEWAY t, targets.Gateways() ) BOOST_FOREACH( PNS_DP_GATEWAY t, targets.Gateways() )
{ {
t.SetPriority ( aOrthoScore ); t.SetPriority( aOrthoScore );
m_gateways.push_back ( t ); m_gateways.push_back( t );
} }
} }
} }
bool PNS_DP_GATEWAYS::FitGateways ( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget, bool aPrefDiagonal, PNS_DIFF_PAIR& aDp ) bool PNS_DP_GATEWAYS::FitGateways( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget,
bool aPrefDiagonal, PNS_DIFF_PAIR& aDp )
{ {
std::vector<DP_CANDIDATE> candidates; std::vector<DP_CANDIDATE> candidates;
BOOST_FOREACH( PNS_DP_GATEWAY g_entry, aEntry.Gateways() ) BOOST_FOREACH( PNS_DP_GATEWAY g_entry, aEntry.Gateways() )
{ {
BOOST_FOREACH ( PNS_DP_GATEWAY g_target, aTarget.Gateways() ) BOOST_FOREACH( PNS_DP_GATEWAY g_target, aTarget.Gateways() )
{ {
for(int attempt = 0; attempt < 2; attempt ++) for( int attempt = 0; attempt < 2; attempt++ )
{ {
PNS_DIFF_PAIR l ( m_gap ); PNS_DIFF_PAIR l( m_gap );
if ( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ (attempt ? true : false) ) ) if( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ ( attempt ? true : false ) ) )
{ {
int score = (attempt == 1 ? -3 : 0); int score = ( attempt == 1 ? -3 : 0 );
score +=g_entry.Priority(); score +=g_entry.Priority();
score +=g_target.Priority(); score +=g_target.Priority();
DP_CANDIDATE c; DP_CANDIDATE c;
c.score = score; c.score = score;
c.p = l.CP(); c.p = l.CP();
c.n = l.CN(); c.n = l.CN();
candidates.push_back(c); candidates.push_back( c );
} }
} }
} }
@ -323,7 +341,7 @@ bool PNS_DP_GATEWAYS::FitGateways ( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& a
BOOST_FOREACH( DP_CANDIDATE c, candidates ) BOOST_FOREACH( DP_CANDIDATE c, candidates )
{ {
if ( c.score > bestScore ) if( c.score > bestScore )
{ {
bestScore = c.score; bestScore = c.score;
best = c; best = c;
@ -331,9 +349,9 @@ bool PNS_DP_GATEWAYS::FitGateways ( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& a
} }
} }
if ( found ) if( found )
{ {
aDp.SetGap ( m_gap ); aDp.SetGap( m_gap );
aDp.SetShape( best.p, best.n ); aDp.SetShape( best.p, best.n );
return true; return true;
} }
@ -341,7 +359,8 @@ bool PNS_DP_GATEWAYS::FitGateways ( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& a
return false; return false;
} }
bool PNS_DP_GATEWAYS::checkDiagonalAlignment ( const VECTOR2I& a, const VECTOR2I& b) const
bool PNS_DP_GATEWAYS::checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I& b ) const
{ {
VECTOR2I dir ( std::abs (a.x - b.x), std::abs ( a.y - b.y )); VECTOR2I dir ( std::abs (a.x - b.x), std::abs ( a.y - b.y ));
@ -355,53 +374,55 @@ void PNS_DP_GATEWAYS::BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool
VECTOR2I p0_p, p0_n; VECTOR2I p0_p, p0_n;
int orthoFanDistance; int orthoFanDistance;
int diagFanDistance; int diagFanDistance;
const SHAPE *shP = NULL; const SHAPE* shP = NULL;
if( aPair.PrimP() == NULL) if( aPair.PrimP() == NULL )
{ {
BuildGeneric ( aPair.AnchorP(), aPair.AnchorN(), true ); BuildGeneric( aPair.AnchorP(), aPair.AnchorN(), true );
return; return;
} }
const int pvMask = PNS_ITEM::SOLID | PNS_ITEM::VIA; const int pvMask = PNS_ITEM::SOLID | PNS_ITEM::VIA;
if ( aPair.PrimP()->OfKind ( pvMask ) && aPair.PrimN()->OfKind ( pvMask ) ) if( aPair.PrimP()->OfKind( pvMask ) && aPair.PrimN()->OfKind( pvMask ) )
{ {
p0_p = aPair.AnchorP(); p0_p = aPair.AnchorP();
p0_n = aPair.AnchorN(); p0_n = aPair.AnchorN();
shP = aPair.PrimP()->Shape(); shP = aPair.PrimP()->Shape();
} else if ( aPair.PrimP()->OfKind ( PNS_ITEM::SEGMENT ) && aPair.PrimN()->OfKind ( PNS_ITEM::SEGMENT ) ) { }
buildDpContinuation ( aPair, aPreferDiagonal ); else if( aPair.PrimP()->OfKind( PNS_ITEM::SEGMENT ) && aPair.PrimN()->OfKind( PNS_ITEM::SEGMENT ) )
{
buildDpContinuation( aPair, aPreferDiagonal );
return; return;
} }
majorDirection = (p0_p - p0_n).Perpendicular(); majorDirection = ( p0_p - p0_n ).Perpendicular();
switch( shP->Type() ) switch( shP->Type() )
{ {
case SH_RECT: case SH_RECT:
{ {
int w = static_cast<const SHAPE_RECT*> ( shP )->GetWidth(); int w = static_cast<const SHAPE_RECT*>( shP )->GetWidth();
int h = static_cast<const SHAPE_RECT*> ( shP )->GetHeight(); int h = static_cast<const SHAPE_RECT*>( shP )->GetHeight();
if(w < h) if( w < h )
std::swap(w,h); std::swap( w, h );
orthoFanDistance = w * 3/4; orthoFanDistance = w * 3/4;
diagFanDistance = (w - h) / 2; diagFanDistance = ( w - h ) / 2;
break; break;
} }
case SH_SEGMENT: case SH_SEGMENT:
{ {
int w = static_cast<const SHAPE_SEGMENT*> ( shP )->GetWidth(); int w = static_cast<const SHAPE_SEGMENT*>( shP )->GetWidth();
SEG s = static_cast<const SHAPE_SEGMENT*> ( shP )->GetSeg(); SEG s = static_cast<const SHAPE_SEGMENT*>( shP )->GetSeg();
orthoFanDistance = w + (s.B - s.A).EuclideanNorm() / 2; orthoFanDistance = w + ( s.B - s.A ).EuclideanNorm() / 2;
diagFanDistance = (s.B - s.A).EuclideanNorm() / 2; diagFanDistance = ( s.B - s.A ).EuclideanNorm() / 2;
break; break;
} }
@ -410,49 +431,50 @@ void PNS_DP_GATEWAYS::BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool
return; return;
} }
if(checkDiagonalAlignment ( p0_p, p0_n )) if( checkDiagonalAlignment( p0_p, p0_n ) )
{ {
int padDist = (p0_p - p0_n).EuclideanNorm(); int padDist = ( p0_p - p0_n ).EuclideanNorm();
for(int k = 0; k < 2; k++ ) for( int k = 0; k < 2; k++ )
{ {
VECTOR2I dir, dp, dv; VECTOR2I dir, dp, dv;
if(k == 0) if( k == 0 )
{ {
dir = majorDirection.Resize( orthoFanDistance );
dir = majorDirection.Resize(orthoFanDistance); int d = ( padDist - m_gap ) / 2;
int d = (padDist - m_gap) / 2;
dp = dir.Resize( d ); dp = dir.Resize( d );
dv = (p0_n - p0_p).Resize( d ); dv = ( p0_n - p0_p ).Resize( d );
} else { }
dir = majorDirection.Resize(diagFanDistance); else
int d = (padDist - m_gap) / 2; {
dir = majorDirection.Resize( diagFanDistance );
int d = ( padDist - m_gap ) / 2;
dp = dir.Resize( d ); dp = dir.Resize( d );
dv = (p0_n - p0_p).Resize( d ); dv = ( p0_n - p0_p ).Resize( d );
} }
for(int i = 0; i < 2; i++) for( int i = 0; i < 2; i++ )
{ {
int sign = i ? -1 : 1; int sign = i ? -1 : 1;
VECTOR2I gw_p ( p0_p + sign * (dir + dp) + dv ); VECTOR2I gw_p( p0_p + sign * ( dir + dp ) + dv );
VECTOR2I gw_n ( p0_n + sign * (dir + dp) - dv ); VECTOR2I gw_n( p0_n + sign * ( dir + dp ) - dv );
SHAPE_LINE_CHAIN entryP (p0_p, p0_p + sign * dir, gw_p); SHAPE_LINE_CHAIN entryP( p0_p, p0_p + sign * dir, gw_p );
SHAPE_LINE_CHAIN entryN (p0_n, p0_n + sign * dir, gw_n); SHAPE_LINE_CHAIN entryN( p0_n, p0_n + sign * dir, gw_n );
PNS_DP_GATEWAY gw ( gw_p, gw_n, false ); PNS_DP_GATEWAY gw( gw_p, gw_n, false );
gw.SetEntryLines ( entryP, entryN ); gw.SetEntryLines( entryP, entryN );
gw.SetPriority(100 - k); gw.SetPriority( 100 - k );
m_gateways.push_back( gw ); m_gateways.push_back( gw );
} }
} }
} }
BuildGeneric ( p0_p, p0_n, true ); BuildGeneric( p0_p, p0_n, true );
} }
@ -460,34 +482,35 @@ void PNS_DP_GATEWAYS::BuildForCursor( const VECTOR2I& aCursorPos )
{ {
int gap = m_fitVias ? m_viaGap + m_viaDiameter : m_gap; int gap = m_fitVias ? m_viaGap + m_viaDiameter : m_gap;
for (int attempt = 0; attempt < 2; attempt ++) for( int attempt = 0; attempt < 2; attempt++ )
{ {
for(int i = 0; i < 4; i++ ) for( int i = 0; i < 4; i++ )
{ {
VECTOR2I dir; VECTOR2I dir;
if( !attempt ) if( !attempt )
{ {
dir = VECTOR2I( gap, gap ).Resize( gap / 2 ); dir = VECTOR2I( gap, gap ).Resize( gap / 2 );
if( i % 2 == 0 ) if( i % 2 == 0 )
dir.x = -dir.x; dir.x = -dir.x;
if( i / 2 == 0 ) if( i / 2 == 0 )
dir.y = -dir.y; dir.y = -dir.y;
} }
else else
{ {
if( i /2 == 0) if( i /2 == 0 )
dir = VECTOR2I( gap / 2 * ( (i % 2) ? -1 : 1), 0 ); dir = VECTOR2I( gap / 2 * ( ( i % 2 ) ? -1 : 1 ), 0 );
else else
dir = VECTOR2I( 0, gap / 2 * ( (i % 2) ? -1 : 1) ); dir = VECTOR2I( 0, gap / 2 * ( ( i % 2 ) ? -1 : 1) );
} }
if( m_fitVias ) if( m_fitVias )
BuildGeneric ( aCursorPos + dir, aCursorPos - dir, true, true ); BuildGeneric( aCursorPos + dir, aCursorPos - dir, true, true );
else else
m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir, aCursorPos - dir, attempt ? true : false ) ); m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir,
aCursorPos - dir, attempt ? true : false ) );
drawGw ( aCursorPos + dir, 2 ); drawGw ( aCursorPos + dir, 2 );
drawGw ( aCursorPos - dir, 3 ); drawGw ( aCursorPos - dir, 3 );
@ -496,42 +519,42 @@ void PNS_DP_GATEWAYS::BuildForCursor( const VECTOR2I& aCursorPos )
} }
void PNS_DP_GATEWAYS::buildEntries ( const VECTOR2I& p0_p, const VECTOR2I& p0_n ) void PNS_DP_GATEWAYS::buildEntries( const VECTOR2I& p0_p, const VECTOR2I& p0_n )
{ {
BOOST_FOREACH (PNS_DP_GATEWAY &g, m_gateways ) BOOST_FOREACH( PNS_DP_GATEWAY &g, m_gateways )
{ {
if ( !g.HasEntryLines() ) if( !g.HasEntryLines() )
{ {
SHAPE_LINE_CHAIN lead_p = DIRECTION_45().BuildInitialTrace ( g.AnchorP(), p0_p, g.IsDiagonal() ).Reverse(); SHAPE_LINE_CHAIN lead_p = DIRECTION_45().BuildInitialTrace ( g.AnchorP(), p0_p, g.IsDiagonal() ).Reverse();
SHAPE_LINE_CHAIN lead_n = DIRECTION_45().BuildInitialTrace ( g.AnchorN(), p0_n, g.IsDiagonal() ).Reverse(); SHAPE_LINE_CHAIN lead_n = DIRECTION_45().BuildInitialTrace ( g.AnchorN(), p0_n, g.IsDiagonal() ).Reverse();
g.SetEntryLines(lead_p, lead_n); g.SetEntryLines( lead_p, lead_n );
} }
} }
} }
void PNS_DP_GATEWAYS::buildDpContinuation ( PNS_DP_PRIMITIVE_PAIR aPair, bool aIsDiagonal ) void PNS_DP_GATEWAYS::buildDpContinuation( PNS_DP_PRIMITIVE_PAIR aPair, bool aIsDiagonal )
{ {
PNS_DP_GATEWAY gw ( aPair.AnchorP(), aPair.AnchorN(), aIsDiagonal ); PNS_DP_GATEWAY gw( aPair.AnchorP(), aPair.AnchorN(), aIsDiagonal );
gw.SetPriority( 100 ); gw.SetPriority( 100 );
m_gateways.push_back ( gw ); m_gateways.push_back( gw );
if ( !aPair.Directional() ) if( !aPair.Directional() )
return; return;
DIRECTION_45 dP = aPair.DirP(); DIRECTION_45 dP = aPair.DirP();
DIRECTION_45 dN = aPair.DirN(); DIRECTION_45 dN = aPair.DirN();
int gap = (aPair.AnchorP() - aPair.AnchorN()).EuclideanNorm(); int gap = ( aPair.AnchorP() - aPair.AnchorN() ).EuclideanNorm();
VECTOR2I vdP = aPair.AnchorP() + dP.Left().ToVector(); VECTOR2I vdP = aPair.AnchorP() + dP.Left().ToVector();
VECTOR2I vdN = aPair.AnchorN() + dN.Left().ToVector(); VECTOR2I vdN = aPair.AnchorN() + dN.Left().ToVector();
PNS_SEGMENT *sP = static_cast <PNS_SEGMENT*> (aPair.PrimP()); PNS_SEGMENT* sP = static_cast<PNS_SEGMENT*>( aPair.PrimP() );
VECTOR2I t1, t2; VECTOR2I t1, t2;
if( sP->Seg().Side(vdP) == sP->Seg().Side(vdN )) if( sP->Seg().Side( vdP ) == sP->Seg().Side( vdN ) )
{ {
t1 = aPair.AnchorP() + dP.Left().ToVector().Resize( gap ); t1 = aPair.AnchorP() + dP.Left().ToVector().Resize( gap );
t2 = aPair.AnchorN() + dP.Right().ToVector().Resize( gap ); t2 = aPair.AnchorN() + dP.Right().ToVector().Resize( gap );
@ -542,21 +565,20 @@ void PNS_DP_GATEWAYS::buildDpContinuation ( PNS_DP_PRIMITIVE_PAIR aPair, bool aI
t2 = aPair.AnchorN() + dP.Left().ToVector().Resize( gap ); t2 = aPair.AnchorN() + dP.Left().ToVector().Resize( gap );
} }
PNS_DP_GATEWAY gwL( t2, aPair.AnchorN(), !aIsDiagonal );
SHAPE_LINE_CHAIN ep = dP.BuildInitialTrace( aPair.AnchorP(), t2, !aIsDiagonal );
PNS_DP_GATEWAY gwL ( t2, aPair.AnchorN(), !aIsDiagonal ); gwL.SetPriority( 10 );
SHAPE_LINE_CHAIN ep = dP.BuildInitialTrace ( aPair.AnchorP(), t2, !aIsDiagonal ); gwL.SetEntryLines( ep , SHAPE_LINE_CHAIN() );
gwL.SetPriority(10); m_gateways.push_back( gwL );
gwL.SetEntryLines ( ep , SHAPE_LINE_CHAIN( ) );
m_gateways.push_back(gwL); PNS_DP_GATEWAY gwR( aPair.AnchorP(), t1, !aIsDiagonal );
SHAPE_LINE_CHAIN en = dP.BuildInitialTrace( aPair.AnchorN(), t1, !aIsDiagonal );
gwR.SetPriority( 10) ;
gwR.SetEntryLines( SHAPE_LINE_CHAIN(), en );
PNS_DP_GATEWAY gwR (aPair.AnchorP(), t1, !aIsDiagonal ); m_gateways.push_back( gwR );
SHAPE_LINE_CHAIN en = dP.BuildInitialTrace ( aPair.AnchorN(), t1, !aIsDiagonal );
gwR.SetPriority(10);
gwR.SetEntryLines ( SHAPE_LINE_CHAIN( ), en );
m_gateways.push_back(gwR);
} }
@ -566,21 +588,21 @@ void PNS_DP_GATEWAYS::BuildGeneric( const VECTOR2I& p0_p, const VECTOR2I& p0_n,
SEG d_n[2], d_p[2]; SEG d_n[2], d_p[2];
const int padToGapThreshold = 3; const int padToGapThreshold = 3;
int padDist = ( p0_p - p0_p ).EuclideanNorm( ); int padDist = ( p0_p - p0_p ).EuclideanNorm();
st_p[0] = SEG(p0_p + VECTOR2I(-100, 0), p0_p + VECTOR2I(100, 0) ); st_p[0] = SEG(p0_p + VECTOR2I( -100, 0 ), p0_p + VECTOR2I( 100, 0 ) );
st_n[0] = SEG(p0_n + VECTOR2I(-100, 0), p0_n + VECTOR2I(100, 0) ); st_n[0] = SEG(p0_n + VECTOR2I( -100, 0 ), p0_n + VECTOR2I( 100, 0 ) );
st_p[1] = SEG(p0_p + VECTOR2I(0, -100), p0_p + VECTOR2I(0, 100) ); st_p[1] = SEG(p0_p + VECTOR2I( 0, -100 ), p0_p + VECTOR2I( 0, 100 ) );
st_n[1] = SEG(p0_n + VECTOR2I(0, -100), p0_n + VECTOR2I(0, 100) ); st_n[1] = SEG(p0_n + VECTOR2I( 0, -100 ), p0_n + VECTOR2I( 0, 100 ) );
d_p[0] = SEG ( p0_p + VECTOR2I (-100, -100), p0_p + VECTOR2I(100, 100)); d_p[0] = SEG( p0_p + VECTOR2I( -100, -100 ), p0_p + VECTOR2I( 100, 100 ) );
d_p[1] = SEG ( p0_p + VECTOR2I (100, -100), p0_p + VECTOR2I(-100, 100)); d_p[1] = SEG( p0_p + VECTOR2I( 100, -100 ), p0_p + VECTOR2I( -100, 100 ) );
d_n[0] = SEG ( p0_n + VECTOR2I (-100, -100), p0_n + VECTOR2I(100, 100)); d_n[0] = SEG( p0_n + VECTOR2I( -100, -100 ), p0_n + VECTOR2I( 100, 100 ) );
d_n[1] = SEG ( p0_n + VECTOR2I (100, -100), p0_n + VECTOR2I(-100, 100)); d_n[1] = SEG( p0_n + VECTOR2I( 100, -100 ), p0_n + VECTOR2I( -100, 100 ) );
// midpoint exit & side-by exits // midpoint exit & side-by exits
for(int i = 0; i < 2; i++) for( int i = 0; i < 2; i++ )
{ {
bool straightColl = st_p[i].Collinear ( st_n[i] ); bool straightColl = st_p[i].Collinear( st_n[i] );
bool diagColl = d_p[i].Collinear( d_n[i] ); bool diagColl = d_p[i].Collinear( d_n[i] );
if( straightColl || diagColl ) if( straightColl || diagColl )
@ -589,7 +611,7 @@ void PNS_DP_GATEWAYS::BuildGeneric( const VECTOR2I& p0_p, const VECTOR2I& p0_n,
VECTOR2I m = ( p0_p + p0_n ) / 2; VECTOR2I m = ( p0_p + p0_n ) / 2;
int prio = ( padDist > padToGapThreshold * m_gap ? 2 : 1); int prio = ( padDist > padToGapThreshold * m_gap ? 2 : 1);
if(!aViaMode) if( !aViaMode )
{ {
m_gateways.push_back( PNS_DP_GATEWAY( m - dir, m + dir, diagColl, DIRECTION_45::ANG_RIGHT, prio ) ); m_gateways.push_back( PNS_DP_GATEWAY( m - dir, m + dir, diagColl, DIRECTION_45::ANG_RIGHT, prio ) );
@ -602,30 +624,30 @@ void PNS_DP_GATEWAYS::BuildGeneric( const VECTOR2I& p0_p, const VECTOR2I& p0_n,
} }
} }
for( int i = 0; i < 2; i++ )
for (int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) for( int j = 0; j < 2; j++ )
{ {
OPT_VECTOR2I ips[2], m; OPT_VECTOR2I ips[2], m;
ips[0] = d_n[i].IntersectLines( d_p[j] ); ips[0] = d_n[i].IntersectLines( d_p[j] );
ips[1] = st_p[i].IntersectLines( st_n[j] ); ips[1] = st_p[i].IntersectLines( st_n[j] );
if ( d_n[i].Collinear (d_p[j]) ) if( d_n[i].Collinear( d_p[j] ) )
ips [0] = OPT_VECTOR2I(); ips [0] = OPT_VECTOR2I();
if ( st_p[i].Collinear (st_p[j]) ) if( st_p[i].Collinear( st_p[j] ) )
ips [1] = OPT_VECTOR2I(); ips [1] = OPT_VECTOR2I();
// diagonal-diagonal and straight-straight cases - the most typical case if the pads // diagonal-diagonal and straight-straight cases - the most typical case if the pads
// are on the same straight/diagonal line // are on the same straight/diagonal line
for ( int k = 0; k < 2; k++ ) for( int k = 0; k < 2; k++ )
{ {
m = ips [ k ]; m = ips[k];
if(m && *m != p0_p && *m != p0_n ) if( m && *m != p0_p && *m != p0_n )
{ {
int prio = ( padDist > padToGapThreshold * m_gap ? 10 : 20); int prio = ( padDist > padToGapThreshold * m_gap ? 10 : 20 );
VECTOR2I g_p ( ( p0_p - *m ).Resize ( ( double ) m_gap * M_SQRT1_2 ) ); VECTOR2I g_p( ( p0_p - *m ).Resize( (double) m_gap * M_SQRT1_2 ) );
VECTOR2I g_n ( ( p0_n - *m ).Resize ( ( double ) m_gap * M_SQRT1_2 ) ); VECTOR2I g_n( ( p0_n - *m ).Resize( (double) m_gap * M_SQRT1_2 ) );
m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, k == 0 ? true : false, DIRECTION_45::ANG_OBTUSE, prio ) ); m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, k == 0 ? true : false, DIRECTION_45::ANG_OBTUSE, prio ) );
} }
@ -635,175 +657,182 @@ void PNS_DP_GATEWAYS::BuildGeneric( const VECTOR2I& p0_p, const VECTOR2I& p0_n,
ips[1] = st_p[i].IntersectLines( d_n[j] ); ips[1] = st_p[i].IntersectLines( d_n[j] );
// diagonal-straight cases: 8 possibilities of "weirder" exists // diagonal-straight cases: 8 possibilities of "weirder" exists
for ( int k = 0; k < 2; k++ ) for( int k = 0; k < 2; k++ )
{ {
m = ips[k]; m = ips[k];
if(!aViaMode && m && *m != p0_p && *m != p0_n ) if( !aViaMode && m && *m != p0_p && *m != p0_n )
{ {
VECTOR2I g_p, g_n; VECTOR2I g_p, g_n;
g_p = ( p0_p - *m ).Resize ((double)m_gap * M_SQRT2 ); g_p = ( p0_p - *m ).Resize( (double) m_gap * M_SQRT2 );
g_n = ( p0_n - *m ).Resize ((double)m_gap ); g_n = ( p0_n - *m ).Resize( (double) m_gap );
if ( angle ( g_p, g_n ) != DIRECTION_45::ANG_ACUTE ) if( angle( g_p, g_n ) != DIRECTION_45::ANG_ACUTE )
m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, true ) ); m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, true ) );
g_p = ( p0_p - *m ).Resize ( m_gap ); g_p = ( p0_p - *m ).Resize( m_gap );
g_n = ( p0_n - *m ).Resize ( (double)m_gap * M_SQRT2 ); g_n = ( p0_n - *m ).Resize( (double) m_gap * M_SQRT2 );
if ( angle ( g_p, g_n ) != DIRECTION_45::ANG_ACUTE ) if( angle( g_p, g_n ) != DIRECTION_45::ANG_ACUTE )
m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, true ) ); m_gateways.push_back( PNS_DP_GATEWAY( *m + g_p, *m + g_n, true ) );
}
} }
} }
} }
if (aBuildEntries) if( aBuildEntries )
buildEntries(p0_p, p0_n); buildEntries( p0_p, p0_n );
} }
PNS_DP_PRIMITIVE_PAIR PNS_DIFF_PAIR::EndingPrimitives() PNS_DP_PRIMITIVE_PAIR PNS_DIFF_PAIR::EndingPrimitives()
{ {
if (m_hasVias) if( m_hasVias )
return PNS_DP_PRIMITIVE_PAIR ( &m_via_p, &m_via_n ); return PNS_DP_PRIMITIVE_PAIR( &m_via_p, &m_via_n );
else else
{ {
const PNS_LINE lP ( PLine() ); const PNS_LINE lP( PLine() );
const PNS_LINE lN ( NLine() ); const PNS_LINE lN( NLine() );
PNS_SEGMENT sP ( lP, lP.CSegment(-1) ); PNS_SEGMENT sP( lP, lP.CSegment( -1 ) );
PNS_SEGMENT sN ( lN, lN.CSegment(-1) ); PNS_SEGMENT sN( lN, lN.CSegment( -1 ) );
PNS_DP_PRIMITIVE_PAIR dpair( &sP, &sN );
dpair.SetAnchors( sP.Seg().B, sN.Seg().B );
PNS_DP_PRIMITIVE_PAIR dpair ( &sP, &sN );
dpair.SetAnchors ( sP.Seg().B, sN.Seg().B );
return dpair; return dpair;
} }
} }
bool commonParallelProjection ( SEG n, SEG p, SEG &pClip, SEG& nClip )
bool commonParallelProjection( SEG n, SEG p, SEG &pClip, SEG& nClip )
{ {
SEG n_proj_p ( p.LineProject(n.A), p.LineProject(n.B) ); SEG n_proj_p( p.LineProject( n.A ), p.LineProject( n.B ) );
int64_t t_a = 0; int64_t t_a = 0;
int64_t t_b = p.TCoef(p.B); int64_t t_b = p.TCoef( p.B );
int64_t tproj_a = p.TCoef(n_proj_p.A); int64_t tproj_a = p.TCoef( n_proj_p.A );
int64_t tproj_b = p.TCoef(n_proj_p.B); int64_t tproj_b = p.TCoef( n_proj_p.B );
if(t_b < t_a) if( t_b < t_a )
std::swap ( t_b, t_a ); std::swap( t_b, t_a );
if(tproj_b < tproj_a) if( tproj_b < tproj_a )
std::swap ( tproj_b, tproj_a ); std::swap( tproj_b, tproj_a );
if( t_b <= tproj_a )
if(t_b <= tproj_a)
return false; return false;
if(t_a >= tproj_b) if( t_a >= tproj_b )
return false; return false;
int64_t t[4] = { 0, p.TCoef( p.B ), p.TCoef( n_proj_p.A ), p.TCoef( n_proj_p.B ) };
int64_t t[4] = { 0, p.TCoef ( p.B ), p.TCoef ( n_proj_p.A ), p.TCoef ( n_proj_p.B ) }; std::vector<int64_t> tv( t, t + 4 );
std::vector<int64_t> tv(t, t+4); std::sort( tv.begin(), tv.end() ); // fixme: awful and disgusting way of finding 2 midpoints
std::sort(tv.begin(), tv.end()); // fixme: awful and disgusting way of finding 2 midpoints
int64_t pLenSq = p.SquaredLength(); int64_t pLenSq = p.SquaredLength();
VECTOR2I dp = p.B - p.A; VECTOR2I dp = p.B - p.A;
pClip.A.x = p.A.x + rescale ( (int64_t)dp.x, tv[1], pLenSq ); pClip.A.x = p.A.x + rescale( (int64_t)dp.x, tv[1], pLenSq );
pClip.A.y = p.A.y + rescale ( (int64_t)dp.y, tv[1], pLenSq ); pClip.A.y = p.A.y + rescale( (int64_t)dp.y, tv[1], pLenSq );
pClip.B.x = p.A.x + rescale ( (int64_t)dp.x, tv[2], pLenSq ); pClip.B.x = p.A.x + rescale( (int64_t)dp.x, tv[2], pLenSq );
pClip.B.y = p.A.y + rescale ( (int64_t)dp.y, tv[2], pLenSq ); pClip.B.y = p.A.y + rescale( (int64_t)dp.y, tv[2], pLenSq );
nClip.A = n.LineProject(pClip.A); nClip.A = n.LineProject( pClip.A );
nClip.B = n.LineProject(pClip.B); nClip.B = n.LineProject( pClip.B );
return true; return true;
} }
double PNS_DIFF_PAIR::Skew () const
double PNS_DIFF_PAIR::Skew() const
{ {
return m_p.Length() - m_n.Length(); return m_p.Length() - m_n.Length();
} }
void PNS_DIFF_PAIR::CoupledSegmentPairs ( COUPLED_SEGMENTS_VEC& aPairs ) const
void PNS_DIFF_PAIR::CoupledSegmentPairs( COUPLED_SEGMENTS_VEC& aPairs ) const
{ {
SHAPE_LINE_CHAIN p ( m_p ); SHAPE_LINE_CHAIN p( m_p );
SHAPE_LINE_CHAIN n ( m_n ); SHAPE_LINE_CHAIN n( m_n );
p.Simplify(); p.Simplify();
n.Simplify(); n.Simplify();
for(int i = 0; i < p.SegmentCount(); i++ ) for( int i = 0; i < p.SegmentCount(); i++ )
{ {
for (int j = 0; j < n.SegmentCount(); j++ ) for( int j = 0; j < n.SegmentCount(); j++ )
{ {
SEG sp = p.CSegment(i); SEG sp = p.CSegment( i );
SEG sn = n.CSegment(j); SEG sn = n.CSegment( j );
SEG p_clip, n_clip; SEG p_clip, n_clip;
int64_t dist = std::abs ( sp.Distance(sn) - m_width ); int64_t dist = std::abs( sp.Distance( sn ) - m_width );
if( sp.ApproxParallel(sn) && m_gapConstraint.Matches ( dist ) && commonParallelProjection ( sp, sn, p_clip, n_clip )) if( sp.ApproxParallel( sn ) && m_gapConstraint.Matches( dist ) && commonParallelProjection( sp, sn, p_clip, n_clip ) )
{ {
const COUPLED_SEGMENTS spair ( p_clip, sp, i, n_clip, sn, j); const COUPLED_SEGMENTS spair( p_clip, sp, i, n_clip, sn, j );
aPairs.push_back( spair ); aPairs.push_back( spair );
} }
} }
} }
} }
int64_t PNS_DIFF_PAIR::CoupledLength ( const SHAPE_LINE_CHAIN& aP, const SHAPE_LINE_CHAIN& aN ) const
int64_t PNS_DIFF_PAIR::CoupledLength( const SHAPE_LINE_CHAIN& aP, const SHAPE_LINE_CHAIN& aN ) const
{ {
int64_t total = 0; int64_t total = 0;
for(int i = 0; i < aP.SegmentCount(); i++ ) for( int i = 0; i < aP.SegmentCount(); i++ )
{ {
for (int j = 0; j < aN.SegmentCount(); j++ ) for( int j = 0; j < aN.SegmentCount(); j++ )
{ {
SEG sp = aP.CSegment(i); SEG sp = aP.CSegment( i );
SEG sn = aN.CSegment(j); SEG sn = aN.CSegment( j );
SEG p_clip, n_clip; SEG p_clip, n_clip;
int64_t dist = std::abs ( sp.Distance(sn) - m_width ); int64_t dist = std::abs( sp.Distance(sn) - m_width );
if( sp.ApproxParallel(sn) && m_gapConstraint.Matches ( dist ) && commonParallelProjection ( sp, sn, p_clip, n_clip )) if( sp.ApproxParallel( sn ) && m_gapConstraint.Matches( dist ) &&
commonParallelProjection( sp, sn, p_clip, n_clip ) )
total += p_clip.Length(); total += p_clip.Length();
} }
} }
return total; return total;
} }
double PNS_DIFF_PAIR::CoupledLength() const double PNS_DIFF_PAIR::CoupledLength() const
{ {
COUPLED_SEGMENTS_VEC pairs; COUPLED_SEGMENTS_VEC pairs;
CoupledSegmentPairs(pairs); CoupledSegmentPairs( pairs );
double l = 0.0; double l = 0.0;
for(unsigned int i = 0; i < pairs.size();i++) for( unsigned int i = 0; i < pairs.size(); i++ )
l += pairs[i].coupledP.Length(); l += pairs[i].coupledP.Length();
return l; return l;
} }
double PNS_DIFF_PAIR::CoupledLengthFactor() const double PNS_DIFF_PAIR::CoupledLengthFactor() const
{ {
double t = TotalLength(); double t = TotalLength();
if( t == 0.0 ) if( t == 0.0 )
return 0.0; return 0.0;
return CoupledLength() / t; return CoupledLength() / t;
} }
double PNS_DIFF_PAIR::TotalLength() const double PNS_DIFF_PAIR::TotalLength() const
{ {
double lenP = m_p.Length(); double lenP = m_p.Length();
@ -812,14 +841,15 @@ double PNS_DIFF_PAIR::TotalLength() const
return (lenN + lenP ) / 2.0; return (lenN + lenP ) / 2.0;
} }
int PNS_DIFF_PAIR::CoupledLength ( const SEG& aP, const SEG& aN ) const int PNS_DIFF_PAIR::CoupledLength ( const SEG& aP, const SEG& aN ) const
{ {
SEG p_clip, n_clip; SEG p_clip, n_clip;
int64_t dist = std::abs ( aP.Distance(aN) - m_width ); int64_t dist = std::abs( aP.Distance( aN ) - m_width );
if( aP.ApproxParallel(aN) && m_gapConstraint.Matches ( dist ) && commonParallelProjection ( aP, aN, p_clip, n_clip )) if( aP.ApproxParallel( aN ) && m_gapConstraint.Matches( dist ) &&
commonParallelProjection ( aP, aN, p_clip, n_clip ) )
return p_clip.Length(); return p_clip.Length();
return 0; return 0;
} }

View File

@ -43,23 +43,22 @@ class PNS_DIFF_PAIR;
**/ **/
class PNS_DP_GATEWAY { class PNS_DP_GATEWAY {
public: public:
PNS_DP_GATEWAY ( const VECTOR2I& aAnchorP, PNS_DP_GATEWAY( const VECTOR2I& aAnchorP,
const VECTOR2I& aAnchorN, const VECTOR2I& aAnchorN,
bool aIsDiagonal, bool aIsDiagonal,
int aAllowedEntryAngles = DIRECTION_45::ANG_OBTUSE, int aAllowedEntryAngles = DIRECTION_45::ANG_OBTUSE,
int aPriority = 0 ) int aPriority = 0 )
: m_anchorP(aAnchorP), : m_anchorP( aAnchorP ),
m_anchorN (aAnchorN), m_anchorN( aAnchorN ),
m_isDiagonal( aIsDiagonal ), m_isDiagonal( aIsDiagonal ),
m_allowedEntryAngles (aAllowedEntryAngles), m_allowedEntryAngles( aAllowedEntryAngles ),
m_priority(aPriority) m_priority( aPriority )
{ {
m_hasEntryLines = false; m_hasEntryLines = false;
} }
~PNS_DP_GATEWAY () ~PNS_DP_GATEWAY()
{ {
} }
/** /**
@ -67,14 +66,14 @@ public:
* *
* @return true, if the gateway anchors lie on a diagonal line * @return true, if the gateway anchors lie on a diagonal line
*/ */
bool IsDiagonal() const bool IsDiagonal() const
{ {
return m_isDiagonal; return m_isDiagonal;
} }
const VECTOR2I& AnchorP () const { return m_anchorP; } const VECTOR2I& AnchorP() const { return m_anchorP; }
const VECTOR2I& AnchorN () const { return m_anchorN; }
const VECTOR2I& AnchorN() const { return m_anchorN; }
/** /**
* Function AllowedAngles() * Function AllowedAngles()
@ -99,15 +98,15 @@ public:
m_priority = aPriority; m_priority = aPriority;
} }
void SetEntryLines ( const SHAPE_LINE_CHAIN& aEntryP, const SHAPE_LINE_CHAIN& aEntryN ) void SetEntryLines( const SHAPE_LINE_CHAIN& aEntryP, const SHAPE_LINE_CHAIN& aEntryN )
{ {
m_entryP = aEntryP; m_entryP = aEntryP;
m_entryN = aEntryN; m_entryN = aEntryN;
m_hasEntryLines = true; m_hasEntryLines = true;
} }
const SHAPE_LINE_CHAIN& EntryP () const { return m_entryP; } const SHAPE_LINE_CHAIN& EntryP() const { return m_entryP; }
const SHAPE_LINE_CHAIN& EntryN () const { return m_entryN; } const SHAPE_LINE_CHAIN& EntryN() const { return m_entryN; }
const PNS_DIFF_PAIR Entry() const ; const PNS_DIFF_PAIR Entry() const ;
void Reverse(); void Reverse();
@ -118,7 +117,6 @@ public:
} }
private: private:
SHAPE_LINE_CHAIN m_entryP, m_entryN; SHAPE_LINE_CHAIN m_entryP, m_entryN;
bool m_hasEntryLines; bool m_hasEntryLines;
VECTOR2I m_anchorP, m_anchorN; VECTOR2I m_anchorP, m_anchorN;
@ -134,37 +132,36 @@ private:
**/ **/
class PNS_DP_PRIMITIVE_PAIR class PNS_DP_PRIMITIVE_PAIR
{ {
public: public:
PNS_DP_PRIMITIVE_PAIR(): PNS_DP_PRIMITIVE_PAIR():
m_primP (NULL), m_primN ( NULL ) {}; m_primP( NULL ), m_primN( NULL ) {};
PNS_DP_PRIMITIVE_PAIR ( const PNS_DP_PRIMITIVE_PAIR& aOther ); PNS_DP_PRIMITIVE_PAIR( const PNS_DP_PRIMITIVE_PAIR& aOther );
PNS_DP_PRIMITIVE_PAIR ( PNS_ITEM *aPrimP, PNS_ITEM *aPrimN ); PNS_DP_PRIMITIVE_PAIR( PNS_ITEM* aPrimP, PNS_ITEM* aPrimN );
PNS_DP_PRIMITIVE_PAIR ( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN ); PNS_DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
~PNS_DP_PRIMITIVE_PAIR(); ~PNS_DP_PRIMITIVE_PAIR();
void SetAnchors ( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN ); void SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
const VECTOR2I& AnchorP () const { return m_anchorP; } const VECTOR2I& AnchorP() const { return m_anchorP; }
const VECTOR2I& AnchorN () const { return m_anchorN; } const VECTOR2I& AnchorN() const { return m_anchorN; }
PNS_DP_PRIMITIVE_PAIR& operator= ( const PNS_DP_PRIMITIVE_PAIR& aOther ); PNS_DP_PRIMITIVE_PAIR& operator=( const PNS_DP_PRIMITIVE_PAIR& aOther );
PNS_ITEM* PrimP () const { return m_primP; } PNS_ITEM* PrimP() const { return m_primP; }
PNS_ITEM* PrimN () const { return m_primN; } PNS_ITEM* PrimN() const { return m_primN; }
bool Directional() const; bool Directional() const;
DIRECTION_45 DirP () const; DIRECTION_45 DirP() const;
DIRECTION_45 DirN () const; DIRECTION_45 DirN() const;
private: private:
DIRECTION_45 anchorDirection( PNS_ITEM* aItem, const VECTOR2I& aP ) const;
DIRECTION_45 anchorDirection ( PNS_ITEM *aItem, const VECTOR2I& aP) const; PNS_ITEM* m_primP;
PNS_ITEM* m_primN;
PNS_ITEM *m_primP, *m_primN;
VECTOR2I m_anchorP, m_anchorN; VECTOR2I m_anchorP, m_anchorN;
}; };

View File

@ -57,70 +57,78 @@ PNS_DIFF_PAIR_PLACER::~PNS_DIFF_PAIR_PLACER()
} }
void PNS_DIFF_PAIR_PLACER::setWorld ( PNS_NODE* aWorld ) void PNS_DIFF_PAIR_PLACER::setWorld( PNS_NODE* aWorld )
{ {
m_world = aWorld; m_world = aWorld;
} }
const PNS_VIA PNS_DIFF_PAIR_PLACER::makeVia ( const VECTOR2I& aP, int aNet )
const PNS_VIA PNS_DIFF_PAIR_PLACER::makeVia( const VECTOR2I& aP, int aNet )
{ {
const PNS_LAYERSET layers( m_sizes.GetLayerTop(), m_sizes.GetLayerBottom() ); const PNS_LAYERSET layers( m_sizes.GetLayerTop(), m_sizes.GetLayerBottom() );
PNS_VIA v( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), -1, m_sizes.ViaType() ); PNS_VIA v( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), -1, m_sizes.ViaType() );
v.SetNet (aNet); v.SetNet( aNet );
return v; return v;
} }
void PNS_DIFF_PAIR_PLACER::SetOrthoMode ( bool aOrthoMode ) void PNS_DIFF_PAIR_PLACER::SetOrthoMode ( bool aOrthoMode )
{ {
m_orthoMode = aOrthoMode; m_orthoMode = aOrthoMode;
if(!m_idle)
Move ( m_currentEnd, NULL ); if( !m_idle )
Move( m_currentEnd, NULL );
} }
bool PNS_DIFF_PAIR_PLACER::ToggleVia( bool aEnabled ) bool PNS_DIFF_PAIR_PLACER::ToggleVia( bool aEnabled )
{ {
m_placingVia = aEnabled; m_placingVia = aEnabled;
if(!m_idle)
Move ( m_currentEnd, NULL ); if( !m_idle )
Move( m_currentEnd, NULL );
return true; return true;
} }
bool PNS_DIFF_PAIR_PLACER::rhMarkObstacles( const VECTOR2I& aP ) bool PNS_DIFF_PAIR_PLACER::rhMarkObstacles( const VECTOR2I& aP )
{ {
if( !routeHead ( aP ) ) if( !routeHead( aP ) )
return false; return false;
bool collP = m_currentNode->CheckColliding( &m_currentTrace.PLine() ); bool collP = m_currentNode->CheckColliding( &m_currentTrace.PLine() );
bool collN = m_currentNode->CheckColliding( &m_currentTrace.NLine() ); bool collN = m_currentNode->CheckColliding( &m_currentTrace.NLine() );
m_fitOk = !(collP || collN); m_fitOk = !( collP || collN ) ;
return m_fitOk; return m_fitOk;
} }
bool PNS_DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP ) bool PNS_DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP )
{ {
PNS_VIA virtHead = makeVia ( aP, -1 ); PNS_VIA virtHead = makeVia( aP, -1 );
if ( m_placingVia ) if( m_placingVia )
virtHead.SetDiameter ( viaGap() + 2 * virtHead.Diameter() ); virtHead.SetDiameter( viaGap() + 2 * virtHead.Diameter() );
else else
{ {
virtHead.SetLayer ( m_currentLayer ); virtHead.SetLayer( m_currentLayer );
virtHead.SetDiameter ( m_sizes.DiffPairGap() + 2 * m_sizes.TrackWidth() ); virtHead.SetDiameter( m_sizes.DiffPairGap() + 2 * m_sizes.TrackWidth() );
} }
VECTOR2I lead(0, 0);// = aP - m_currentStart ; VECTOR2I lead( 0, 0 );// = aP - m_currentStart ;
VECTOR2I force; VECTOR2I force;
bool solidsOnly = true; bool solidsOnly = true;
if( m_currentMode == RM_MarkObstacles )
if(m_currentMode == RM_MarkObstacles )
{ {
aNewP = aP; aNewP = aP;
return true; return true;
} else if (m_currentMode == RM_Walkaround ) }
else if( m_currentMode == RM_Walkaround )
{ {
solidsOnly = false; solidsOnly = false;
} }
@ -136,24 +144,24 @@ bool PNS_DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I&
} }
bool PNS_DIFF_PAIR_PLACER::attemptWalk ( PNS_NODE *aNode, PNS_DIFF_PAIR *aCurrent, PNS_DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly ) bool PNS_DIFF_PAIR_PLACER::attemptWalk ( PNS_NODE* aNode, PNS_DIFF_PAIR* aCurrent, PNS_DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly )
{ {
PNS_WALKAROUND walkaround( aNode, Router() ); PNS_WALKAROUND walkaround( aNode, Router() );
PNS_WALKAROUND::WALKAROUND_STATUS wf1; PNS_WALKAROUND::WALKAROUND_STATUS wf1;
Router()->GetClearanceFunc()->OverrideClearance ( true, aCurrent->NetP(), aCurrent->NetN(), aCurrent->Gap() - 20 ); Router()->GetClearanceFunc()->OverrideClearance( true, aCurrent->NetP(), aCurrent->NetN(), aCurrent->Gap() - 20 );
walkaround.SetSolidsOnly( aSolidsOnly ); walkaround.SetSolidsOnly( aSolidsOnly );
walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() ); walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
PNS_SHOVE shove(aNode, Router()); PNS_SHOVE shove( aNode, Router() );
PNS_LINE walkP, walkN; PNS_LINE walkP, walkN;
aWalk = *aCurrent; aWalk = *aCurrent;
int iter = 0; int iter = 0;
PNS_DIFF_PAIR cur (*aCurrent); PNS_DIFF_PAIR cur( *aCurrent );
bool currentIsP = aPFirst; bool currentIsP = aPFirst;
@ -162,17 +170,17 @@ bool PNS_DIFF_PAIR_PLACER::attemptWalk ( PNS_NODE *aNode, PNS_DIFF_PAIR *aCurren
//Router()->DisplayDebugLine( aCurrent->CP(), 4, 10000 ); //Router()->DisplayDebugLine( aCurrent->CP(), 4, 10000 );
//Router()->DisplayDebugLine( aCurrent->CN(), 5, 10000 ); //Router()->DisplayDebugLine( aCurrent->CN(), 5, 10000 );
do { do
PNS_LINE preWalk = (currentIsP ? cur.PLine() : cur.NLine() ); {
PNS_LINE preShove = (currentIsP ? cur.NLine() : cur.PLine() ); PNS_LINE preWalk = ( currentIsP ? cur.PLine() : cur.NLine() );
PNS_LINE preShove = ( currentIsP ? cur.NLine() : cur.PLine() );
PNS_LINE postWalk; PNS_LINE postWalk;
if (!aNode->CheckColliding ( &preWalk, mask ) ) if( !aNode->CheckColliding ( &preWalk, mask ) )
{ {
currentIsP = !currentIsP; currentIsP = !currentIsP;
if (!aNode->CheckColliding ( &preShove, mask ) ) if( !aNode->CheckColliding( &preShove, mask ) )
break; break;
else else
continue; continue;
@ -180,52 +188,50 @@ bool PNS_DIFF_PAIR_PLACER::attemptWalk ( PNS_NODE *aNode, PNS_DIFF_PAIR *aCurren
wf1 = walkaround.Route( preWalk, postWalk, false ); wf1 = walkaround.Route( preWalk, postWalk, false );
if(wf1 != PNS_WALKAROUND::DONE) if( wf1 != PNS_WALKAROUND::DONE )
return false; return false;
PNS_LINE postShove ( preShove ); PNS_LINE postShove( preShove );
shove.ForceClearance(true, cur.Gap() - 12); shove.ForceClearance( true, cur.Gap() - 12 );
PNS_SHOVE::SHOVE_STATUS sh1; PNS_SHOVE::SHOVE_STATUS sh1;
sh1 = shove.ProcessSingleLine( &postWalk, &preShove, &postShove ); sh1 = shove.ProcessSingleLine( &postWalk, &preShove, &postShove );
if(sh1 != PNS_SHOVE::SH_OK) if( sh1 != PNS_SHOVE::SH_OK )
return false; return false;
postWalk.Line().Simplify(); postWalk.Line().Simplify();
postShove.Line().Simplify(); postShove.Line().Simplify();
cur.SetShape( postWalk.CLine(), postShove.CLine(), !currentIsP );
cur.SetShape ( postWalk.CLine(), postShove.CLine(), !currentIsP );
currentIsP = !currentIsP; currentIsP = !currentIsP;
if (!aNode->CheckColliding ( &postShove, mask ) ) if( !aNode->CheckColliding( &postShove, mask ) )
break; break;
iter++; iter++;
} while (iter < 3); }
while( iter < 3 );
if(iter == 3) if( iter == 3 )
return false; return false;
aWalk.SetShape( cur.CP(), cur.CN() );
Router()->GetClearanceFunc()->OverrideClearance( false );
aWalk.SetShape(cur.CP(), cur.CN() );
Router()->GetClearanceFunc()->OverrideClearance ( false );
return true; return true;
} }
bool PNS_DIFF_PAIR_PLACER::tryWalkDp ( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bool aSolidsOnly )
bool PNS_DIFF_PAIR_PLACER::tryWalkDp( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bool aSolidsOnly )
{ {
PNS_DIFF_PAIR best; PNS_DIFF_PAIR best;
double bestScore = 100000000000000.0; double bestScore = 100000000000000.0;
for(int attempt = 0; attempt <= 1; attempt ++) for( int attempt = 0; attempt <= 1; attempt++ )
{ {
PNS_DIFF_PAIR p; PNS_DIFF_PAIR p;
PNS_NODE *tmp = m_currentNode->Branch(); PNS_NODE *tmp = m_currentNode->Branch();
@ -233,7 +239,7 @@ bool PNS_DIFF_PAIR_PLACER::tryWalkDp ( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bo
bool pfirst = attempt % 2 ? true : false; bool pfirst = attempt % 2 ? true : false;
bool wind_cw = attempt / 2 ? true : false; bool wind_cw = attempt / 2 ? true : false;
if ( attemptWalk ( tmp, &aPair, p, pfirst, wind_cw, aSolidsOnly ) ) if( attemptWalk ( tmp, &aPair, p, pfirst, wind_cw, aSolidsOnly ) )
{ {
// double len = p.TotalLength(); // double len = p.TotalLength();
double cl = p.CoupledLength(); double cl = p.CoupledLength();
@ -241,7 +247,7 @@ bool PNS_DIFF_PAIR_PLACER::tryWalkDp ( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bo
double score = cl + fabs(skew) * 3.0; double score = cl + fabs(skew) * 3.0;
if(score < bestScore) if( score < bestScore )
{ {
bestScore = score; bestScore = score;
best = p; best = p;
@ -251,31 +257,32 @@ bool PNS_DIFF_PAIR_PLACER::tryWalkDp ( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bo
delete tmp; delete tmp;
} }
if(bestScore > 0.0) if( bestScore > 0.0 )
{ {
PNS_OPTIMIZER optimizer( m_currentNode ); PNS_OPTIMIZER optimizer( m_currentNode );
aPair.SetShape ( best ); aPair.SetShape( best );
optimizer.Optimize( &aPair );
optimizer.Optimize ( &aPair );
return true; return true;
} }
return false; return false;
} }
bool PNS_DIFF_PAIR_PLACER::rhWalkOnly( const VECTOR2I& aP ) bool PNS_DIFF_PAIR_PLACER::rhWalkOnly( const VECTOR2I& aP )
{ {
if ( !routeHead ( aP ) ) if( !routeHead ( aP ) )
return false; return false;
m_fitOk = tryWalkDp ( m_currentNode, m_currentTrace, false ); m_fitOk = tryWalkDp( m_currentNode, m_currentTrace, false );
return m_fitOk; return m_fitOk;
} }
bool PNS_DIFF_PAIR_PLACER::route ( const VECTOR2I& aP ) bool PNS_DIFF_PAIR_PLACER::route( const VECTOR2I& aP )
{ {
switch( m_currentMode ) switch( m_currentMode )
{ {
@ -292,7 +299,8 @@ bool PNS_DIFF_PAIR_PLACER::route ( const VECTOR2I& aP )
return false; return false;
} }
bool PNS_DIFF_PAIR_PLACER::rhShoveOnly ( const VECTOR2I& aP )
bool PNS_DIFF_PAIR_PLACER::rhShoveOnly( const VECTOR2I& aP )
{ {
m_currentNode = m_shove->CurrentNode(); m_currentNode = m_shove->CurrentNode();
@ -300,18 +308,18 @@ bool PNS_DIFF_PAIR_PLACER::rhShoveOnly ( const VECTOR2I& aP )
m_fitOk = false; m_fitOk = false;
if(!ok) if( !ok )
return false; return false;
if (!tryWalkDp ( m_currentNode, m_currentTrace, true ) ) if( !tryWalkDp( m_currentNode, m_currentTrace, true ) )
return false; return false;
PNS_LINE pLine ( m_currentTrace.PLine() ); PNS_LINE pLine( m_currentTrace.PLine() );
PNS_LINE nLine ( m_currentTrace.NLine() ); PNS_LINE nLine( m_currentTrace.NLine() );
PNS_ITEMSET head; PNS_ITEMSET head;
head.Add ( &pLine ); head.Add( &pLine );
head.Add ( &nLine ); head.Add( &nLine );
PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveMultiLines( head ); PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveMultiLines( head );
@ -321,8 +329,8 @@ bool PNS_DIFF_PAIR_PLACER::rhShoveOnly ( const VECTOR2I& aP )
{ {
m_currentNode = m_shove->CurrentNode(); m_currentNode = m_shove->CurrentNode();
if( !m_currentNode->CheckColliding ( &m_currentTrace.PLine() ) && if( !m_currentNode->CheckColliding( &m_currentTrace.PLine() ) &&
!m_currentNode->CheckColliding ( &m_currentTrace.NLine() ) ) !m_currentNode->CheckColliding( &m_currentTrace.NLine() ) )
{ {
m_fitOk = true; m_fitOk = true;
} }
@ -332,13 +340,12 @@ bool PNS_DIFF_PAIR_PLACER::rhShoveOnly ( const VECTOR2I& aP )
} }
const PNS_ITEMSET PNS_DIFF_PAIR_PLACER::Traces() const PNS_ITEMSET PNS_DIFF_PAIR_PLACER::Traces()
{ {
PNS_ITEMSET t; PNS_ITEMSET t;
t.Add( const_cast<PNS_LINE *> ( &m_currentTrace.PLine( ) ) ); t.Add( const_cast<PNS_LINE*>( &m_currentTrace.PLine() ) );
t.Add( const_cast<PNS_LINE *> ( &m_currentTrace.NLine( ) ) ); t.Add( const_cast<PNS_LINE*>( &m_currentTrace.NLine() ) );
return t; return t;
} }
@ -348,8 +355,8 @@ void PNS_DIFF_PAIR_PLACER::FlipPosture()
{ {
m_startDiagonal = !m_startDiagonal; m_startDiagonal = !m_startDiagonal;
if(!m_idle) if( !m_idle )
Move ( m_currentEnd, NULL ); Move( m_currentEnd, NULL );
} }
@ -372,84 +379,93 @@ bool PNS_DIFF_PAIR_PLACER::SetLayer( int aLayer )
return false; return false;
else if( !m_prevPair ) else if( !m_prevPair )
return false; return false;
else if( m_prevPair->PrimP() || ( m_prevPair->PrimP()->OfKind( PNS_ITEM::VIA ) && m_prevPair->PrimP()->Layers().Overlaps( aLayer ) ) ) { else if( m_prevPair->PrimP() || ( m_prevPair->PrimP()->OfKind( PNS_ITEM::VIA ) &&
m_prevPair->PrimP()->Layers().Overlaps( aLayer ) ) )
{
m_currentLayer = aLayer; m_currentLayer = aLayer;
m_start = *m_prevPair; m_start = *m_prevPair;
initPlacement ( false ); initPlacement( false );
Move ( m_currentEnd, NULL ); Move( m_currentEnd, NULL );
return true; return true;
} }
return false; return false;
} }
int PNS_DIFF_PAIR_PLACER::matchDpSuffix ( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
int PNS_DIFF_PAIR_PLACER::matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
{ {
int rv = 0; int rv = 0;
if (aNetName.EndsWith("+"))
if( aNetName.EndsWith( "+" ) )
{ {
aComplementNet = "-"; aComplementNet = "-";
rv = 1; rv = 1;
} else if (aNetName.EndsWith("_P")) }
else if( aNetName.EndsWith( "_P" ) )
{ {
aComplementNet = "_N"; aComplementNet = "_N";
rv = 1; rv = 1;
} else if (aNetName.EndsWith("-")) }
else if( aNetName.EndsWith( "-" ) )
{ {
aComplementNet = "+"; aComplementNet = "+";
rv = -1; rv = -1;
} else if (aNetName.EndsWith("_N")) }
else if( aNetName.EndsWith( "_N" ) )
{ {
aComplementNet = "_P"; aComplementNet = "_P";
rv = -1; rv = -1;
} }
if (rv != 0) { if( rv != 0 )
aBaseDpName = aNetName.Left ( aNetName.Length() - aComplementNet.Length() ); {
aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
} }
return rv; return rv;
} }
OPT_VECTOR2I PNS_DIFF_PAIR_PLACER::getDanglingAnchor ( PNS_NODE *aNode, PNS_ITEM *aItem )
OPT_VECTOR2I PNS_DIFF_PAIR_PLACER::getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem )
{ {
switch(aItem->Kind()) switch( aItem->Kind() )
{ {
case PNS_ITEM::VIA: case PNS_ITEM::VIA:
case PNS_ITEM::SOLID: case PNS_ITEM::SOLID:
return aItem->Anchor(0); return aItem->Anchor( 0 );
case PNS_ITEM::SEGMENT: case PNS_ITEM::SEGMENT:
{ {
PNS_SEGMENT *s =static_cast<PNS_SEGMENT*> ( aItem ); PNS_SEGMENT* s =static_cast<PNS_SEGMENT*>( aItem );
PNS_JOINT *jA = aNode->FindJoint( s->Seg().A, s ); PNS_JOINT* jA = aNode->FindJoint( s->Seg().A, s );
PNS_JOINT *jB = aNode->FindJoint( s->Seg().B, s ); PNS_JOINT* jB = aNode->FindJoint( s->Seg().B, s );
if(jA->LinkCount() == 1) if( jA->LinkCount() == 1 )
return s->Seg().A; return s->Seg().A;
else if (jB->LinkCount() == 1) else if( jB->LinkCount() == 1 )
return s->Seg().B; return s->Seg().B;
else else
return OPT_VECTOR2I(); return OPT_VECTOR2I();
} }
default: default:
return OPT_VECTOR2I(); return OPT_VECTOR2I();
break; break;
} }
} }
bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair ( const VECTOR2I& aP, PNS_ITEM *aItem, PNS_DP_PRIMITIVE_PAIR& aPair )
{
if(!aItem || !aItem->Parent() || !aItem->Parent()->GetNet() ) bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair )
{
if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() )
return false; return false;
wxString netNameP = aItem->Parent()->GetNet()->GetNetname(); wxString netNameP = aItem->Parent()->GetNet()->GetNetname();
wxString netNameN, netNameBase; wxString netNameN, netNameBase;
BOARD* brd = Router()->GetBoard();
BOARD *brd = Router()->GetBoard();
PNS_ITEM *primRef = NULL, *primP = NULL, *primN = NULL; PNS_ITEM *primRef = NULL, *primP = NULL, *primN = NULL;
// printf("Current %p\n", m_currentNode); // printf("Current %p\n", m_currentNode);
@ -459,22 +475,24 @@ bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair ( const VECTOR2I& aP, PNS_ITEM *a
int r = matchDpSuffix ( netNameP, suffix, netNameBase ); int r = matchDpSuffix ( netNameP, suffix, netNameBase );
if(r == 0) if( r == 0 )
return false; return false;
else if(r == 1) else if( r == 1 )
{ {
primRef = primP = static_cast <PNS_SOLID *> (aItem); primRef = primP = static_cast<PNS_SOLID*>( aItem );
netNameN = netNameBase + suffix; netNameN = netNameBase + suffix;
} else { }
primRef = primN = static_cast <PNS_SOLID *> (aItem); else
{
primRef = primN = static_cast<PNS_SOLID*>( aItem );
netNameN = netNameP; netNameN = netNameP;
netNameP = netNameBase + suffix; netNameP = netNameBase + suffix;
} }
int netP = brd->FindNet ( netNameP )->GetNet(); int netP = brd->FindNet( netNameP )->GetNet();
int netN = brd->FindNet ( netNameN )->GetNet(); int netN = brd->FindNet( netNameN )->GetNet();
if ( primP ) if( primP )
refNet = netN; refNet = netN;
else else
refNet = netP; refNet = netP;
@ -483,37 +501,39 @@ bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair ( const VECTOR2I& aP, PNS_ITEM *a
std::set<PNS_ITEM*> items; std::set<PNS_ITEM*> items;
OPT_VECTOR2I refAnchor = getDanglingAnchor ( m_currentNode, primRef ); OPT_VECTOR2I refAnchor = getDanglingAnchor( m_currentNode, primRef );
if(!refAnchor) if( !refAnchor )
return false; return false;
m_currentNode->AllItemsInNet( refNet, items ); m_currentNode->AllItemsInNet( refNet, items );
double bestDist = std::numeric_limits<double>::max(); double bestDist = std::numeric_limits<double>::max();
bool found = false; bool found = false;
BOOST_FOREACH (PNS_ITEM *item, items) BOOST_FOREACH(PNS_ITEM* item, items )
{ {
if ( item->Kind() == aItem->Kind() ) if( item->Kind() == aItem->Kind() )
{ {
OPT_VECTOR2I anchor = getDanglingAnchor ( m_currentNode, item ); OPT_VECTOR2I anchor = getDanglingAnchor( m_currentNode, item );
if(!anchor) if( !anchor )
continue; continue;
double dist = (*anchor - *refAnchor).EuclideanNorm(); double dist = ( *anchor - *refAnchor ).EuclideanNorm();
if (dist < bestDist) if( dist < bestDist )
{ {
found = true; found = true;
bestDist = dist; bestDist = dist;
if (refNet == netP) if( refNet == netP )
{ {
aPair = PNS_DP_PRIMITIVE_PAIR ( item, primRef ); aPair = PNS_DP_PRIMITIVE_PAIR ( item, primRef );
aPair.SetAnchors ( *anchor, *refAnchor ); aPair.SetAnchors( *anchor, *refAnchor );
} else { }
aPair = PNS_DP_PRIMITIVE_PAIR ( primRef, item ); else
aPair.SetAnchors ( *refAnchor, *anchor ); {
aPair = PNS_DP_PRIMITIVE_PAIR( primRef, item );
aPair.SetAnchors( *refAnchor, *anchor );
} }
} }
} }
@ -528,11 +548,13 @@ int PNS_DIFF_PAIR_PLACER::viaGap() const
return m_sizes.DiffPairViaGap(); return m_sizes.DiffPairViaGap();
} }
int PNS_DIFF_PAIR_PLACER::gap() const int PNS_DIFF_PAIR_PLACER::gap() const
{ {
return m_sizes.DiffPairGap() + m_sizes.DiffPairWidth(); return m_sizes.DiffPairGap() + m_sizes.DiffPairWidth();
} }
bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
VECTOR2I p( aP ); VECTOR2I p( aP );
@ -542,7 +564,7 @@ bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
if( Router()->SnappingEnabled() ) if( Router()->SnappingEnabled() )
p = Router()->SnapToItem( aStartItem, aP, split ); p = Router()->SnapToItem( aStartItem, aP, split );
if(!aStartItem) if( !aStartItem )
{ {
Router()->SetFailureReason( _( "Can't start a differential pair " Router()->SetFailureReason( _( "Can't start a differential pair "
" in the middle of nowhere." ) ); " in the middle of nowhere." ) );
@ -553,7 +575,7 @@ bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
m_currentNode = Router()->GetWorld(); m_currentNode = Router()->GetWorld();
if (!findDpPrimitivePair(aP, aStartItem, m_start ) ) if( !findDpPrimitivePair( aP, aStartItem, m_start ) )
{ {
Router()->SetFailureReason( _( "Unable to find complementary differential pair " Router()->SetFailureReason( _( "Unable to find complementary differential pair "
"net. Make sure the names of the nets belonging " "net. Make sure the names of the nets belonging "
@ -573,6 +595,7 @@ bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
return true; return true;
} }
void PNS_DIFF_PAIR_PLACER::initPlacement( bool aSplitSeg ) void PNS_DIFF_PAIR_PLACER::initPlacement( bool aSplitSeg )
{ {
m_idle = false; m_idle = false;
@ -609,57 +632,56 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
{ {
m_fitOk = false; m_fitOk = false;
PNS_DP_GATEWAYS gwsEntry ( gap() ); PNS_DP_GATEWAYS gwsEntry( gap() );
PNS_DP_GATEWAYS gwsTarget ( gap() ); PNS_DP_GATEWAYS gwsTarget( gap() );
if( !m_prevPair )
if(!m_prevPair)
m_prevPair = m_start; m_prevPair = m_start;
gwsEntry.BuildFromPrimitivePair ( *m_prevPair, m_startDiagonal ); gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );
PNS_DP_PRIMITIVE_PAIR target; PNS_DP_PRIMITIVE_PAIR target;
if (findDpPrimitivePair ( aP, m_currentEndItem, target )) if( findDpPrimitivePair ( aP, m_currentEndItem, target ) )
{ {
gwsTarget.BuildFromPrimitivePair( target, m_startDiagonal ); gwsTarget.BuildFromPrimitivePair( target, m_startDiagonal );
m_snapOnTarget = true; m_snapOnTarget = true;
} else { } else {
VECTOR2I fp; VECTOR2I fp;
if( !propagateDpHeadForces ( aP, fp ) ) if( !propagateDpHeadForces( aP, fp ) )
return false; return false;
gwsTarget.SetFitVias ( m_placingVia, m_sizes.ViaDiameter(), viaGap() ); gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() );
gwsTarget.BuildForCursor ( fp ); gwsTarget.BuildForCursor( fp );
gwsTarget.BuildOrthoProjections ( gwsEntry, fp, m_orthoMode ? 200 : -200 ); gwsTarget.BuildOrthoProjections( gwsEntry, fp, m_orthoMode ? 200 : -200 );
m_snapOnTarget = false; m_snapOnTarget = false;
} }
m_currentTrace = PNS_DIFF_PAIR(); m_currentTrace = PNS_DIFF_PAIR();
m_currentTrace.SetGap ( gap() ); m_currentTrace.SetGap( gap() );
m_currentTrace.SetLayer( m_currentLayer ); m_currentTrace.SetLayer( m_currentLayer );
if ( gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace ) )
if ( gwsEntry.FitGateways(gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace ) )
{ {
m_currentTrace.SetNets ( m_netP, m_netN ); m_currentTrace.SetNets( m_netP, m_netN );
m_currentTrace.SetWidth ( m_sizes.DiffPairWidth() ); m_currentTrace.SetWidth( m_sizes.DiffPairWidth() );
m_currentTrace.SetGap ( m_sizes.DiffPairGap() ); m_currentTrace.SetGap( m_sizes.DiffPairGap() );
if(m_placingVia) if( m_placingVia )
{ {
m_currentTrace.AppendVias ( makeVia ( m_currentTrace.CP().CPoint(-1), m_netP ), m_currentTrace.AppendVias ( makeVia ( m_currentTrace.CP().CPoint(-1), m_netP ),
makeVia ( m_currentTrace.CN().CPoint(-1), m_netN ) ); makeVia ( m_currentTrace.CN().CPoint(-1), m_netN ) );
} }
return true; return true;
} }
return false; return false;
} }
bool PNS_DIFF_PAIR_PLACER::Move(const VECTOR2I& aP , PNS_ITEM* aEndItem )
bool PNS_DIFF_PAIR_PLACER::Move( const VECTOR2I& aP , PNS_ITEM* aEndItem )
{ {
m_currentEndItem = aEndItem; m_currentEndItem = aEndItem;
m_fitOk = false; m_fitOk = false;
@ -667,13 +689,13 @@ bool PNS_DIFF_PAIR_PLACER::Move(const VECTOR2I& aP , PNS_ITEM* aEndItem )
delete m_lastNode; delete m_lastNode;
m_lastNode = NULL; m_lastNode = NULL;
if ( !route( aP ) ) if( !route( aP ) )
return false; return false;
PNS_NODE* latestNode = m_currentNode; PNS_NODE* latestNode = m_currentNode;
m_lastNode = latestNode->Branch(); m_lastNode = latestNode->Branch();
assert (m_lastNode != NULL); assert( m_lastNode != NULL );
m_currentEnd = aP; m_currentEnd = aP;
updateLeadingRatLine(); updateLeadingRatLine();
@ -681,42 +703,45 @@ bool PNS_DIFF_PAIR_PLACER::Move(const VECTOR2I& aP , PNS_ITEM* aEndItem )
return true; return true;
} }
void PNS_DIFF_PAIR_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes ) void PNS_DIFF_PAIR_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
{ {
m_sizes = aSizes; m_sizes = aSizes;
if( !m_idle ) if( !m_idle )
{ {
initPlacement ( ); initPlacement();
Move ( m_currentEnd, NULL ); Move( m_currentEnd, NULL );
} }
} }
bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
if (!m_fitOk) if( !m_fitOk )
return false; return false;
if (m_currentTrace.CP().SegmentCount() < 1 || if( m_currentTrace.CP().SegmentCount() < 1 ||
m_currentTrace.CN().SegmentCount() < 1 ) m_currentTrace.CN().SegmentCount() < 1 )
return false; return false;
if( m_currentTrace.CP().SegmentCount() > 1) if( m_currentTrace.CP().SegmentCount() > 1 )
m_initialDiagonal = !DIRECTION_45( m_currentTrace.CP().CSegment(-2) ).IsDiagonal(); m_initialDiagonal = !DIRECTION_45( m_currentTrace.CP().CSegment( -2 ) ).IsDiagonal();
PNS_TOPOLOGY topo ( m_lastNode ); PNS_TOPOLOGY topo( m_lastNode );
if( !m_snapOnTarget && !m_currentTrace.EndsWithVias() ) if( !m_snapOnTarget && !m_currentTrace.EndsWithVias() )
{ {
SHAPE_LINE_CHAIN newP ( m_currentTrace.CP() ); SHAPE_LINE_CHAIN newP ( m_currentTrace.CP() );
SHAPE_LINE_CHAIN newN ( m_currentTrace.CN() ); SHAPE_LINE_CHAIN newN ( m_currentTrace.CN() );
if( newP.SegmentCount() > 1 && newN.SegmentCount() > 1) if( newP.SegmentCount() > 1 && newN.SegmentCount() > 1 )
{ {
newP.Remove(-1, -1); newP.Remove( -1, -1 );
newN.Remove(-1, -1); newN.Remove( -1, -1 );
} }
m_currentTrace.SetShape ( newP, newN ); m_currentTrace.SetShape( newP, newN );
} }
if( m_currentTrace.EndsWithVias() ) if( m_currentTrace.EndsWithVias() )
@ -727,11 +752,11 @@ bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
} else } else
m_chainedPlacement = !m_snapOnTarget; m_chainedPlacement = !m_snapOnTarget;
PNS_LINE lineP ( m_currentTrace.PLine() ); PNS_LINE lineP( m_currentTrace.PLine() );
PNS_LINE lineN ( m_currentTrace.NLine() ); PNS_LINE lineN( m_currentTrace.NLine() );
m_lastNode->Add ( &lineP ); m_lastNode->Add( &lineP );
m_lastNode->Add ( &lineN ); m_lastNode->Add( &lineN );
topo.SimplifyLine( &lineP ); topo.SimplifyLine( &lineP );
topo.SimplifyLine( &lineN ); topo.SimplifyLine( &lineN );
@ -743,11 +768,13 @@ bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
m_lastNode = NULL; m_lastNode = NULL;
m_placingVia = false; m_placingVia = false;
if(m_snapOnTarget) if( m_snapOnTarget )
{ {
m_idle = true; m_idle = true;
return true; return true;
} else { }
else
{
initPlacement(); initPlacement();
return false; return false;
} }
@ -760,19 +787,19 @@ void PNS_DIFF_PAIR_PLACER::GetModifiedNets( std::vector<int> &aNets ) const
aNets.push_back( m_netN ); aNets.push_back( m_netN );
} }
void PNS_DIFF_PAIR_PLACER::updateLeadingRatLine() void PNS_DIFF_PAIR_PLACER::updateLeadingRatLine()
{ {
SHAPE_LINE_CHAIN ratLineN, ratLineP; SHAPE_LINE_CHAIN ratLineN, ratLineP;
PNS_TOPOLOGY topo ( m_lastNode ); PNS_TOPOLOGY topo( m_lastNode );
if( topo.LeadingRatLine ( &m_currentTrace.PLine(), ratLineP )) if( topo.LeadingRatLine( &m_currentTrace.PLine(), ratLineP ) )
{ {
Router()->DisplayDebugLine( ratLineP, 1, 10000 ); Router()->DisplayDebugLine( ratLineP, 1, 10000 );
} }
if( topo.LeadingRatLine ( &m_currentTrace.NLine(), ratLineN )) if( topo.LeadingRatLine ( &m_currentTrace.NLine(), ratLineN ) )
{ {
Router()->DisplayDebugLine( ratLineN, 3, 10000 ); Router()->DisplayDebugLine( ratLineN, 3, 10000 );
} }
} }

View File

@ -161,11 +161,11 @@ public:
bool IsPlacingVia() const { return m_placingVia; } bool IsPlacingVia() const { return m_placingVia; }
void SetOrthoMode ( bool aOrthoMode ); void SetOrthoMode( bool aOrthoMode );
void GetModifiedNets( std::vector<int>& aNets ) const;
void GetModifiedNets( std::vector<int> &aNets ) const;
private: private:
int viaGap() const; int viaGap() const;
int gap() const; int gap() const;
@ -214,7 +214,7 @@ private:
bool routeHead( const VECTOR2I& aP ); bool routeHead( const VECTOR2I& aP );
bool tryWalkDp ( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bool aSolidsOnly ); bool tryWalkDp( PNS_NODE* aNode, PNS_DIFF_PAIR& aPair, bool aSolidsOnly );
///> route step, walkaround mode ///> route step, walkaround mode
bool rhWalkOnly( const VECTOR2I& aP ); bool rhWalkOnly( const VECTOR2I& aP );
@ -227,10 +227,10 @@ private:
const PNS_VIA makeVia ( const VECTOR2I& aP, int aNet ); const PNS_VIA makeVia ( const VECTOR2I& aP, int aNet );
bool findDpPrimitivePair ( const VECTOR2I& aP, PNS_ITEM *aItem, PNS_DP_PRIMITIVE_PAIR& aPair ); bool findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair );
OPT_VECTOR2I getDanglingAnchor ( PNS_NODE *aNode, PNS_ITEM *aItem ); OPT_VECTOR2I getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem );
int matchDpSuffix ( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName ); int matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
bool attemptWalk ( PNS_NODE *aNode, PNS_DIFF_PAIR *aCurrent, PNS_DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly ); bool attemptWalk( PNS_NODE* aNode, PNS_DIFF_PAIR* aCurrent, PNS_DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly );
bool propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP ); bool propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP );
enum State { enum State {
@ -251,7 +251,6 @@ private:
PNS_DP_PRIMITIVE_PAIR m_start; PNS_DP_PRIMITIVE_PAIR m_start;
boost::optional<PNS_DP_PRIMITIVE_PAIR> m_prevPair; boost::optional<PNS_DP_PRIMITIVE_PAIR> m_prevPair;
///> current algorithm iteration ///> current algorithm iteration
int m_iteration; int m_iteration;
@ -294,7 +293,7 @@ private:
VECTOR2I m_currentEnd, m_currentStart; VECTOR2I m_currentEnd, m_currentStart;
PNS_DIFF_PAIR m_currentTrace; PNS_DIFF_PAIR m_currentTrace;
PNS_ITEM *m_currentEndItem; PNS_ITEM* m_currentEndItem;
PNS_MODE m_currentMode; PNS_MODE m_currentMode;
bool m_idle; bool m_idle;

View File

@ -34,13 +34,10 @@
#include "pns_router.h" #include "pns_router.h"
#include "pns_utils.h" #include "pns_utils.h"
using boost::optional; using boost::optional;
PNS_DP_MEANDER_PLACER::PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter ) : PNS_DP_MEANDER_PLACER::PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
PNS_MEANDER_PLACER_BASE ( aRouter ) PNS_MEANDER_PLACER_BASE( aRouter )
{ {
m_world = NULL; m_world = NULL;
m_currentNode = NULL; m_currentNode = NULL;
@ -49,31 +46,35 @@ PNS_DP_MEANDER_PLACER::PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
PNS_DP_MEANDER_PLACER::~PNS_DP_MEANDER_PLACER() PNS_DP_MEANDER_PLACER::~PNS_DP_MEANDER_PLACER()
{ {
} }
const PNS_LINE PNS_DP_MEANDER_PLACER::Trace() const const PNS_LINE PNS_DP_MEANDER_PLACER::Trace() const
{ {
return m_currentTraceP; return m_currentTraceP;
} }
PNS_NODE* PNS_DP_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const PNS_NODE* PNS_DP_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
{ {
if(!m_currentNode) if( !m_currentNode )
return m_world; return m_world;
return m_currentNode; return m_currentNode;
} }
bool PNS_DP_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) bool PNS_DP_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
VECTOR2I p; VECTOR2I p;
if(!aStartItem || !aStartItem->OfKind ( PNS_ITEM::SEGMENT ))
if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
{ {
Router()->SetFailureReason( _("Please select a track whose length you want to tune.") ); Router()->SetFailureReason( _( "Please select a track whose length you want to tune." ) );
return false; return false;
} }
m_initialSegment = static_cast<PNS_SEGMENT *>(aStartItem); m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
p = m_initialSegment->Seg().NearestPoint( aP ); p = m_initialSegment->Seg().NearestPoint( aP );
@ -82,9 +83,9 @@ bool PNS_DP_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
m_world = Router()->GetWorld()->Branch(); m_world = Router()->GetWorld()->Branch();
PNS_TOPOLOGY topo ( m_world ); PNS_TOPOLOGY topo( m_world );
if( !topo.AssembleDiffPair ( m_initialSegment, m_originPair ) ) if( !topo.AssembleDiffPair( m_initialSegment, m_originPair ) )
{ {
Router()->SetFailureReason( _( "Unable to find complementary differential pair " Router()->SetFailureReason( _( "Unable to find complementary differential pair "
"net for length tuning. Make sure the names of the nets belonging " "net for length tuning. Make sure the names of the nets belonging "
@ -92,18 +93,17 @@ bool PNS_DP_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
return false; return false;
} }
m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
m_originPair.SetGap ( Router()->Sizes().DiffPairGap() );
if( !m_originPair.PLine().SegmentCount() || if( !m_originPair.PLine().SegmentCount() ||
!m_originPair.NLine().SegmentCount() ) !m_originPair.NLine().SegmentCount() )
return false; return false;
m_tunedPathP = topo.AssembleTrivialPath ( m_originPair.PLine().GetLink(0) ); m_tunedPathP = topo.AssembleTrivialPath( m_originPair.PLine().GetLink( 0 ) );
m_tunedPathN = topo.AssembleTrivialPath ( m_originPair.NLine().GetLink(0) ); m_tunedPathN = topo.AssembleTrivialPath( m_originPair.NLine().GetLink( 0 ) );
m_world->Remove ( m_originPair.PLine() ); m_world->Remove( m_originPair.PLine() );
m_world->Remove ( m_originPair.NLine() ); m_world->Remove( m_originPair.NLine() );
m_currentWidth = m_originPair.Width(); m_currentWidth = m_originPair.Width();
@ -123,33 +123,35 @@ void PNS_DP_MEANDER_PLACER::release()
#endif #endif
} }
int PNS_DP_MEANDER_PLACER::origPathLength () const
int PNS_DP_MEANDER_PLACER::origPathLength() const
{ {
int totalP = 0; int totalP = 0;
int totalN = 0; int totalN = 0;
BOOST_FOREACH ( const PNS_ITEM *item, m_tunedPathP.CItems() ) BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathP.CItems() )
{ {
if ( const PNS_LINE *l = dyn_cast<const PNS_LINE *> (item) ) if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
totalP += l->CLine( ).Length( ); totalP += l->CLine().Length();
}
BOOST_FOREACH ( const PNS_ITEM *item, m_tunedPathN.CItems() )
{
if ( const PNS_LINE *l = dyn_cast<const PNS_LINE *> (item) )
totalN += l->CLine( ).Length( );
} }
return std::max(totalP, totalN); BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
{
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
totalN += l->CLine().Length();
}
return std::max( totalP, totalN );
} }
const SEG PNS_DP_MEANDER_PLACER::baselineSegment ( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aCoupledSegs )
const SEG PNS_DP_MEANDER_PLACER::baselineSegment( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aCoupledSegs )
{ {
const VECTOR2I a( ( aCoupledSegs.coupledP.A + aCoupledSegs.coupledN.A ) / 2 ); const VECTOR2I a( ( aCoupledSegs.coupledP.A + aCoupledSegs.coupledN.A ) / 2 );
const VECTOR2I b( ( aCoupledSegs.coupledP.B + aCoupledSegs.coupledN.B ) / 2 ); const VECTOR2I b( ( aCoupledSegs.coupledP.B + aCoupledSegs.coupledN.B ) / 2 );
return SEG (a, b); return SEG( a, b );
} }
@ -228,24 +230,21 @@ PNS_MEANDER_PLACER_BASE::TUNING_STATUS PNS_DP_MEANDER_PLACER::tuneLineLength ( P
#endif #endif
bool pairOrientation( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aPair ) bool pairOrientation( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aPair )
{ {
VECTOR2I midp = ( aPair.coupledP.A + aPair.coupledN.A ) / 2; VECTOR2I midp = ( aPair.coupledP.A + aPair.coupledN.A ) / 2;
//DrawDebugPoint (midp, 6); //DrawDebugPoint (midp, 6);
return aPair.coupledP.Side ( midp ) > 0; return aPair.coupledP.Side( midp ) > 0;
} }
bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem ) bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
// return false; // return false;
if(m_currentNode) if( m_currentNode )
delete m_currentNode; delete m_currentNode;
m_currentNode = m_world->Branch(); m_currentNode = m_world->Branch();
@ -253,18 +252,18 @@ bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
SHAPE_LINE_CHAIN preP, tunedP, postP; SHAPE_LINE_CHAIN preP, tunedP, postP;
SHAPE_LINE_CHAIN preN, tunedN, postN; SHAPE_LINE_CHAIN preN, tunedN, postN;
cutTunedLine ( m_originPair.CP(), m_currentStart, aP, preP, tunedP, postP ); cutTunedLine( m_originPair.CP(), m_currentStart, aP, preP, tunedP, postP );
cutTunedLine ( m_originPair.CN(), m_currentStart, aP, preN, tunedN, postN ); cutTunedLine( m_originPair.CN(), m_currentStart, aP, preN, tunedN, postN );
PNS_DIFF_PAIR tuned ( m_originPair ); PNS_DIFF_PAIR tuned ( m_originPair );
tuned.SetShape ( tunedP, tunedN ); tuned.SetShape( tunedP, tunedN );
m_coupledSegments.clear(); m_coupledSegments.clear();
tuned.CoupledSegmentPairs ( m_coupledSegments ); tuned.CoupledSegmentPairs( m_coupledSegments );
if (m_coupledSegments.size() == 0) if( m_coupledSegments.size() == 0 )
return false; return false;
//Router()->DisplayDebugLine ( tuned.CP(), 5, 20000 ); //Router()->DisplayDebugLine ( tuned.CP(), 5, 20000 );
@ -273,74 +272,71 @@ bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
//Router()->DisplayDebugLine ( m_originPair.CP(), 5, 20000 ); //Router()->DisplayDebugLine ( m_originPair.CP(), 5, 20000 );
//Router()->DisplayDebugLine ( m_originPair.CN(), 4, 20000 ); //Router()->DisplayDebugLine ( m_originPair.CN(), 4, 20000 );
m_result = PNS_MEANDERED_LINE (this, true ); m_result = PNS_MEANDERED_LINE( this, true );
m_result.SetWidth ( tuned.Width() ); m_result.SetWidth( tuned.Width() );
int offset = ( tuned.Gap() + tuned.Width() ) / 2; int offset = ( tuned.Gap() + tuned.Width() ) / 2;
if ( !pairOrientation ( m_coupledSegments[0] ) ) if( !pairOrientation( m_coupledSegments[0] ) )
offset *= -1; offset *= -1;
m_result.SetBaselineOffset( offset );
m_result.SetBaselineOffset ( offset ); BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathP.CItems() )
BOOST_FOREACH ( const PNS_ITEM *item, m_tunedPathP.CItems() )
{ {
if ( const PNS_LINE *l = dyn_cast<const PNS_LINE *> (item) ) if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
Router()->DisplayDebugLine ( l->CLine(), 5, 10000 ); Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
} }
BOOST_FOREACH ( const PNS_ITEM *item, m_tunedPathN.CItems() ) BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
{ {
if ( const PNS_LINE *l = dyn_cast<const PNS_LINE *> (item) ) if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
Router()->DisplayDebugLine ( l->CLine(), 5, 10000 ); Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
} }
BOOST_FOREACH( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& sp, m_coupledSegments )
BOOST_FOREACH ( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& sp, m_coupledSegments )
{ {
SEG base = baselineSegment ( sp ); SEG base = baselineSegment( sp );
// DrawDebugSeg ( base, 3 ); // DrawDebugSeg ( base, 3 );
m_result.AddCorner ( sp.parentP.A, sp.parentN.A ); m_result.AddCorner( sp.parentP.A, sp.parentN.A );
m_result.MeanderSegment ( base ); m_result.MeanderSegment( base );
m_result.AddCorner ( sp.parentP.B, sp.parentN.B ); m_result.AddCorner( sp.parentP.B, sp.parentN.B );
} }
int dpLen = origPathLength(); int dpLen = origPathLength();
m_lastStatus = TUNED; m_lastStatus = TUNED;
if (dpLen - m_settings.m_targetLength > m_settings.m_lengthTollerance) if( dpLen - m_settings.m_targetLength > m_settings.m_lengthTolerance )
{ {
m_lastStatus = TOO_LONG; m_lastStatus = TOO_LONG;
m_lastLength = dpLen; m_lastLength = dpLen;
} else { }
else
m_lastLength = dpLen - std::max ( tunedP.Length(), tunedN.Length() ); {
tuneLineLength(m_result, m_settings.m_targetLength - dpLen ); m_lastLength = dpLen - std::max( tunedP.Length(), tunedN.Length() );
tuneLineLength( m_result, m_settings.m_targetLength - dpLen );
} }
if (m_lastStatus != TOO_LONG) if( m_lastStatus != TOO_LONG )
{ {
tunedP.Clear(); tunedP.Clear();
tunedN.Clear(); tunedN.Clear();
BOOST_FOREACH ( PNS_MEANDER_SHAPE *m, m_result.Meanders() ) BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_result.Meanders() )
{ {
if( m->Type() != MT_EMPTY ) if( m->Type() != MT_EMPTY )
{ {
tunedP.Append ( m->CLine(0) ); tunedP.Append ( m->CLine( 0 ) );
tunedN.Append ( m->CLine(1) ); tunedN.Append ( m->CLine( 1 ) );
} }
} }
m_lastLength += std::max ( tunedP.Length(), tunedN.Length() ); m_lastLength += std::max( tunedP.Length(), tunedN.Length() );
int comp = compareWithTollerance( m_lastLength - m_settings.m_targetLength, 0, m_settings.m_lengthTollerance ); int comp = compareWithTolerance( m_lastLength - m_settings.m_targetLength, 0, m_settings.m_lengthTolerance );
if( comp > 0 ) if( comp > 0 )
m_lastStatus = TOO_LONG; m_lastStatus = TOO_LONG;
@ -348,16 +344,15 @@ bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
m_lastStatus = TOO_SHORT; m_lastStatus = TOO_SHORT;
else else
m_lastStatus = TUNED; m_lastStatus = TUNED;
} }
m_finalShapeP.Clear( ); m_finalShapeP.Clear();
m_finalShapeP.Append( preP ); m_finalShapeP.Append( preP );
m_finalShapeP.Append( tunedP ); m_finalShapeP.Append( tunedP );
m_finalShapeP.Append( postP ); m_finalShapeP.Append( postP );
m_finalShapeP.Simplify(); m_finalShapeP.Simplify();
m_finalShapeN.Clear( ); m_finalShapeN.Clear();
m_finalShapeN.Append( preN ); m_finalShapeN.Append( preN );
m_finalShapeN.Append( tunedN ); m_finalShapeN.Append( tunedN );
m_finalShapeN.Append( postN ); m_finalShapeN.Append( postN );
@ -369,21 +364,22 @@ bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
bool PNS_DP_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) bool PNS_DP_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
PNS_LINE lP ( m_originPair.PLine(), m_finalShapeP ); PNS_LINE lP( m_originPair.PLine(), m_finalShapeP );
PNS_LINE lN ( m_originPair.NLine(), m_finalShapeN ); PNS_LINE lN( m_originPair.NLine(), m_finalShapeN );
m_currentNode->Add ( &lP ); m_currentNode->Add( &lP );
m_currentNode->Add ( &lN ); m_currentNode->Add( &lN );
Router()->CommitRouting( m_currentNode ); Router()->CommitRouting( m_currentNode );
return true; return true;
} }
bool PNS_DP_MEANDER_PLACER::CheckFit ( PNS_MEANDER_SHAPE *aShape )
bool PNS_DP_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE* aShape )
{ {
PNS_LINE l1 ( m_originPair.PLine(), aShape->CLine(0) ); PNS_LINE l1( m_originPair.PLine(), aShape->CLine( 0 ) );
PNS_LINE l2 ( m_originPair.NLine(), aShape->CLine(1) ); PNS_LINE l2( m_originPair.NLine(), aShape->CLine( 1 ) );
if( m_currentNode->CheckColliding( &l1 ) ) if( m_currentNode->CheckColliding( &l1 ) )
return false; return false;
@ -400,50 +396,53 @@ bool PNS_DP_MEANDER_PLACER::CheckFit ( PNS_MEANDER_SHAPE *aShape )
const PNS_ITEMSET PNS_DP_MEANDER_PLACER::Traces() const PNS_ITEMSET PNS_DP_MEANDER_PLACER::Traces()
{ {
m_currentTraceP = PNS_LINE( m_originPair.PLine(), m_finalShapeP );
m_currentTraceP = PNS_LINE ( m_originPair.PLine(), m_finalShapeP ); m_currentTraceN = PNS_LINE( m_originPair.NLine(), m_finalShapeN );
m_currentTraceN = PNS_LINE ( m_originPair.NLine(), m_finalShapeN );
PNS_ITEMSET traces; PNS_ITEMSET traces;
traces.Add (&m_currentTraceP); traces.Add( &m_currentTraceP );
traces.Add (&m_currentTraceN); traces.Add( &m_currentTraceN );
return traces; return traces;
} }
const VECTOR2I& PNS_DP_MEANDER_PLACER::CurrentEnd() const const VECTOR2I& PNS_DP_MEANDER_PLACER::CurrentEnd() const
{ {
return m_currentEnd; return m_currentEnd;
} }
int PNS_DP_MEANDER_PLACER::CurrentNet() const int PNS_DP_MEANDER_PLACER::CurrentNet() const
{ {
return m_initialSegment->Net(); return m_initialSegment->Net();
} }
int PNS_DP_MEANDER_PLACER::CurrentLayer() const int PNS_DP_MEANDER_PLACER::CurrentLayer() const
{ {
return m_initialSegment->Layers().Start(); return m_initialSegment->Layers().Start();
} }
const wxString PNS_DP_MEANDER_PLACER::TuningInfo() const const wxString PNS_DP_MEANDER_PLACER::TuningInfo() const
{ {
wxString status; wxString status;
switch (m_lastStatus) switch( m_lastStatus )
{ {
case TOO_LONG: case TOO_LONG:
status = _("Too long: "); status = _( "Too long: " );
break; break;
case TOO_SHORT: case TOO_SHORT:
status = _("Too short: "); status = _("Too short: " );
break; break;
case TUNED: case TUNED:
status = _("Tuned: "); status = _( "Tuned: " );
break; break;
default: default:
return _("?"); return _( "?" );
} }
status += LengthDoubleToString( (double) m_lastLength, false ); status += LengthDoubleToString( (double) m_lastLength, false );
@ -453,6 +452,7 @@ const wxString PNS_DP_MEANDER_PLACER::TuningInfo() const
return status; return status;
} }
PNS_DP_MEANDER_PLACER::TUNING_STATUS PNS_DP_MEANDER_PLACER::TuningStatus() const PNS_DP_MEANDER_PLACER::TUNING_STATUS PNS_DP_MEANDER_PLACER::TuningStatus() const
{ {
return m_lastStatus; return m_lastStatus;

View File

@ -48,7 +48,6 @@ class PNS_ROUTER_BASE;
class PNS_DP_MEANDER_PLACER : public PNS_MEANDER_PLACER_BASE class PNS_DP_MEANDER_PLACER : public PNS_MEANDER_PLACER_BASE
{ {
public: public:
PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter ); PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter );
~PNS_DP_MEANDER_PLACER(); ~PNS_DP_MEANDER_PLACER();
@ -96,13 +95,12 @@ public:
int CurrentNet() const; int CurrentNet() const;
int CurrentLayer() const; int CurrentLayer() const;
int totalLength(); int totalLength();
const wxString TuningInfo() const; const wxString TuningInfo() const;
TUNING_STATUS TuningStatus() const; TUNING_STATUS TuningStatus() const;
bool CheckFit ( PNS_MEANDER_SHAPE* aShape ); bool CheckFit( PNS_MEANDER_SHAPE* aShape );
private: private:
@ -110,17 +108,15 @@ private:
void meanderSegment ( const SEG& aBase ); void meanderSegment ( const SEG& aBase );
// void addMeander ( PNS_MEANDER *aM ); // void addMeander ( PNS_MEANDER *aM );
// void addCorner ( const VECTOR2I& aP ); // void addCorner ( const VECTOR2I& aP );
const SEG baselineSegment ( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aCoupledSegs ); const SEG baselineSegment( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aCoupledSegs );
void setWorld ( PNS_NODE* aWorld ); void setWorld( PNS_NODE* aWorld );
void release(); void release();
int origPathLength () const; int origPathLength() const;
///> pointer to world to search colliding items ///> pointer to world to search colliding items
PNS_NODE* m_world; PNS_NODE* m_world;
@ -139,7 +135,7 @@ private:
SHAPE_LINE_CHAIN m_finalShapeP, m_finalShapeN; SHAPE_LINE_CHAIN m_finalShapeP, m_finalShapeN;
PNS_MEANDERED_LINE m_result; PNS_MEANDERED_LINE m_result;
PNS_SEGMENT *m_initialSegment; PNS_SEGMENT* m_initialSegment;
int m_lastLength; int m_lastLength;
TUNING_STATUS m_lastStatus; TUNING_STATUS m_lastStatus;

View File

@ -96,7 +96,7 @@ public:
virtual PNS_LOGGER* Logger(); virtual PNS_LOGGER* Logger();
private: private:
typedef std::pair<PNS_LINE *, PNS_LINE *> LinePair; typedef std::pair<PNS_LINE*, PNS_LINE*> LinePair;
typedef std::vector<LinePair> LinePairVec; typedef std::vector<LinePair> LinePairVec;
enum DragMode { enum DragMode {

View File

@ -160,7 +160,6 @@ PNS_INDEX::PNS_INDEX()
memset( m_subIndices, 0, sizeof( m_subIndices ) ); memset( m_subIndices, 0, sizeof( m_subIndices ) );
} }
PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
{ {
int idx_n = -1; int idx_n = -1;
@ -201,7 +200,6 @@ PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
return m_subIndices[idx_n]; return m_subIndices[idx_n];
} }
void PNS_INDEX::Add( PNS_ITEM* aItem ) void PNS_INDEX::Add( PNS_ITEM* aItem )
{ {
ITEM_SHAPE_INDEX* idx = getSubindex( aItem ); ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
@ -216,7 +214,6 @@ void PNS_INDEX::Add( PNS_ITEM* aItem )
} }
} }
void PNS_INDEX::Remove( PNS_ITEM* aItem ) void PNS_INDEX::Remove( PNS_ITEM* aItem )
{ {
ITEM_SHAPE_INDEX* idx = getSubindex( aItem ); ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
@ -230,14 +227,12 @@ void PNS_INDEX::Remove( PNS_ITEM* aItem )
m_netMap[net].remove( aItem ); m_netMap[net].remove( aItem );
} }
void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ) void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem )
{ {
Remove( aOldItem ); Remove( aOldItem );
Add( aNewItem ); Add( aNewItem );
} }
template<class Visitor> template<class Visitor>
int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& aVisitor ) int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
{ {
@ -247,7 +242,6 @@ int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Vi
return m_subIndices[index]->Query( aShape, aMinDistance, aVisitor, false ); return m_subIndices[index]->Query( aShape, aMinDistance, aVisitor, false );
} }
template<class Visitor> template<class Visitor>
int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& aVisitor ) int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& aVisitor )
{ {
@ -281,7 +275,6 @@ int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& aVisitor
return total; return total;
} }
template<class Visitor> template<class Visitor>
int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& aVisitor ) int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
{ {
@ -293,7 +286,6 @@ int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
return total; return total;
} }
void PNS_INDEX::Clear() void PNS_INDEX::Clear()
{ {
for( int i = 0; i < MaxSubIndices; ++i ) for( int i = 0; i < MaxSubIndices; ++i )
@ -307,13 +299,11 @@ void PNS_INDEX::Clear()
} }
} }
PNS_INDEX::~PNS_INDEX() PNS_INDEX::~PNS_INDEX()
{ {
Clear(); Clear();
} }
PNS_INDEX::NET_ITEMS_LIST* PNS_INDEX::GetItemsForNet( int aNet ) PNS_INDEX::NET_ITEMS_LIST* PNS_INDEX::GetItemsForNet( int aNet )
{ {
if( m_netMap.find( aNet ) == m_netMap.end() ) if( m_netMap.find( aNet ) == m_netMap.end() )

View File

@ -23,21 +23,23 @@
#include "pns_itemset.h" #include "pns_itemset.h"
PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem ) : PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem ) :
m_owner ( false ) m_owner( false )
{ {
if( aInitialItem ) if( aInitialItem )
m_items.push_back( aInitialItem ); m_items.push_back( aInitialItem );
} }
PNS_ITEMSET::~PNS_ITEMSET() PNS_ITEMSET::~PNS_ITEMSET()
{ {
if (m_owner) if( m_owner )
{ {
BOOST_FOREACH ( PNS_ITEM *item, m_items ) BOOST_FOREACH( PNS_ITEM* item, m_items )
delete item; delete item;
} }
} }
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert ) PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
{ {
ITEMS newItems; ITEMS newItems;
@ -74,6 +76,7 @@ PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask, bool aInvert )
return *this; return *this;
} }
PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, bool aInvert ) PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, bool aInvert )
{ {
ITEMS newItems; ITEMS newItems;
@ -105,6 +108,7 @@ PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
return *this; return *this;
} }
PNS_ITEMSET& PNS_ITEMSET::ExcludeItem( const PNS_ITEM* aItem ) PNS_ITEMSET& PNS_ITEMSET::ExcludeItem( const PNS_ITEM* aItem )
{ {
ITEMS newItems; ITEMS newItems;

View File

@ -41,14 +41,14 @@ public:
PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL ); PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL );
PNS_ITEMSET( const PNS_ITEMSET& aOther ): PNS_ITEMSET( const PNS_ITEMSET& aOther ):
m_owner ( false ) m_owner( false )
{ {
m_items = aOther.m_items; m_items = aOther.m_items;
} }
~PNS_ITEMSET(); ~PNS_ITEMSET();
void MakeOwner ( ) void MakeOwner()
{ {
m_owner = true; m_owner = true;
} }
@ -105,9 +105,9 @@ public:
m_items.push_back( aItem ); m_items.push_back( aItem );
} }
void Prepend ( PNS_ITEM *aItem ) void Prepend( PNS_ITEM* aItem )
{ {
m_items.push_front ( aItem ); m_items.push_front( aItem );
} }
PNS_ITEM* Get( int index ) const PNS_ITEM* Get( int index ) const

View File

@ -95,20 +95,20 @@ public:
return seg1->Width() == seg2->Width(); return seg1->Width() == seg2->Width();
} }
bool IsNonFanoutVia () const bool IsNonFanoutVia() const
{ {
if ( m_linkedItems.Size() != 3 ) if( m_linkedItems.Size() != 3 )
return false; return false;
int vias = 0, segs = 0; int vias = 0, segs = 0;
for(int i = 0; i < 3; i++) for( int i = 0; i < 3; i++ )
{ {
vias += m_linkedItems[i]->Kind() == VIA ? 1 : 0; vias += m_linkedItems[i]->Kind() == VIA ? 1 : 0;
segs += m_linkedItems[i]->Kind() == SEGMENT ? 1 : 0; segs += m_linkedItems[i]->Kind() == SEGMENT ? 1 : 0;
} }
return (vias == 1 && segs == 2); return ( vias == 1 && segs == 2 );
} }
///> Links the joint to a given board item (when it's added to the PNS_NODE) ///> Links the joint to a given board item (when it's added to the PNS_NODE)
@ -209,15 +209,11 @@ private:
PNS_ITEMSET m_linkedItems; PNS_ITEMSET m_linkedItems;
}; };
inline bool operator==( PNS_JOINT::HASH_TAG const& aP1, PNS_JOINT::HASH_TAG const& aP2 )
// hash function & comparison operator for boost::unordered_map<>
inline bool operator==( PNS_JOINT::HASH_TAG const& aP1,
PNS_JOINT::HASH_TAG const& aP2 )
{ {
return aP1.pos == aP2.pos && aP1.net == aP2.net; return aP1.pos == aP2.pos && aP1.net == aP2.net;
} }
inline std::size_t hash_value( PNS_JOINT::HASH_TAG const& aP ) inline std::size_t hash_value( PNS_JOINT::HASH_TAG const& aP )
{ {
std::size_t seed = 0; std::size_t seed = 0;

View File

@ -348,7 +348,6 @@ SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECT
{ {
optional<SHAPE_LINE_CHAIN> picked; optional<SHAPE_LINE_CHAIN> picked;
int i; int i;
int d = 2; int d = 2;
if( aOrigin.CSegment( -1 ).Length() > 100000 * 30 ) // fixme: constant/parameter? if( aOrigin.CSegment( -1 ).Length() > 100000 * 30 ) // fixme: constant/parameter?
@ -701,7 +700,7 @@ void PNS_LINE::Reverse()
void PNS_LINE::AppendVia( const PNS_VIA& aVia ) void PNS_LINE::AppendVia( const PNS_VIA& aVia )
{ {
if(m_line.PointCount() == 0) if( m_line.PointCount() == 0 )
return; return;
if( aVia.Pos() == m_line.CPoint( 0 ) ) if( aVia.Pos() == m_line.CPoint( 0 ) )
@ -785,44 +784,47 @@ void PNS_LINE::ClearSegmentLinks()
m_segmentRefs = NULL; m_segmentRefs = NULL;
} }
static void extendBox( BOX2I& aBox, bool &aDefined, const VECTOR2I& aP )
static void extendBox( BOX2I& aBox, bool& aDefined, const VECTOR2I& aP )
{ {
if( aDefined ) if( aDefined )
aBox.Merge ( aP ); aBox.Merge ( aP );
else { else {
aBox = BOX2I ( aP, VECTOR2I (0, 0 ) ); aBox = BOX2I( aP, VECTOR2I( 0, 0 ) );
aDefined = true; aDefined = true;
} }
} }
OPT_BOX2I PNS_LINE::ChangedArea ( const PNS_LINE *aOther ) const
OPT_BOX2I PNS_LINE::ChangedArea( const PNS_LINE* aOther ) const
{ {
BOX2I area; BOX2I area;
bool areaDefined = false; bool areaDefined = false;
int i_start = -1; int i_start = -1;
int i_end_self = -1, i_end_other = -1; int i_end_self = -1, i_end_other = -1;
SHAPE_LINE_CHAIN self ( m_line ); SHAPE_LINE_CHAIN self( m_line );
self.Simplify(); self.Simplify();
SHAPE_LINE_CHAIN other ( aOther->m_line ); SHAPE_LINE_CHAIN other( aOther->m_line );
other.Simplify(); other.Simplify();
int np_self = self.PointCount(); int np_self = self.PointCount();
int np_other = other.PointCount(); int np_other = other.PointCount();
int n = std::min ( np_self, np_other ); int n = std::min( np_self, np_other );
for( int i = 0; i < n; i++) for( int i = 0; i < n; i++ )
{ {
const VECTOR2I p1 = self.CPoint(i); const VECTOR2I p1 = self.CPoint( i );
const VECTOR2I p2 = other.CPoint(i); const VECTOR2I p2 = other.CPoint( i );
if (p1 != p2)
if( p1 != p2 )
{ {
if (i != n - 1) if( i != n - 1 )
{ {
SEG s = self.CSegment(i); SEG s = self.CSegment( i );
if( !s.Contains( p2 ) ) if( !s.Contains( p2 ) )
{ {
i_start = i; i_start = i;
@ -832,16 +834,15 @@ OPT_BOX2I PNS_LINE::ChangedArea ( const PNS_LINE *aOther ) const
i_start = i; i_start = i;
break; break;
} }
} }
} }
for( int i = 0; i < n; i++) for( int i = 0; i < n; i++ )
{ {
const VECTOR2I p1 = self.CPoint( np_self - 1 - i ); const VECTOR2I p1 = self.CPoint( np_self - 1 - i );
const VECTOR2I p2 = other.CPoint( np_other - 1 - i ); const VECTOR2I p2 = other.CPoint( np_other - 1 - i );
if (p1 != p2)
if( p1 != p2 )
{ {
i_end_self = np_self - 1 - i; i_end_self = np_self - 1 - i;
i_end_other = np_other - 1 - i; i_end_other = np_other - 1 - i;
@ -858,17 +859,17 @@ OPT_BOX2I PNS_LINE::ChangedArea ( const PNS_LINE *aOther ) const
if( i_end_other < 0 ) if( i_end_other < 0 )
i_end_other = np_other - 1; i_end_other = np_other - 1;
for (int i = i_start; i <= i_end_self; i++ ) for( int i = i_start; i <= i_end_self; i++ )
extendBox ( area, areaDefined, self.CPoint(i) ); extendBox( area, areaDefined, self.CPoint( i ) );
for (int i = i_start; i <= i_end_other; i++ ) for( int i = i_start; i <= i_end_other; i++ )
extendBox ( area, areaDefined, other.CPoint(i) ); extendBox( area, areaDefined, other.CPoint( i ) );
if( areaDefined ) if( areaDefined )
{ {
area.Inflate ( std::max( Width(), aOther->Width() ) ); area.Inflate( std::max( Width(), aOther->Width() ) );
return area; return area;
} }
return OPT_BOX2I ( ); return OPT_BOX2I();
} }

View File

@ -184,7 +184,7 @@ public:
return m_segmentRefs; return m_segmentRefs;
} }
bool IsLinked () const bool IsLinked() const
{ {
return m_segmentRefs != NULL; return m_segmentRefs != NULL;
} }
@ -199,7 +199,7 @@ public:
aSeg ) != m_segmentRefs->end(); aSeg ) != m_segmentRefs->end();
} }
PNS_SEGMENT* GetLink ( int aIndex ) const PNS_SEGMENT* GetLink( int aIndex ) const
{ {
return (*m_segmentRefs) [ aIndex ]; return (*m_segmentRefs) [ aIndex ];
} }
@ -266,7 +266,7 @@ public:
bool HasLoops() const; bool HasLoops() const;
OPT_BOX2I ChangedArea ( const PNS_LINE *aOther ) const; OPT_BOX2I ChangedArea( const PNS_LINE* aOther ) const;
private: private:
VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP, VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,

View File

@ -38,7 +38,7 @@
using boost::optional; using boost::optional;
PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) : PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) :
PNS_PLACEMENT_ALGO ( aRouter ) PNS_PLACEMENT_ALGO( aRouter )
{ {
m_initial_direction = DIRECTION_45::N; m_initial_direction = DIRECTION_45::N;
m_world = NULL; m_world = NULL;
@ -71,8 +71,8 @@ const PNS_VIA PNS_LINE_PLACER::makeVia ( const VECTOR2I& aP )
bool PNS_LINE_PLACER::ToggleVia( bool aEnabled ) bool PNS_LINE_PLACER::ToggleVia( bool aEnabled )
{ {
m_placingVia = aEnabled; m_placingVia = aEnabled;
if(!m_idle) if( !m_idle )
Move ( m_currentEnd, NULL ); Move( m_currentEnd, NULL );
return true; return true;
} }
@ -377,7 +377,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead ) bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
{ {
SHAPE_LINE_CHAIN line = buildInitialLine ( aP ); SHAPE_LINE_CHAIN line = buildInitialLine( aP );
PNS_LINE initTrack( m_head, line ), walkFull; PNS_LINE initTrack( m_head, line ), walkFull;
int effort = 0; int effort = 0;
bool viaOk = handleViaPlacement( initTrack ); bool viaOk = handleViaPlacement( initTrack );
@ -431,7 +431,7 @@ bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead ) bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
{ {
m_head.SetShape( buildInitialLine ( aP ) ); m_head.SetShape( buildInitialLine( aP ) );
if( m_placingVia ) if( m_placingVia )
{ {
@ -446,7 +446,7 @@ bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
{ {
SHAPE_LINE_CHAIN line = buildInitialLine ( aP ); SHAPE_LINE_CHAIN line = buildInitialLine( aP );
PNS_LINE initTrack( m_head, line ); PNS_LINE initTrack( m_head, line );
PNS_LINE walkSolids, l2; PNS_LINE walkSolids, l2;
@ -531,9 +531,9 @@ bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
case RM_MarkObstacles: case RM_MarkObstacles:
return rhMarkObstacles( aP, aNewHead ); return rhMarkObstacles( aP, aNewHead );
case RM_Walkaround: case RM_Walkaround:
return rhWalkOnly ( aP, aNewHead ); return rhWalkOnly( aP, aNewHead );
case RM_Shove: case RM_Shove:
return rhShoveOnly ( aP, aNewHead ); return rhShoveOnly( aP, aNewHead );
default: default:
break; break;
} }
@ -732,9 +732,12 @@ bool PNS_LINE_PLACER::SetLayer( int aLayer )
{ {
m_currentLayer = aLayer; m_currentLayer = aLayer;
return true; return true;
} else if( m_chainedPlacement ) { }
else if( m_chainedPlacement )
{
return false; return false;
} else if( !m_startItem || ( m_startItem->OfKind( PNS_ITEM::VIA ) && m_startItem->Layers().Overlaps( aLayer ) ) ) { }
else if( !m_startItem || ( m_startItem->OfKind( PNS_ITEM::VIA ) && m_startItem->Layers().Overlaps( aLayer ) ) ) {
m_currentLayer = aLayer; m_currentLayer = aLayer;
m_splitSeg = false; m_splitSeg = false;
initPlacement ( m_splitSeg ); initPlacement ( m_splitSeg );
@ -745,6 +748,7 @@ bool PNS_LINE_PLACER::SetLayer( int aLayer )
return false; return false;
} }
bool PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) bool PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
VECTOR2I p( aP ); VECTOR2I p( aP );
@ -1013,36 +1017,39 @@ void PNS_LINE_PLACER::updateLeadingRatLine()
SHAPE_LINE_CHAIN ratLine; SHAPE_LINE_CHAIN ratLine;
PNS_TOPOLOGY topo ( m_lastNode ); PNS_TOPOLOGY topo ( m_lastNode );
if( topo.LeadingRatLine ( &current, ratLine )) if( topo.LeadingRatLine( &current, ratLine ) )
Router()->DisplayDebugLine( ratLine, 5, 10000 ); Router()->DisplayDebugLine( ratLine, 5, 10000 );
} }
void PNS_LINE_PLACER::SetOrthoMode ( bool aOrthoMode )
void PNS_LINE_PLACER::SetOrthoMode( bool aOrthoMode )
{ {
m_orthoMode = aOrthoMode; m_orthoMode = aOrthoMode;
if(!m_idle)
Move ( m_currentEnd, NULL ); if( !m_idle )
Move( m_currentEnd, NULL );
} }
const SHAPE_LINE_CHAIN PNS_LINE_PLACER::buildInitialLine ( const VECTOR2I& aP ) const SHAPE_LINE_CHAIN PNS_LINE_PLACER::buildInitialLine( const VECTOR2I& aP )
{ {
SHAPE_LINE_CHAIN l (m_direction.BuildInitialTrace( m_p_start, aP ) ); SHAPE_LINE_CHAIN l( m_direction.BuildInitialTrace( m_p_start, aP ) );
if( l.SegmentCount() <= 1 ) if( l.SegmentCount() <= 1 )
return l; return l;
if (m_orthoMode) if( m_orthoMode )
{ {
VECTOR2I newLast = l.CSegment(0).LineProject ( l.CPoint(-1) ); VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
l.Remove(-1, -1); l.Remove( -1, -1 );
l.Point(1) = newLast; l.Point( 1 ) = newLast;
} }
return l; return l;
} }
void PNS_LINE_PLACER::GetModifiedNets( std::vector<int> &aNets ) const
void PNS_LINE_PLACER::GetModifiedNets( std::vector<int>& aNets ) const
{ {
aNets.push_back( m_currentNet ); aNets.push_back( m_currentNet );
} }

View File

@ -40,7 +40,6 @@ class PNS_VIA;
class PNS_SIZES_SETTINGS; class PNS_SIZES_SETTINGS;
/** /**
* Class PNS_LINE_PLACER * Class PNS_LINE_PLACER
* *
@ -96,7 +95,6 @@ public:
*/ */
bool SetLayer( int aLayer ); bool SetLayer( int aLayer );
/** /**
* Function Head() * Function Head()
* *
@ -181,11 +179,11 @@ public:
*/ */
void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes ); void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes );
void SetOrthoMode ( bool aOrthoMode ); void SetOrthoMode( bool aOrthoMode );
bool IsPlacingVia() const { return m_placingVia; } bool IsPlacingVia() const { return m_placingVia; }
void GetModifiedNets( std::vector<int> &aNets ) const; void GetModifiedNets( std::vector<int>& aNets ) const;
private: private:
/** /**
* Function route() * Function route()
@ -348,7 +346,8 @@ private:
bool rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead ); bool rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead );
const PNS_VIA makeVia ( const VECTOR2I& aP ); const PNS_VIA makeVia ( const VECTOR2I& aP );
const SHAPE_LINE_CHAIN buildInitialLine ( const VECTOR2I& aP );
const SHAPE_LINE_CHAIN buildInitialLine( const VECTOR2I& aP );
///> current routing direction ///> current routing direction
DIRECTION_45 m_direction; DIRECTION_45 m_direction;

View File

@ -178,6 +178,7 @@ void PNS_LOGGER::dumpShape( const SHAPE* aSh )
} }
} }
void PNS_LOGGER::Save( const std::string& aFilename ) void PNS_LOGGER::Save( const std::string& aFilename )
{ {
EndGroup(); EndGroup();

View File

@ -50,7 +50,7 @@ public:
const std::string aName = std::string() ); const std::string aName = std::string() );
private: private:
void dumpShape ( const SHAPE* aSh ); void dumpShape( const SHAPE* aSh );
bool m_groupOpened; bool m_groupOpened;
std::stringstream m_theLog; std::stringstream m_theLog;

View File

@ -32,26 +32,26 @@
#include "pns_meander_placer_base.h" #include "pns_meander_placer_base.h"
#include "pns_router.h" #include "pns_router.h"
const PNS_MEANDER_SETTINGS& PNS_MEANDER_SHAPE::Settings( ) const const PNS_MEANDER_SETTINGS& PNS_MEANDER_SHAPE::Settings() const
{ {
return m_placer->MeanderSettings( ); return m_placer->MeanderSettings();
} }
const PNS_MEANDER_SETTINGS& PNS_MEANDERED_LINE::Settings( ) const const PNS_MEANDER_SETTINGS& PNS_MEANDERED_LINE::Settings() const
{ {
return m_placer->MeanderSettings( ); return m_placer->MeanderSettings();
} }
void PNS_MEANDERED_LINE::MeanderSegment( const SEG &aBase, int aBaseIndex ) void PNS_MEANDERED_LINE::MeanderSegment( const SEG& aBase, int aBaseIndex )
{ {
double base_len = aBase.Length( ); double base_len = aBase.Length();
SHAPE_LINE_CHAIN lc; SHAPE_LINE_CHAIN lc;
bool side = true; bool side = true;
VECTOR2D dir( aBase.B - aBase.A ); VECTOR2D dir( aBase.B - aBase.A );
if(!m_dual) if( !m_dual )
AddCorner( aBase.A ); AddCorner( aBase.A );
bool turning = false; bool turning = false;
@ -61,21 +61,20 @@ void PNS_MEANDERED_LINE::MeanderSegment( const SEG &aBase, int aBaseIndex )
do do
{ {
PNS_MEANDER_SHAPE *m = new PNS_MEANDER_SHAPE( m_placer, m_width, m_dual ); PNS_MEANDER_SHAPE* m = new PNS_MEANDER_SHAPE( m_placer, m_width, m_dual );
m->SetBaselineOffset( m_baselineOffset ); m->SetBaselineOffset( m_baselineOffset );
m->SetBaseIndex( aBaseIndex ); m->SetBaseIndex( aBaseIndex );
double thr = (double) m->spacing( ); double thr = (double) m->spacing();
bool fail = false; bool fail = false;
double remaining = base_len - ( m_last - aBase.A ).EuclideanNorm( ); double remaining = base_len - ( m_last - aBase.A ).EuclideanNorm();
if( remaining < Settings( ).m_step ) if( remaining < Settings( ).m_step )
break; break;
if( remaining > 3.0 * thr ) if( remaining > 3.0 * thr )
{ {
if( !turning ) if( !turning )
{ {
for( int i = 0; i < 2; i++ ) for( int i = 0; i < 2; i++ )
@ -106,7 +105,6 @@ void PNS_MEANDERED_LINE::MeanderSegment( const SEG &aBase, int aBaseIndex )
} }
} }
} }
} else { } else {
bool rv = m->Fit( MT_CHECK_FINISH, aBase, m_last, side ); bool rv = m->Fit( MT_CHECK_FINISH, aBase, m_last, side );
@ -124,12 +122,11 @@ void PNS_MEANDERED_LINE::MeanderSegment( const SEG &aBase, int aBaseIndex )
side = !side; side = !side;
} }
} else if( started ) } else if( started )
{ {
bool rv = m->Fit( MT_FINISH, aBase, m_last, side ); bool rv = m->Fit( MT_FINISH, aBase, m_last, side );
if( rv ) if( rv )
AddMeander(m); AddMeander( m );
break; break;
@ -142,19 +139,18 @@ void PNS_MEANDERED_LINE::MeanderSegment( const SEG &aBase, int aBaseIndex )
if( remaining < Settings( ).m_step ) if( remaining < Settings( ).m_step )
break; break;
if( fail ) if( fail )
{ {
PNS_MEANDER_SHAPE tmp( m_placer, m_width, m_dual ); PNS_MEANDER_SHAPE tmp( m_placer, m_width, m_dual );
tmp.SetBaselineOffset( m_baselineOffset ); tmp.SetBaselineOffset( m_baselineOffset );
tmp.SetBaseIndex( aBaseIndex ); tmp.SetBaseIndex( aBaseIndex );
int nextP = tmp.spacing( ) - 2 * tmp.cornerRadius( ) + Settings( ).m_step; int nextP = tmp.spacing() - 2 * tmp.cornerRadius() + Settings().m_step;
VECTOR2I pn = m_last + dir.Resize ( nextP ); VECTOR2I pn = m_last + dir.Resize( nextP );
if (aBase.Contains( pn ) && !m_dual) if( aBase.Contains( pn ) && !m_dual )
{ {
AddCorner ( pn ); AddCorner( pn );
} else } else
break; break;
} }
@ -167,26 +163,27 @@ void PNS_MEANDERED_LINE::MeanderSegment( const SEG &aBase, int aBaseIndex )
} }
int PNS_MEANDER_SHAPE::cornerRadius( ) const int PNS_MEANDER_SHAPE::cornerRadius() const
{ {
int cr = (int64_t) spacing( ) * Settings( ).m_cornerRadiusPercentage / 200; int cr = (int64_t) spacing() * Settings().m_cornerRadiusPercentage / 200;
return cr; return cr;
} }
int PNS_MEANDER_SHAPE::spacing( ) const int PNS_MEANDER_SHAPE::spacing( ) const
{ {
if ( !m_dual ) if ( !m_dual )
return std::max ( 2 * m_width, Settings( ).m_spacing ); return std::max( 2 * m_width, Settings().m_spacing );
else else
{ {
int sp = 2 * ( m_width + std::abs( m_baselineOffset ) ); int sp = 2 * ( m_width + std::abs( m_baselineOffset ) );
return std::max ( sp, Settings( ).m_spacing ); return std::max ( sp, Settings().m_spacing );
} }
} }
SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::circleQuad( VECTOR2D aP, VECTOR2D aDir, bool side ) SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide )
{ {
SHAPE_LINE_CHAIN lc; SHAPE_LINE_CHAIN lc;
@ -199,18 +196,20 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::circleQuad( VECTOR2D aP, VECTOR2D aDir, bool
VECTOR2D dir_u( aDir ); VECTOR2D dir_u( aDir );
VECTOR2D dir_v( aDir.Perpendicular( ) ); VECTOR2D dir_v( aDir.Perpendicular( ) );
const int ArcSegments = Settings( ).m_cornerArcSegments; const int ArcSegments = Settings().m_cornerArcSegments;
for(int i = ArcSegments - 1; i >= 0; i--) for( int i = ArcSegments - 1; i >= 0; i-- )
{ {
VECTOR2D p; VECTOR2D p;
double alpha = (double) i / (double) (ArcSegments - 1) * M_PI / 2.0; double alpha = (double) i / (double) ( ArcSegments - 1 ) * M_PI / 2.0;
p = aP + dir_u * cos( alpha ) + dir_v * ( side ? -1.0 : 1.0 ) * ( 1.0 - sin( alpha ) ); p = aP + dir_u * cos( alpha ) + dir_v * ( aSide ? -1.0 : 1.0 ) * ( 1.0 - sin( alpha ) );
lc.Append( ( int ) p.x, ( int ) p.y ); lc.Append( ( int ) p.x, ( int ) p.y );
} }
return lc; return lc;
} }
VECTOR2I PNS_MEANDER_SHAPE::reflect( VECTOR2I p, const SEG& line ) VECTOR2I PNS_MEANDER_SHAPE::reflect( VECTOR2I p, const SEG& line )
{ {
typedef int64_t ecoord; typedef int64_t ecoord;
@ -219,53 +218,58 @@ VECTOR2I PNS_MEANDER_SHAPE::reflect( VECTOR2I p, const SEG& line )
ecoord t = d.Dot( p - line.A ); ecoord t = d.Dot( p - line.A );
VECTOR2I c, rv; VECTOR2I c, rv;
if(!l_squared) if( !l_squared )
c = p; c = p;
else { else {
c.x = line.A.x + rescale( t, (ecoord)d.x, l_squared ); c.x = line.A.x + rescale( t, (ecoord) d.x, l_squared );
c.y = line.A.y + rescale( t, (ecoord)d.y, l_squared ); c.y = line.A.y + rescale( t, (ecoord) d.y, l_squared );
} }
return 2 * c - p; return 2 * c - p;
} }
void PNS_MEANDER_SHAPE::start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir ) void PNS_MEANDER_SHAPE::start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir )
{ {
m_currentTarget = aTarget; m_currentTarget = aTarget;
m_currentTarget->Clear( ); m_currentTarget->Clear();
m_currentTarget->Append( aWhere ); m_currentTarget->Append( aWhere );
m_currentDir = aDir; m_currentDir = aDir;
m_currentPos = aWhere; m_currentPos = aWhere;
} }
void PNS_MEANDER_SHAPE::forward( int aLength ) void PNS_MEANDER_SHAPE::forward( int aLength )
{ {
m_currentPos += m_currentDir.Resize( aLength ); m_currentPos += m_currentDir.Resize( aLength );
m_currentTarget->Append( m_currentPos ); m_currentTarget->Append( m_currentPos );
} }
void PNS_MEANDER_SHAPE::turn( int aAngle ) void PNS_MEANDER_SHAPE::turn( int aAngle )
{ {
m_currentDir = m_currentDir.Rotate( (double)aAngle * M_PI / 180.0 ); m_currentDir = m_currentDir.Rotate( (double) aAngle * M_PI / 180.0 );
} }
void PNS_MEANDER_SHAPE::arc( int aRadius, bool aSide ) void PNS_MEANDER_SHAPE::arc( int aRadius, bool aSide )
{ {
if( aRadius <= 0 ) if( aRadius <= 0 )
{ {
turn ( aSide ? -90 : 90 ); turn( aSide ? -90 : 90 );
return; return;
} }
VECTOR2D dir = m_currentDir.Resize( (double) aRadius ); VECTOR2D dir = m_currentDir.Resize( (double) aRadius );
SHAPE_LINE_CHAIN arc = circleQuad( m_currentPos, dir, aSide ); SHAPE_LINE_CHAIN arc = circleQuad( m_currentPos, dir, aSide );
m_currentPos = arc.CPoint( -1 ); m_currentPos = arc.CPoint( -1 );
m_currentDir = dir.Rotate( aSide ? -M_PI/2.0 : M_PI/2.0 ); m_currentDir = dir.Rotate( aSide ? -M_PI / 2.0 : M_PI / 2.0 );
m_currentTarget->Append ( arc ); m_currentTarget->Append ( arc );
} }
void PNS_MEANDER_SHAPE::uShape ( int aSides, int aCorner, int aTop )
void PNS_MEANDER_SHAPE::uShape( int aSides, int aCorner, int aTop )
{ {
forward( aSides ); forward( aSides );
arc( aCorner, true ); arc( aCorner, true );
@ -274,35 +278,36 @@ void PNS_MEANDER_SHAPE::uShape ( int aSides, int aCorner, int aTop )
forward( aSides ); forward( aSides );
} }
SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir, bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset )
SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape( VECTOR2D aP, VECTOR2D aDir,
bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset )
{ {
const PNS_MEANDER_SETTINGS& st = Settings(); const PNS_MEANDER_SETTINGS& st = Settings();
int cr = cornerRadius(); int cr = cornerRadius();
int offset = aBaselineOffset; int offset = aBaselineOffset;
int spc = spacing(); int spc = spacing();
if (aSide) if( aSide )
offset *= -1; offset *= -1;
VECTOR2D dir_u_b ( aDir.Resize( offset ) ); VECTOR2D dir_u_b( aDir.Resize( offset ) );
VECTOR2D dir_v_b (dir_u_b.Perpendicular()); VECTOR2D dir_v_b( dir_u_b.Perpendicular() );
if (2 * cr > aAmpl) if( 2 * cr > aAmpl )
{ {
cr = aAmpl / 2; cr = aAmpl / 2;
} }
if (2 * cr > spc) if( 2 * cr > spc )
{ {
cr = spc / 2; cr = spc / 2;
} }
SHAPE_LINE_CHAIN lc; SHAPE_LINE_CHAIN lc;
start ( &lc, aP + dir_v_b, aDir ); start( &lc, aP + dir_v_b, aDir );
switch (aType) switch( aType )
{ {
case MT_EMPTY: case MT_EMPTY:
{ {
@ -313,7 +318,7 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
{ {
arc( cr - offset, false ); arc( cr - offset, false );
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr ); uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
forward( std::min(cr - offset, cr + offset) ); forward( std::min( cr - offset, cr + offset ) );
forward( std::abs( offset ) ); forward( std::abs( offset ) );
break; break;
@ -323,7 +328,7 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
{ {
start( &lc, aP - dir_u_b, aDir ); start( &lc, aP - dir_u_b, aDir );
turn ( 90 ); turn ( 90 );
forward( std::min(cr - offset, cr + offset) ); forward( std::min( cr - offset, cr + offset ) );
forward( std::abs( offset ) ); forward( std::abs( offset ) );
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr ); uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
arc( cr - offset, false ); arc( cr - offset, false );
@ -332,13 +337,11 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
case MT_TURN: case MT_TURN:
{ {
start( &lc, aP - dir_u_b, aDir ); start( &lc, aP - dir_u_b, aDir );
turn( 90 ); turn( 90 );
forward( std::abs( offset ) ); forward( std::abs( offset ) );
uShape ( aAmpl - cr, cr + offset, spc - 2 * cr ); uShape ( aAmpl - cr, cr + offset, spc - 2 * cr );
forward( std::abs( offset ) ); forward( std::abs( offset ) );
break; break;
} }
@ -347,7 +350,7 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
arc( cr - offset, false ); arc( cr - offset, false );
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr ); uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
arc( cr - offset, false ); arc( cr - offset, false );
lc.Append ( aP + dir_v_b + aDir.Resize ( 2 * st.m_spacing) ); lc.Append( aP + dir_v_b + aDir.Resize ( 2 * st.m_spacing ) );
break; break;
} }
@ -358,71 +361,76 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
if( aSide ) if( aSide )
{ {
SEG axis ( aP, aP + aDir ); SEG axis ( aP, aP + aDir );
for(int i = 0; i < lc.PointCount(); i++ )
lc.Point(i) = reflect ( lc.CPoint(i), axis ); for( int i = 0; i < lc.PointCount(); i++ )
lc.Point( i ) = reflect( lc.CPoint( i ), axis );
} }
return lc; return lc;
} }
bool PNS_MEANDERED_LINE::CheckSelfIntersections ( PNS_MEANDER_SHAPE *aShape, int aClearance )
{
for (int i = m_meanders.size() - 1; i >= 0; i--)
{
PNS_MEANDER_SHAPE *m = m_meanders[i];
if (m->Type() == MT_EMPTY || m->Type() == MT_CORNER ) bool PNS_MEANDERED_LINE::CheckSelfIntersections( PNS_MEANDER_SHAPE* aShape, int aClearance )
{
for( int i = m_meanders.size() - 1; i >= 0; i-- )
{
PNS_MEANDER_SHAPE* m = m_meanders[i];
if( m->Type() == MT_EMPTY || m->Type() == MT_CORNER )
continue; continue;
const SEG& b1 = aShape->BaseSegment(); const SEG& b1 = aShape->BaseSegment();
const SEG& b2 = m->BaseSegment(); const SEG& b2 = m->BaseSegment();
if (b1.ApproxParallel(b2)) if( b1.ApproxParallel( b2 ) )
continue; continue;
int n = m->CLine(0).SegmentCount(); int n = m->CLine( 0 ).SegmentCount();
for (int j = n - 1; j >= 0; j--) for( int j = n - 1; j >= 0; j-- )
if ( aShape->CLine(0).Collide ( m->CLine(0).CSegment(j), aClearance ) ) if( aShape->CLine( 0 ).Collide ( m->CLine( 0 ) .CSegment( j ), aClearance ) )
return false; return false;
} }
return true; return true;
} }
bool PNS_MEANDER_SHAPE::Fit ( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide )
bool PNS_MEANDER_SHAPE::Fit( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide )
{ {
const PNS_MEANDER_SETTINGS& st = Settings(); const PNS_MEANDER_SETTINGS& st = Settings();
bool checkMode = false; bool checkMode = false;
PNS_MEANDER_TYPE prim1, prim2; PNS_MEANDER_TYPE prim1, prim2;
if(aType == MT_CHECK_START) if( aType == MT_CHECK_START )
{ {
prim1 = MT_START; prim1 = MT_START;
prim2 = MT_TURN; prim2 = MT_TURN;
checkMode = true; checkMode = true;
} else if (aType == MT_CHECK_FINISH ) { }
else if( aType == MT_CHECK_FINISH )
{
prim1 = MT_TURN; prim1 = MT_TURN;
prim2 = MT_FINISH; prim2 = MT_FINISH;
checkMode = true; checkMode = true;
} }
if(checkMode) if( checkMode )
{ {
PNS_MEANDER_SHAPE m1 ( m_placer, m_width, m_dual ); PNS_MEANDER_SHAPE m1( m_placer, m_width, m_dual );
PNS_MEANDER_SHAPE m2 ( m_placer, m_width, m_dual ); PNS_MEANDER_SHAPE m2( m_placer, m_width, m_dual );
m1.SetBaselineOffset ( m_baselineOffset ); m1.SetBaselineOffset( m_baselineOffset );
m2.SetBaselineOffset ( m_baselineOffset ); m2.SetBaselineOffset( m_baselineOffset );
bool c1 = m1.Fit ( prim1, aSeg, aP, aSide ); bool c1 = m1.Fit( prim1, aSeg, aP, aSide );
bool c2 = false; bool c2 = false;
if(c1) if( c1 )
c2 = m2.Fit ( prim2, aSeg, m1.End(), !aSide ); c2 = m2.Fit( prim2, aSeg, m1.End(), !aSide );
if(c1 && c2) if( c1 && c2 )
{ {
m_type = prim1; m_type = prim1;
m_shapes[0] = m1.m_shapes[0]; m_shapes[0] = m1.m_shapes[0];
@ -434,63 +442,64 @@ bool PNS_MEANDER_SHAPE::Fit ( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VEC
m_dual = m1.m_dual; m_dual = m1.m_dual;
m_baseSeg = m1.m_baseSeg; m_baseSeg = m1.m_baseSeg;
m_baseIndex = m1.m_baseIndex; m_baseIndex = m1.m_baseIndex;
updateBaseSegment (); updateBaseSegment();
m_baselineOffset = m1.m_baselineOffset; m_baselineOffset = m1.m_baselineOffset;
return true; return true;
} else } else
return false; return false;
} }
int minAmpl = st.m_minAmplitude; int minAmpl = st.m_minAmplitude;
int maxAmpl = st.m_maxAmplitude; int maxAmpl = st.m_maxAmplitude;
if (m_dual) if( m_dual )
{ {
minAmpl = std::max( minAmpl, 2 * std::abs(m_baselineOffset) ); minAmpl = std::max( minAmpl, 2 * std::abs( m_baselineOffset ) );
maxAmpl = std::max( maxAmpl, 2 * std::abs(m_baselineOffset) ); maxAmpl = std::max( maxAmpl, 2 * std::abs( m_baselineOffset ) );
} }
for(int ampl = maxAmpl; ampl >= minAmpl; ampl -= st.m_step) for( int ampl = maxAmpl; ampl >= minAmpl; ampl -= st.m_step )
{ {
if (m_dual) if( m_dual )
{ {
m_shapes[0] = genMeanderShape ( aP, aSeg.B - aSeg.A, aSide, aType, ampl, m_baselineOffset ); m_shapes[0] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, m_baselineOffset );
m_shapes[1] = genMeanderShape ( aP, aSeg.B - aSeg.A, aSide, aType, ampl, -m_baselineOffset ); m_shapes[1] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, -m_baselineOffset );
} else { }
m_shapes[0] = genMeanderShape ( aP, aSeg.B - aSeg.A, aSide, aType, ampl, 0); else
{
m_shapes[0] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, 0 );
} }
m_type = aType; m_type = aType;
m_baseSeg =aSeg; m_baseSeg = aSeg;
m_p0 = aP; m_p0 = aP;
m_side = aSide; m_side = aSide;
m_amplitude = ampl; m_amplitude = ampl;
updateBaseSegment(); updateBaseSegment();
if( m_placer->CheckFit ( this ) ) if( m_placer->CheckFit( this ) )
return true; return true;
} }
return false; return false;
} }
void PNS_MEANDER_SHAPE::Recalculate ( )
void PNS_MEANDER_SHAPE::Recalculate()
{ {
m_shapes[0] = genMeanderShape( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, m_dual ? m_baselineOffset : 0 );
m_shapes[0] = genMeanderShape ( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, m_dual ? m_baselineOffset : 0); if( m_dual )
m_shapes[1] = genMeanderShape( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, -m_baselineOffset );
if (m_dual)
m_shapes[1] = genMeanderShape ( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, -m_baselineOffset );
updateBaseSegment(); updateBaseSegment();
} }
void PNS_MEANDER_SHAPE::Resize ( int aAmpl )
void PNS_MEANDER_SHAPE::Resize( int aAmpl )
{ {
if(aAmpl < 0) if( aAmpl < 0 )
return; return;
m_amplitude = aAmpl; m_amplitude = aAmpl;
@ -498,6 +507,7 @@ void PNS_MEANDER_SHAPE::Resize ( int aAmpl )
Recalculate(); Recalculate();
} }
void PNS_MEANDER_SHAPE::MakeEmpty() void PNS_MEANDER_SHAPE::MakeEmpty()
{ {
updateBaseSegment(); updateBaseSegment();
@ -506,47 +516,46 @@ void PNS_MEANDER_SHAPE::MakeEmpty()
m_type = MT_EMPTY; m_type = MT_EMPTY;
m_shapes[0] = genMeanderShape ( m_p0, dir, m_side, m_type, 0, m_dual ? m_baselineOffset : 0); m_shapes[0] = genMeanderShape ( m_p0, dir, m_side, m_type, 0, m_dual ? m_baselineOffset : 0 );
if(m_dual)
m_shapes[1] = genMeanderShape ( m_p0, dir, m_side, m_type, 0, -m_baselineOffset );
if( m_dual )
m_shapes[1] = genMeanderShape( m_p0, dir, m_side, m_type, 0, -m_baselineOffset );
} }
void PNS_MEANDERED_LINE::AddCorner ( const VECTOR2I& aA, const VECTOR2I& aB ) void PNS_MEANDERED_LINE::AddCorner( const VECTOR2I& aA, const VECTOR2I& aB )
{ {
PNS_MEANDER_SHAPE *m = new PNS_MEANDER_SHAPE ( m_placer, m_width, m_dual ); PNS_MEANDER_SHAPE* m = new PNS_MEANDER_SHAPE( m_placer, m_width, m_dual );
m->MakeCorner ( aA, aB ); m->MakeCorner( aA, aB );
m_last = aA; m_last = aA;
m_meanders.push_back( m ); m_meanders.push_back( m );
} }
void PNS_MEANDER_SHAPE::MakeCorner ( VECTOR2I aP1, VECTOR2I aP2 )
void PNS_MEANDER_SHAPE::MakeCorner( VECTOR2I aP1, VECTOR2I aP2 )
{ {
SetType( MT_CORNER ); SetType( MT_CORNER );
m_shapes[ 0 ].Clear( ); m_shapes[0].Clear();
m_shapes[ 1 ].Clear( ); m_shapes[1].Clear();
m_shapes[ 0 ].Append( aP1 ); m_shapes[0].Append( aP1 );
m_shapes[ 1 ].Append( aP2 ); m_shapes[1].Append( aP2 );
m_clippedBaseSeg.A = aP1; m_clippedBaseSeg.A = aP1;
m_clippedBaseSeg.B = aP1; m_clippedBaseSeg.B = aP1;
} }
void PNS_MEANDERED_LINE::AddMeander ( PNS_MEANDER_SHAPE *aShape )
void PNS_MEANDERED_LINE::AddMeander( PNS_MEANDER_SHAPE* aShape )
{ {
m_last = aShape->BaseSegment( ).B; m_last = aShape->BaseSegment().B;
m_meanders.push_back( aShape ); m_meanders.push_back( aShape );
} }
void PNS_MEANDERED_LINE::Clear( ) void PNS_MEANDERED_LINE::Clear()
{ {
BOOST_FOREACH( PNS_MEANDER_SHAPE *m, m_meanders ) BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_meanders )
{ {
delete m; delete m;
} }
@ -554,16 +563,19 @@ void PNS_MEANDERED_LINE::Clear( )
m_meanders.clear( ); m_meanders.clear( );
} }
int PNS_MEANDER_SHAPE::BaselineLength( ) const
int PNS_MEANDER_SHAPE::BaselineLength() const
{ {
return m_clippedBaseSeg.Length( ); return m_clippedBaseSeg.Length();
} }
int PNS_MEANDER_SHAPE::MaxTunableLength( ) const
int PNS_MEANDER_SHAPE::MaxTunableLength() const
{ {
return CLine( 0 ).Length( ); return CLine( 0 ).Length();
} }
void PNS_MEANDER_SHAPE::updateBaseSegment( ) void PNS_MEANDER_SHAPE::updateBaseSegment( )
{ {
if( m_dual ) if( m_dual )
@ -573,7 +585,9 @@ void PNS_MEANDER_SHAPE::updateBaseSegment( )
m_clippedBaseSeg.A = m_baseSeg.LineProject( midpA ); m_clippedBaseSeg.A = m_baseSeg.LineProject( midpA );
m_clippedBaseSeg.B = m_baseSeg.LineProject( midpB ); m_clippedBaseSeg.B = m_baseSeg.LineProject( midpB );
} else { }
else
{
m_clippedBaseSeg.A = m_baseSeg.LineProject( CLine( 0 ).CPoint( 0 ) ); m_clippedBaseSeg.A = m_baseSeg.LineProject( CLine( 0 ).CPoint( 0 ) );
m_clippedBaseSeg.B = m_baseSeg.LineProject( CLine( 0 ).CPoint( -1 ) ); m_clippedBaseSeg.B = m_baseSeg.LineProject( CLine( 0 ).CPoint( -1 ) );
} }

View File

@ -55,7 +55,7 @@ public:
CHAMFER // chamfered (45 degree segment) CHAMFER // chamfered (45 degree segment)
}; };
PNS_MEANDER_SETTINGS () PNS_MEANDER_SETTINGS()
{ {
m_minAmplitude = 100000; m_minAmplitude = 100000;
m_maxAmplitude = 1000000; m_maxAmplitude = 1000000;
@ -65,7 +65,7 @@ public:
m_targetSkew = 0; m_targetSkew = 0;
m_cornerType = ROUND; m_cornerType = ROUND;
m_cornerRadiusPercentage = 100; m_cornerRadiusPercentage = 100;
m_lengthTollerance = 100000; m_lengthTolerance = 100000;
m_cornerArcSegments = 8; m_cornerArcSegments = 8;
} }
@ -84,7 +84,7 @@ public:
///> rounding percentage (0 - 100) ///> rounding percentage (0 - 100)
int m_cornerRadiusPercentage; int m_cornerRadiusPercentage;
///> allowable tuning error ///> allowable tuning error
int m_lengthTollerance; int m_lengthTolerance;
///> number of line segments for arc approximation ///> number of line segments for arc approximation
int m_cornerArcSegments; int m_cornerArcSegments;
///> target skew value for diff pair de-skewing ///> target skew value for diff pair de-skewing
@ -100,8 +100,7 @@ class PNS_MEANDERED_LINE;
*/ */
class PNS_MEANDER_SHAPE class PNS_MEANDER_SHAPE
{ {
public: public:
/** /**
* Constructor * Constructor
* *
@ -116,7 +115,6 @@ class PNS_MEANDER_SHAPE
m_width( aWidth ), m_width( aWidth ),
m_baselineOffset( 0 ) m_baselineOffset( 0 )
{ {
} }
/** /**
@ -134,7 +132,7 @@ class PNS_MEANDER_SHAPE
* *
* @return the type of the meander. * @return the type of the meander.
*/ */
PNS_MEANDER_TYPE Type( ) const PNS_MEANDER_TYPE Type() const
{ {
return m_type; return m_type;
} }
@ -154,7 +152,7 @@ class PNS_MEANDER_SHAPE
* *
* @return auxillary index of the segment being meandered in its original PNS_LINE. * @return auxillary index of the segment being meandered in its original PNS_LINE.
*/ */
int BaseIndex( ) const int BaseIndex() const
{ {
return m_baseIndex; return m_baseIndex;
} }
@ -164,7 +162,7 @@ class PNS_MEANDER_SHAPE
* *
* @return the amplitude of the meander shape. * @return the amplitude of the meander shape.
*/ */
int Amplitude( ) const int Amplitude() const
{ {
return m_amplitude; return m_amplitude;
} }
@ -177,7 +175,7 @@ class PNS_MEANDER_SHAPE
* @param aP1 corner point of the 1st line * @param aP1 corner point of the 1st line
* @param aP2 corner point of the 2nd line (if m_dual == true) * @param aP2 corner point of the 2nd line (if m_dual == true)
*/ */
void MakeCorner( VECTOR2I aP1, VECTOR2I aP2 = VECTOR2I ( 0, 0 ) ); void MakeCorner( VECTOR2I aP1, VECTOR2I aP2 = VECTOR2I( 0, 0 ) );
/** /**
* Function Resize() * Function Resize()
@ -193,14 +191,14 @@ class PNS_MEANDER_SHAPE
* *
* Recalculates the line chain representing the meanders's shape. * Recalculates the line chain representing the meanders's shape.
*/ */
void Recalculate ( ); void Recalculate();
/** /**
* Function IsDual() * Function IsDual()
* *
* @return true if the shape represents 2 parallel lines (diff pair). * @return true if the shape represents 2 parallel lines (diff pair).
*/ */
bool IsDual( ) const bool IsDual() const
{ {
return m_dual; return m_dual;
} }
@ -210,7 +208,7 @@ class PNS_MEANDER_SHAPE
* *
* @return true if the meander is to the right of its base segment. * @return true if the meander is to the right of its base segment.
*/ */
bool Side( ) const bool Side() const
{ {
return m_side; return m_side;
} }
@ -220,7 +218,7 @@ class PNS_MEANDER_SHAPE
* *
* @return end vertex of the base segment of the meander shape. * @return end vertex of the base segment of the meander shape.
*/ */
VECTOR2I End( ) const VECTOR2I End() const
{ {
return m_clippedBaseSeg.B; return m_clippedBaseSeg.B;
} }
@ -232,7 +230,7 @@ class PNS_MEANDER_SHAPE
*/ */
const SHAPE_LINE_CHAIN& CLine( int aShape ) const const SHAPE_LINE_CHAIN& CLine( int aShape ) const
{ {
return m_shapes[ aShape ]; return m_shapes[aShape];
} }
/** /**
@ -241,7 +239,7 @@ class PNS_MEANDER_SHAPE
* Replaces the meander with straight bypass line(s), effectively * Replaces the meander with straight bypass line(s), effectively
* clearing it. * clearing it.
*/ */
void MakeEmpty( ); void MakeEmpty();
/** /**
* Function Fit() * Function Fit()
@ -262,7 +260,7 @@ class PNS_MEANDER_SHAPE
* Returns the base segment the meadner was fitted to. * Returns the base segment the meadner was fitted to.
* @return the base segment. * @return the base segment.
*/ */
const SEG& BaseSegment( ) const const SEG& BaseSegment() const
{ {
return m_clippedBaseSeg; return m_clippedBaseSeg;
} }
@ -271,23 +269,23 @@ class PNS_MEANDER_SHAPE
* Function BaselineLength() * Function BaselineLength()
* *
* @return length of the base segment for the meander (i.e. * @return length of the base segment for the meander (i.e.
* the minimim tuned length. * the minimum tuned length.
*/ */
int BaselineLength( ) const; int BaselineLength() const;
/** /**
* Function MaxTunableLength() * Function MaxTunableLength()
* *
* @return the length of the fitted line chain. * @return the length of the fitted line chain.
*/ */
int MaxTunableLength( ) const; int MaxTunableLength() const;
/** /**
* Function Settings() * Function Settings()
* *
* @return the current meandering settings. * @return the current meandering settings.
*/ */
const PNS_MEANDER_SETTINGS& Settings( ) const; const PNS_MEANDER_SETTINGS& Settings() const;
/** /**
* Function Width() * Function Width()
@ -306,48 +304,48 @@ class PNS_MEANDER_SHAPE
* line. Used for dual menaders (diff pair) only. * line. Used for dual menaders (diff pair) only.
* @param aOffset the offset * @param aOffset the offset
*/ */
void SetBaselineOffset ( int aOffset ) void SetBaselineOffset( int aOffset )
{ {
m_baselineOffset = aOffset; m_baselineOffset = aOffset;
} }
private: private:
friend class PNS_MEANDERED_LINE; friend class PNS_MEANDERED_LINE;
///> starts turtle drawing ///> starts turtle drawing
void start ( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir ); void start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir );
///> moves turtle forward by aLength ///> moves turtle forward by aLength
void forward ( int aLength ); void forward( int aLength );
///> turns the turtle by aAngle ///> turns the turtle by aAngle
void turn ( int aAngle ); void turn( int aAngle );
///> tells the turtle to draw an arc of given radius and turn direction ///> tells the turtle to draw an arc of given radius and turn direction
void arc ( int aRadius, bool aSide ); void arc( int aRadius, bool aSide );
///> tells the turtle to draw an U-like shape ///> tells the turtle to draw an U-like shape
void uShape ( int aSides, int aCorner, int aTop ); void uShape( int aSides, int aCorner, int aTop );
///> generates a 90-degree circular arc ///> generates a 90-degree circular arc
SHAPE_LINE_CHAIN circleQuad ( VECTOR2D aP, VECTOR2D aDir, bool side ); SHAPE_LINE_CHAIN circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide );
///> reflects a point onto other side of a given segment ///> reflects a point onto other side of a given segment
VECTOR2I reflect ( VECTOR2I p, const SEG& line ); VECTOR2I reflect( VECTOR2I aP, const SEG& aLine );
///> produces a meander shape of given type ///> produces a meander shape of given type
SHAPE_LINE_CHAIN genMeanderShape ( VECTOR2D aP, VECTOR2D aDir, bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset = 0); SHAPE_LINE_CHAIN genMeanderShape( VECTOR2D aP, VECTOR2D aDir, bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset = 0 );
///> recalculates the clipped baseline after the parameters of ///> recalculates the clipped baseline after the parameters of
///> the meander have been changed. ///> the meander have been changed.
void updateBaseSegment(); void updateBaseSegment();
///> returns sanitized corner radius value ///> returns sanitized corner radius value
int cornerRadius ( ) const; int cornerRadius() const;
///> returns sanitized spacing value ///> returns sanitized spacing value
int spacing ( ) const; int spacing() const;
///> the type ///> the type
PNS_MEANDER_TYPE m_type; PNS_MEANDER_TYPE m_type;
///> the placer that placed this meander ///> the placer that placed this meander
PNS_MEANDER_PLACER_BASE *m_placer; PNS_MEANDER_PLACER_BASE* m_placer;
///> dual or single line ///> dual or single line
bool m_dual; bool m_dual;
///> width of the line ///> width of the line
@ -384,10 +382,9 @@ class PNS_MEANDER_SHAPE
*/ */
class PNS_MEANDERED_LINE class PNS_MEANDERED_LINE
{ {
public: public:
PNS_MEANDERED_LINE( ) PNS_MEANDERED_LINE()
{ {
} }
/** /**
@ -396,11 +393,10 @@ class PNS_MEANDERED_LINE
* @param aPlacer the meander placer instance * @param aPlacer the meander placer instance
* @param aIsDual when true, the meanders are generated for two coupled lines * @param aIsDual when true, the meanders are generated for two coupled lines
*/ */
PNS_MEANDERED_LINE( PNS_MEANDER_PLACER_BASE *aPlacer, bool aIsDual = false ) : PNS_MEANDERED_LINE( PNS_MEANDER_PLACER_BASE* aPlacer, bool aIsDual = false ) :
m_placer( aPlacer ), m_placer( aPlacer ),
m_dual( aIsDual ) m_dual( aIsDual )
{ {
} }
/** /**
@ -419,14 +415,14 @@ class PNS_MEANDERED_LINE
* Adds a new meander shape the the meandered line. * Adds a new meander shape the the meandered line.
* @param aShape the meander shape to add * @param aShape the meander shape to add
*/ */
void AddMeander( PNS_MEANDER_SHAPE *aShape ); void AddMeander( PNS_MEANDER_SHAPE* aShape );
/** /**
* Function Clear() * Function Clear()
* *
* Clears the line geometry, removing all corners and meanders. * Clears the line geometry, removing all corners and meanders.
*/ */
void Clear( ); void Clear();
/** /**
* Function SetWidth() * Function SetWidth()
@ -459,12 +455,11 @@ class PNS_MEANDERED_LINE
* *
* @return set of meander shapes for this line * @return set of meander shapes for this line
*/ */
std::vector<PNS_MEANDER_SHAPE*> & Meanders() std::vector<PNS_MEANDER_SHAPE*>& Meanders()
{ {
return m_meanders; return m_meanders;
} }
/** /**
* Function CheckSelfIntersections() * Function CheckSelfIntersections()
* *
@ -474,7 +469,7 @@ class PNS_MEANDERED_LINE
* @param aClearance clearance value * @param aClearance clearance value
* @return true, if the meander shape is not colliding * @return true, if the meander shape is not colliding
*/ */
bool CheckSelfIntersections ( PNS_MEANDER_SHAPE *aShape, int aClearance ); bool CheckSelfIntersections ( PNS_MEANDER_SHAPE* aShape, int aClearance );
/** /**
* Function Settings() * Function Settings()
@ -483,12 +478,11 @@ class PNS_MEANDERED_LINE
*/ */
const PNS_MEANDER_SETTINGS& Settings() const; const PNS_MEANDER_SETTINGS& Settings() const;
private: private:
VECTOR2I m_last; VECTOR2I m_last;
PNS_MEANDER_PLACER_BASE *m_placer; PNS_MEANDER_PLACER_BASE* m_placer;
std::vector<PNS_MEANDER_SHAPE *> m_meanders; std::vector<PNS_MEANDER_SHAPE*> m_meanders;
bool m_dual; bool m_dual;
int m_width; int m_width;

View File

@ -33,7 +33,7 @@
PNS_MEANDER_PLACER::PNS_MEANDER_PLACER( PNS_ROUTER* aRouter ) : PNS_MEANDER_PLACER::PNS_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
PNS_MEANDER_PLACER_BASE ( aRouter ) PNS_MEANDER_PLACER_BASE( aRouter )
{ {
m_world = NULL; m_world = NULL;
m_currentNode = NULL; m_currentNode = NULL;
@ -41,11 +41,11 @@ PNS_MEANDER_PLACER::PNS_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
} }
PNS_MEANDER_PLACER::~PNS_MEANDER_PLACER( ) PNS_MEANDER_PLACER::~PNS_MEANDER_PLACER()
{ {
} }
PNS_NODE* PNS_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const PNS_NODE* PNS_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
{ {
if( !m_currentNode ) if( !m_currentNode )
@ -54,25 +54,26 @@ PNS_NODE* PNS_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
return m_currentNode; return m_currentNode;
} }
bool PNS_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) bool PNS_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
VECTOR2I p; VECTOR2I p;
if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) ) if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
{ {
Router( )->SetFailureReason( _( "Please select a track whose length you want to tune." ) ); Router()->SetFailureReason( _( "Please select a track whose length you want to tune." ) );
return false; return false;
} }
m_initialSegment = static_cast<PNS_SEGMENT *>( aStartItem ); m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
p = m_initialSegment->Seg( ).NearestPoint( aP ); p = m_initialSegment->Seg().NearestPoint( aP );
m_originLine = NULL; m_originLine = NULL;
m_currentNode = NULL; m_currentNode = NULL;
m_currentStart = p; m_currentStart = p;
m_world = Router( )->GetWorld( )->Branch( ); m_world = Router()->GetWorld()->Branch();
m_originLine = m_world->AssembleLine( m_initialSegment ); m_originLine = m_world->AssembleLine( m_initialSegment );
PNS_TOPOLOGY topo( m_world ); PNS_TOPOLOGY topo( m_world );
@ -80,42 +81,44 @@ bool PNS_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
m_world->Remove( m_originLine ); m_world->Remove( m_originLine );
m_currentWidth = m_originLine->Width( ); m_currentWidth = m_originLine->Width();
m_currentEnd = VECTOR2I( 0, 0 ); m_currentEnd = VECTOR2I( 0, 0 );
return true; return true;
} }
int PNS_MEANDER_PLACER::origPathLength( ) const int PNS_MEANDER_PLACER::origPathLength() const
{ {
int total = 0; int total = 0;
BOOST_FOREACH( const PNS_ITEM *item, m_tunedPath.CItems( ) ) BOOST_FOREACH( const PNS_ITEM* item, m_tunedPath.CItems() )
{ {
if( const PNS_LINE *l = dyn_cast<const PNS_LINE *>( item ) ) if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
{ {
total += l->CLine( ).Length( ); total += l->CLine().Length();
} }
} }
return total; return total;
} }
bool PNS_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem ) bool PNS_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
return doMove ( aP, aEndItem, m_settings.m_targetLength ); return doMove( aP, aEndItem, m_settings.m_targetLength );
} }
bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength ) bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength )
{ {
SHAPE_LINE_CHAIN pre, tuned, post; SHAPE_LINE_CHAIN pre, tuned, post;
if(m_currentNode) if( m_currentNode )
delete m_currentNode; delete m_currentNode;
m_currentNode = m_world->Branch( ); m_currentNode = m_world->Branch();
cutTunedLine ( m_originLine->CLine( ), m_currentStart, aP, pre, tuned, post ); cutTunedLine( m_originLine->CLine(), m_currentStart, aP, pre, tuned, post );
m_result = PNS_MEANDERED_LINE( this, false ); m_result = PNS_MEANDERED_LINE( this, false );
m_result.SetWidth( m_originLine->Width() ); m_result.SetWidth( m_originLine->Width() );
@ -129,42 +132,42 @@ bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTa
m_result.AddCorner( s.B ); m_result.AddCorner( s.B );
} }
int lineLen = origPathLength( ); int lineLen = origPathLength();
m_lastLength = lineLen; m_lastLength = lineLen;
m_lastStatus = TUNED; m_lastStatus = TUNED;
if( compareWithTollerance ( lineLen, aTargetLength, m_settings.m_lengthTollerance ) > 0 ) if( compareWithTolerance( lineLen, aTargetLength, m_settings.m_lengthTolerance ) > 0 )
{ {
m_lastStatus = TOO_LONG; m_lastStatus = TOO_LONG;
} else { } else {
m_lastLength = lineLen - tuned.Length( ); m_lastLength = lineLen - tuned.Length();
tuneLineLength( m_result, aTargetLength - lineLen ); tuneLineLength( m_result, aTargetLength - lineLen );
} }
BOOST_FOREACH ( const PNS_ITEM *item, m_tunedPath.CItems( ) ) BOOST_FOREACH ( const PNS_ITEM* item, m_tunedPath.CItems() )
{ {
if ( const PNS_LINE *l = dyn_cast<const PNS_LINE *>( item ) ) if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
{ {
Router( )->DisplayDebugLine( l->CLine( ), 5, 10000 ); Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
} }
} }
if (m_lastStatus != TOO_LONG) if( m_lastStatus != TOO_LONG )
{ {
tuned.Clear( ); tuned.Clear();
BOOST_FOREACH ( PNS_MEANDER_SHAPE *m, m_result.Meanders() ) BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_result.Meanders() )
{ {
if( m->Type() != MT_EMPTY ) if( m->Type() != MT_EMPTY )
{ {
tuned.Append ( m->CLine(0) ); tuned.Append ( m->CLine( 0 ) );
} }
} }
m_lastLength += tuned.Length( ); m_lastLength += tuned.Length();
int comp = compareWithTollerance( m_lastLength - aTargetLength, 0, m_settings.m_lengthTollerance ); int comp = compareWithTolerance( m_lastLength - aTargetLength, 0, m_settings.m_lengthTolerance );
if( comp > 0 ) if( comp > 0 )
m_lastStatus = TOO_LONG; m_lastStatus = TOO_LONG;
@ -172,14 +175,13 @@ bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTa
m_lastStatus = TOO_SHORT; m_lastStatus = TOO_SHORT;
else else
m_lastStatus = TUNED; m_lastStatus = TUNED;
} }
m_finalShape.Clear( ); m_finalShape.Clear();
m_finalShape.Append( pre ); m_finalShape.Append( pre );
m_finalShape.Append( tuned ); m_finalShape.Append( tuned );
m_finalShape.Append( post ); m_finalShape.Append( post );
m_finalShape.Simplify( ); m_finalShape.Simplify();
return true; return true;
} }
@ -188,20 +190,21 @@ bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTa
bool PNS_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) bool PNS_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
m_currentTrace = PNS_LINE( *m_originLine, m_finalShape ); m_currentTrace = PNS_LINE( *m_originLine, m_finalShape );
m_currentNode->Add ( &m_currentTrace ); m_currentNode->Add( &m_currentTrace );
Router( )->CommitRouting( m_currentNode ); Router()->CommitRouting( m_currentNode );
return true; return true;
} }
bool PNS_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE *aShape )
bool PNS_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE* aShape )
{ {
PNS_LINE l( *m_originLine, aShape->CLine( 0 ) ); PNS_LINE l( *m_originLine, aShape->CLine( 0 ) );
if( m_currentNode->CheckColliding( &l ) ) if( m_currentNode->CheckColliding( &l ) )
return false; return false;
int w = aShape->Width( ); int w = aShape->Width();
int clearance = w + m_settings.m_spacing; int clearance = w + m_settings.m_spacing;
return m_result.CheckSelfIntersections( aShape, clearance ); return m_result.CheckSelfIntersections( aShape, clearance );
@ -214,23 +217,26 @@ const PNS_ITEMSET PNS_MEANDER_PLACER::Traces()
return PNS_ITEMSET( &m_currentTrace ); return PNS_ITEMSET( &m_currentTrace );
} }
const VECTOR2I& PNS_MEANDER_PLACER::CurrentEnd() const const VECTOR2I& PNS_MEANDER_PLACER::CurrentEnd() const
{ {
return m_currentEnd; return m_currentEnd;
} }
int PNS_MEANDER_PLACER::CurrentNet() const int PNS_MEANDER_PLACER::CurrentNet() const
{ {
return m_initialSegment->Net( ); return m_initialSegment->Net();
} }
int PNS_MEANDER_PLACER::CurrentLayer() const int PNS_MEANDER_PLACER::CurrentLayer() const
{ {
return m_initialSegment->Layers( ).Start( ); return m_initialSegment->Layers().Start();
} }
const wxString PNS_MEANDER_PLACER::TuningInfo( ) const const wxString PNS_MEANDER_PLACER::TuningInfo() const
{ {
wxString status; wxString status;
@ -240,10 +246,10 @@ const wxString PNS_MEANDER_PLACER::TuningInfo( ) const
status = _( "Too long: " ); status = _( "Too long: " );
break; break;
case TOO_SHORT: case TOO_SHORT:
status = _(" Too short: " ); status = _( "Too short: " );
break; break;
case TUNED: case TUNED:
status = _(" Tuned: " ); status = _( "Tuned: " );
break; break;
default: default:
return _( "?" ); return _( "?" );
@ -256,7 +262,8 @@ const wxString PNS_MEANDER_PLACER::TuningInfo( ) const
return status; return status;
} }
PNS_MEANDER_PLACER::TUNING_STATUS PNS_MEANDER_PLACER::TuningStatus( ) const
PNS_MEANDER_PLACER::TUNING_STATUS PNS_MEANDER_PLACER::TuningStatus() const
{ {
return m_lastStatus; return m_lastStatus;
} }

View File

@ -87,9 +87,9 @@ protected:
bool doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength ); bool doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength );
void setWorld ( PNS_NODE* aWorld ); void setWorld( PNS_NODE* aWorld );
virtual int origPathLength () const; virtual int origPathLength() const;
///> pointer to world to search colliding items ///> pointer to world to search colliding items
PNS_NODE* m_world; PNS_NODE* m_world;
@ -106,7 +106,7 @@ protected:
SHAPE_LINE_CHAIN m_finalShape; SHAPE_LINE_CHAIN m_finalShape;
PNS_MEANDERED_LINE m_result; PNS_MEANDERED_LINE m_result;
PNS_SEGMENT *m_initialSegment; PNS_SEGMENT* m_initialSegment;
int m_lastLength; int m_lastLength;
TUNING_STATUS m_lastStatus; TUNING_STATUS m_lastStatus;

View File

@ -25,13 +25,13 @@
PNS_MEANDER_PLACER_BASE::PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter ) : PNS_MEANDER_PLACER_BASE::PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter ) :
PNS_PLACEMENT_ALGO( aRouter ) PNS_PLACEMENT_ALGO( aRouter )
{ {
}
};
PNS_MEANDER_PLACER_BASE::~PNS_MEANDER_PLACER_BASE( ) PNS_MEANDER_PLACER_BASE::~PNS_MEANDER_PLACER_BASE()
{ {
}
};
void PNS_MEANDER_PLACER_BASE::AmplitudeStep( int aSign ) void PNS_MEANDER_PLACER_BASE::AmplitudeStep( int aSign )
{ {
@ -41,6 +41,7 @@ void PNS_MEANDER_PLACER_BASE::AmplitudeStep( int aSign )
m_settings.m_maxAmplitude = a; m_settings.m_maxAmplitude = a;
} }
void PNS_MEANDER_PLACER_BASE::SpacingStep( int aSign ) void PNS_MEANDER_PLACER_BASE::SpacingStep( int aSign )
{ {
int s = m_settings.m_spacing + aSign * m_settings.m_step; int s = m_settings.m_spacing + aSign * m_settings.m_step;
@ -49,11 +50,13 @@ void PNS_MEANDER_PLACER_BASE::SpacingStep( int aSign )
m_settings.m_spacing = s; m_settings.m_spacing = s;
} }
void PNS_MEANDER_PLACER_BASE::UpdateSettings( const PNS_MEANDER_SETTINGS& aSettings ) void PNS_MEANDER_PLACER_BASE::UpdateSettings( const PNS_MEANDER_SETTINGS& aSettings )
{ {
m_settings = aSettings; m_settings = aSettings;
} }
void PNS_MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin, void PNS_MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
const VECTOR2I& aTuneStart, const VECTOR2I& aTuneStart,
const VECTOR2I& aCursorPos, const VECTOR2I& aCursorPos,
@ -73,7 +76,7 @@ void PNS_MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
if( i_start > i_end ) if( i_start > i_end )
{ {
l = l.Reverse( ); l = l.Reverse();
i_start = l.Find( m ); i_start = l.Find( m );
i_end = l.Find( n ); i_end = l.Find( n );
} }
@ -81,34 +84,35 @@ void PNS_MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
aPre = l.Slice( 0, i_start ); aPre = l.Slice( 0, i_start );
aPost = l.Slice( i_end, -1 ); aPost = l.Slice( i_end, -1 );
aTuned = l.Slice( i_start, i_end ); aTuned = l.Slice( i_start, i_end );
aTuned.Simplify( ); aTuned.Simplify();
} }
void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation ) void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation )
{ {
int remaining = aElongation; int remaining = aElongation;
bool finished = false; bool finished = false;
BOOST_FOREACH(PNS_MEANDER_SHAPE *m, aTuned.Meanders()) BOOST_FOREACH( PNS_MEANDER_SHAPE* m, aTuned.Meanders() )
{ {
if(m->Type() != MT_CORNER ) if( m->Type() != MT_CORNER )
{ {
if(remaining >= 0) if( remaining >= 0 )
remaining -= m->MaxTunableLength() - m->BaselineLength(); remaining -= m->MaxTunableLength() - m->BaselineLength();
if(remaining < 0) if( remaining < 0 )
{ {
if(!finished) if( !finished )
{ {
PNS_MEANDER_TYPE newType; PNS_MEANDER_TYPE newType;
if ( m->Type() == MT_START || m->Type() == MT_SINGLE) if( m->Type() == MT_START || m->Type() == MT_SINGLE )
newType = MT_SINGLE; newType = MT_SINGLE;
else else
newType = MT_FINISH; newType = MT_FINISH;
m->SetType ( newType ); m->SetType( newType );
m->Recalculate( ); m->Recalculate();
finished = true; finished = true;
} else { } else {
@ -121,7 +125,7 @@ void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aE
remaining = aElongation; remaining = aElongation;
int meanderCount = 0; int meanderCount = 0;
BOOST_FOREACH(PNS_MEANDER_SHAPE *m, aTuned.Meanders()) BOOST_FOREACH(PNS_MEANDER_SHAPE* m, aTuned.Meanders())
{ {
if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY ) if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
{ {
@ -138,29 +142,30 @@ void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aE
if( meanderCount ) if( meanderCount )
balance = -remaining / meanderCount; balance = -remaining / meanderCount;
if (balance >= 0) if( balance >= 0 )
{ {
BOOST_FOREACH(PNS_MEANDER_SHAPE *m, aTuned.Meanders()) BOOST_FOREACH( PNS_MEANDER_SHAPE* m, aTuned.Meanders() )
{ {
if(m->Type() != MT_CORNER && m->Type() != MT_EMPTY) if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
{ {
m->Resize ( std::max( m->Amplitude() - balance / 2, m_settings.m_minAmplitude ) ); m->Resize( std::max( m->Amplitude() - balance / 2, m_settings.m_minAmplitude ) );
} }
} }
} }
} }
const PNS_MEANDER_SETTINGS& PNS_MEANDER_PLACER_BASE::MeanderSettings( ) const
const PNS_MEANDER_SETTINGS& PNS_MEANDER_PLACER_BASE::MeanderSettings() const
{ {
return m_settings; return m_settings;
} }
int PNS_MEANDER_PLACER_BASE::compareWithTollerance ( int aValue, int aExpected, int aTollerance ) const
int PNS_MEANDER_PLACER_BASE::compareWithTolerance( int aValue, int aExpected, int aTolerance ) const
{ {
if( aValue < aExpected - aTollerance ) if( aValue < aExpected - aTolerance )
return -1; return -1;
else if( aValue > aExpected + aTollerance ) else if( aValue > aExpected + aTolerance )
return 1; return 1;
else else
return 0; return 0;

View File

@ -54,7 +54,7 @@ public:
}; };
PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter ); PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter );
virtual ~PNS_MEANDER_PLACER_BASE( ); virtual ~PNS_MEANDER_PLACER_BASE();
/** /**
* Function TuningInfo() * Function TuningInfo()
@ -62,7 +62,7 @@ public:
* Returns a string describing the status and length of the * Returns a string describing the status and length of the
* tuned traces. * tuned traces.
*/ */
virtual const wxString TuningInfo( ) const = 0; virtual const wxString TuningInfo() const = 0;
/** /**
* Function TuningStatus() * Function TuningStatus()
@ -70,7 +70,7 @@ public:
* Returns the tuning status (too short, too long, etc.) * Returns the tuning status (too short, too long, etc.)
* of the trace(s) being tuned. * of the trace(s) being tuned.
*/ */
virtual TUNING_STATUS TuningStatus( ) const = 0; virtual TUNING_STATUS TuningStatus() const = 0;
/** /**
* Function AmplitudeStep() * Function AmplitudeStep()
@ -113,13 +113,11 @@ public:
* @param aShape the shape to check * @param aShape the shape to check
* @return true if the shape fits * @return true if the shape fits
*/ */
virtual bool CheckFit ( PNS_MEANDER_SHAPE* aShape ) virtual bool CheckFit( PNS_MEANDER_SHAPE* aShape )
{ {
return false; return false;
} }
protected: protected:
/** /**
@ -150,11 +148,11 @@ protected:
void tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation ); void tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation );
/** /**
* Function compareWithTollerance() * Function compareWithTolerance()
* *
* Compares aValue against aExpected with given tollerance. * Compares aValue against aExpected with given tolerance.
*/ */
int compareWithTollerance ( int aValue, int aExpected, int aTollerance = 0 ) const; int compareWithTolerance ( int aValue, int aExpected, int aTolerance = 0 ) const;
///> width of the meandered trace(s) ///> width of the meandered trace(s)
int m_currentWidth; int m_currentWidth;

View File

@ -38,30 +38,31 @@ PNS_MEANDER_SKEW_PLACER::PNS_MEANDER_SKEW_PLACER ( PNS_ROUTER* aRouter ) :
{ {
} }
PNS_MEANDER_SKEW_PLACER::~PNS_MEANDER_SKEW_PLACER( ) PNS_MEANDER_SKEW_PLACER::~PNS_MEANDER_SKEW_PLACER( )
{ {
} }
bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
VECTOR2I p; VECTOR2I p;
if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) ) if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
{ {
Router( )->SetFailureReason( _( "Please select a differential pair trace you want to tune." ) ); Router()->SetFailureReason( _( "Please select a differential pair trace you want to tune." ) );
return false; return false;
} }
m_initialSegment = static_cast<PNS_SEGMENT *>( aStartItem ); m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
p = m_initialSegment->Seg( ).NearestPoint( aP ); p = m_initialSegment->Seg().NearestPoint( aP );
m_originLine = NULL; m_originLine = NULL;
m_currentNode = NULL; m_currentNode = NULL;
m_currentStart = p; m_currentStart = p;
m_world = Router( )->GetWorld( )->Branch( ); m_world = Router()->GetWorld( )->Branch();
m_originLine = m_world->AssembleLine( m_initialSegment ); m_originLine = m_world->AssembleLine( m_initialSegment );
PNS_TOPOLOGY topo( m_world ); PNS_TOPOLOGY topo( m_world );
@ -75,15 +76,14 @@ bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
return false; return false;
} }
m_originPair.SetGap ( Router()->Sizes().DiffPairGap() ); m_originPair.SetGap ( Router()->Sizes().DiffPairGap() );
if( !m_originPair.PLine().SegmentCount() || if( !m_originPair.PLine().SegmentCount() ||
!m_originPair.NLine().SegmentCount() ) !m_originPair.NLine().SegmentCount() )
return false; return false;
m_tunedPathP = topo.AssembleTrivialPath ( m_originPair.PLine().GetLink(0) ); m_tunedPathP = topo.AssembleTrivialPath ( m_originPair.PLine().GetLink( 0 ) );
m_tunedPathN = topo.AssembleTrivialPath ( m_originPair.NLine().GetLink(0) ); m_tunedPathN = topo.AssembleTrivialPath ( m_originPair.NLine().GetLink( 0 ) );
m_world->Remove( m_originLine ); m_world->Remove( m_originLine );
@ -104,45 +104,48 @@ int PNS_MEANDER_SKEW_PLACER::origPathLength( ) const
return itemsetLength ( m_tunedPath ); return itemsetLength ( m_tunedPath );
} }
int PNS_MEANDER_SKEW_PLACER::itemsetLength( const PNS_ITEMSET& aSet ) const int PNS_MEANDER_SKEW_PLACER::itemsetLength( const PNS_ITEMSET& aSet ) const
{ {
int total = 0; int total = 0;
BOOST_FOREACH( const PNS_ITEM *item, aSet.CItems( ) ) BOOST_FOREACH( const PNS_ITEM* item, aSet.CItems() )
{ {
if( const PNS_LINE *l = dyn_cast<const PNS_LINE *>( item ) ) if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
{ {
total += l->CLine( ).Length( ); total += l->CLine().Length();
} }
} }
return total; return total;
} }
int PNS_MEANDER_SKEW_PLACER::currentSkew () const
int PNS_MEANDER_SKEW_PLACER::currentSkew() const
{ {
return m_lastLength - m_coupledLength; return m_lastLength - m_coupledLength;
} }
bool PNS_MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem ) bool PNS_MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
return doMove ( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew ); return doMove( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew );
} }
const wxString PNS_MEANDER_SKEW_PLACER::TuningInfo( ) const const wxString PNS_MEANDER_SKEW_PLACER::TuningInfo() const
{ {
wxString status; wxString status;
switch ( m_lastStatus ) switch( m_lastStatus )
{ {
case TOO_LONG: case TOO_LONG:
status = _( "Too long: skew " ); status = _( "Too long: skew " );
break; break;
case TOO_SHORT: case TOO_SHORT:
status = _(" Too short: skew " ); status = _( "Too short: skew " );
break; break;
case TUNED: case TUNED:
status = _(" Tuned: skew " ); status = _( "Tuned: skew " );
break; break;
default: default:
return _( "?" ); return _( "?" );

View File

@ -37,7 +37,6 @@ class PNS_ROUTER_BASE;
class PNS_MEANDER_SKEW_PLACER : public PNS_MEANDER_PLACER class PNS_MEANDER_SKEW_PLACER : public PNS_MEANDER_PLACER
{ {
public: public:
PNS_MEANDER_SKEW_PLACER( PNS_ROUTER* aRouter ); PNS_MEANDER_SKEW_PLACER( PNS_ROUTER* aRouter );
~PNS_MEANDER_SKEW_PLACER(); ~PNS_MEANDER_SKEW_PLACER();

View File

@ -619,13 +619,13 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
{ {
std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments(); std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments();
if(! aLine->SegmentCount() ) if( !aLine->SegmentCount() )
return; return;
assert (segRefs != NULL); assert( segRefs != NULL );
assert (aLine->Owner()); assert( aLine->Owner() );
if ( (int) segRefs->size() != aLine->SegmentCount() ) if( (int) segRefs->size() != aLine->SegmentCount() )
{ {
//printf("******weird deletion: segrefs %d segcount %d hasloops %d\n", segRefs->size(), aLine->SegmentCount(), aLine->HasLoops()); //printf("******weird deletion: segrefs %d segcount %d hasloops %d\n", segRefs->size(), aLine->SegmentCount(), aLine->HasLoops());
} }
@ -723,9 +723,10 @@ void PNS_NODE::Remove( PNS_ITEM* aItem )
} }
} }
void PNS_NODE::Remove ( PNS_LINE& aLine )
void PNS_NODE::Remove( PNS_LINE& aLine )
{ {
removeLine ( &aLine ); removeLine( &aLine );
} }
@ -763,7 +764,7 @@ void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos
aCurrent = jt->NextSegment( aCurrent ); aCurrent = jt->NextSegment( aCurrent );
prevReversed = prevReversed =
( jt->Pos() == (aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) ); ( jt->Pos() == ( aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) );
} }
} }
@ -865,8 +866,6 @@ void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFo
#endif #endif
int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<PNS_LINE*>& aLines ) int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<PNS_LINE*>& aLines )
{ {
BOOST_FOREACH( PNS_ITEM* item, aA.LinkList() ) BOOST_FOREACH( PNS_ITEM* item, aA.LinkList() )
@ -1209,7 +1208,7 @@ int PNS_NODE::RemoveByMarker( int aMarker )
} }
PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg ) PNS_SEGMENT* PNS_NODE::findRedundantSegment( PNS_SEGMENT* aSeg )
{ {
PNS_JOINT* jtStart = FindJoint ( aSeg->Seg().A, aSeg ); PNS_JOINT* jtStart = FindJoint ( aSeg->Seg().A, aSeg );
@ -1237,7 +1236,7 @@ PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg )
return NULL; return NULL;
} }
void PNS_NODE::SetCollisionFilter ( PNS_COLLISION_FILTER *aFilter ) void PNS_NODE::SetCollisionFilter( PNS_COLLISION_FILTER* aFilter )
{ {
m_collisionFilter = aFilter; m_collisionFilter = aFilter;
} }

View File

@ -55,7 +55,6 @@ public:
virtual ~PNS_CLEARANCE_FUNC() {} virtual ~PNS_CLEARANCE_FUNC() {}
virtual int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB ) = 0; virtual int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB ) = 0;
virtual void OverrideClearance (bool aEnable, int aNetA = 0, int aNetB = 0, int aClearance = 0) = 0; virtual void OverrideClearance (bool aEnable, int aNetA = 0, int aNetB = 0, int aClearance = 0) = 0;
}; };
class PNS_PCBNEW_CLEARANCE_FUNC : public PNS_CLEARANCE_FUNC class PNS_PCBNEW_CLEARANCE_FUNC : public PNS_CLEARANCE_FUNC
@ -297,7 +296,7 @@ public:
* @param aOriginSegmentIndex index of aSeg in the resulting line * @param aOriginSegmentIndex index of aSeg in the resulting line
* @return the line * @return the line
*/ */
PNS_LINE* AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex = NULL ); PNS_LINE* AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex = NULL );
///> Prints the contents and joints structure ///> Prints the contents and joints structure
void Dump( bool aLong = false ); void Dump( bool aLong = false );
@ -365,7 +364,7 @@ public:
int FindByMarker( int aMarker, PNS_ITEMSET& aItems ); int FindByMarker( int aMarker, PNS_ITEMSET& aItems );
int RemoveByMarker( int aMarker ); int RemoveByMarker( int aMarker );
void SetCollisionFilter ( PNS_COLLISION_FILTER *aFilter ); void SetCollisionFilter( PNS_COLLISION_FILTER* aFilter );
private: private:
struct OBSTACLE_VISITOR; struct OBSTACLE_VISITOR;

View File

@ -101,14 +101,14 @@ void PNS_COST_ESTIMATOR::Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine )
bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther, bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
double aLengthTollerance, double aLengthTolerance,
double aCornerTollerance ) const double aCornerTolerance ) const
{ {
if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost ) if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost )
return true; return true;
else if( aOther.m_cornerCost < m_cornerCost * aCornerTollerance && else if( aOther.m_cornerCost < m_cornerCost * aCornerTolerance &&
aOther.m_lengthCost < m_lengthCost * aLengthTollerance ) aOther.m_lengthCost < m_lengthCost * aLengthTolerance )
return true; return true;
return false; return false;
@ -224,27 +224,26 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
} }
} }
class LINE_RESTRICTIONS class LINE_RESTRICTIONS
{ {
public: public:
LINE_RESTRICTIONS( ) {}; LINE_RESTRICTIONS() {};
~LINE_RESTRICTIONS( ) {}; ~LINE_RESTRICTIONS() {};
void Build( PNS_NODE *aWorld, PNS_LINE *aOriginLine, const SHAPE_LINE_CHAIN& aLine, const BOX2I& aRestrictedArea, bool aRestrictedAreaEnable ); void Build( PNS_NODE* aWorld, PNS_LINE* aOriginLine, const SHAPE_LINE_CHAIN& aLine, const BOX2I& aRestrictedArea, bool aRestrictedAreaEnable );
bool Check ( int aVertex1, int aVertex2, const SHAPE_LINE_CHAIN& aReplacement ); bool Check ( int aVertex1, int aVertex2, const SHAPE_LINE_CHAIN& aReplacement );
void Dump(); void Dump();
private: private:
int allowedAngles ( PNS_NODE *aWorld, const PNS_LINE *aLine, const VECTOR2I& aP, bool aFirst ); int allowedAngles( PNS_NODE* aWorld, const PNS_LINE* aLine, const VECTOR2I& aP, bool aFirst );
struct RVERTEX struct RVERTEX
{ {
RVERTEX ( bool aRestricted, int aAllowedAngles ) : RVERTEX ( bool aRestricted, int aAllowedAngles ) :
restricted ( aRestricted ), restricted( aRestricted ),
allowedAngles ( aAllowedAngles ) allowedAngles( aAllowedAngles )
{ {
} }
bool restricted; bool restricted;
@ -254,55 +253,54 @@ class LINE_RESTRICTIONS
std::vector<RVERTEX> m_rs; std::vector<RVERTEX> m_rs;
}; };
// fixme: use later // fixme: use later
int LINE_RESTRICTIONS::allowedAngles ( PNS_NODE *aWorld, const PNS_LINE *aLine, const VECTOR2I& aP, bool aFirst ) int LINE_RESTRICTIONS::allowedAngles( PNS_NODE* aWorld, const PNS_LINE* aLine, const VECTOR2I& aP, bool aFirst )
{ {
PNS_JOINT* jt = aWorld->FindJoint( aP , aLine ); PNS_JOINT* jt = aWorld->FindJoint( aP , aLine );
if( !jt ) if( !jt )
return 0xff; return 0xff;
DIRECTION_45 dirs [8]; DIRECTION_45 dirs [8];
int n_dirs = 0; int n_dirs = 0;
BOOST_FOREACH ( const PNS_ITEM *item, jt->Links().CItems() ) BOOST_FOREACH( const PNS_ITEM* item, jt->Links().CItems() )
{ {
if (item->OfKind (PNS_ITEM::VIA) || item->OfKind (PNS_ITEM::SOLID)) if( item->OfKind( PNS_ITEM::VIA ) || item->OfKind( PNS_ITEM::SOLID ) )
return 0xff; return 0xff;
else if ( const PNS_SEGMENT *seg = dyn_cast<const PNS_SEGMENT*> ( item ) ) else if( const PNS_SEGMENT* seg = dyn_cast<const PNS_SEGMENT*>( item ) )
{ {
SEG s = seg->Seg(); SEG s = seg->Seg();
if (s.A != aP) if( s.A != aP )
s.Reverse(); s.Reverse();
if (n_dirs < 8) if( n_dirs < 8 )
dirs [ n_dirs++ ] = aFirst ? DIRECTION_45 ( s ) : DIRECTION_45 ( s ).Opposite(); dirs[n_dirs++] = aFirst ? DIRECTION_45( s ) : DIRECTION_45( s ).Opposite();
} }
} }
const int angleMask = DIRECTION_45::ANG_OBTUSE | DIRECTION_45::ANG_HALF_FULL | DIRECTION_45::ANG_STRAIGHT; const int angleMask = DIRECTION_45::ANG_OBTUSE | DIRECTION_45::ANG_HALF_FULL | DIRECTION_45::ANG_STRAIGHT;
int outputMask = 0xff; int outputMask = 0xff;
for (int d = 0; d < 8; d ++) for( int d = 0; d < 8; d++ )
{ {
DIRECTION_45 refDir( (DIRECTION_45::Directions) d ); DIRECTION_45 refDir( ( DIRECTION_45::Directions ) d );
for (int i = 0; i < n_dirs; i++ )
for( int i = 0; i < n_dirs; i++ )
{ {
if (! (refDir.Angle(dirs [ i ] ) & angleMask) ) if( !(refDir.Angle( dirs[i] ) & angleMask ) )
outputMask &= ~refDir.Mask(); outputMask &= ~refDir.Mask();
} }
} }
DrawDebugDirs ( aP, outputMask, 3 ); DrawDebugDirs( aP, outputMask, 3 );
return 0xff; return 0xff;
} }
void LINE_RESTRICTIONS::Build( PNS_NODE *aWorld, PNS_LINE *aOriginLine, const SHAPE_LINE_CHAIN& aLine, const BOX2I& aRestrictedArea, bool aRestrictedAreaEnable ) void LINE_RESTRICTIONS::Build( PNS_NODE* aWorld, PNS_LINE* aOriginLine, const SHAPE_LINE_CHAIN& aLine, const BOX2I& aRestrictedArea, bool aRestrictedAreaEnable )
{ {
const SHAPE_LINE_CHAIN& l = aLine; const SHAPE_LINE_CHAIN& l = aLine;
VECTOR2I v_prev; VECTOR2I v_prev;
@ -310,49 +308,56 @@ void LINE_RESTRICTIONS::Build( PNS_NODE *aWorld, PNS_LINE *aOriginLine, const SH
m_rs.reserve( n ); m_rs.reserve( n );
for (int i = 0; i < n; i++) for( int i = 0; i < n; i++ )
{ {
const VECTOR2I &v = l.CPoint(i), v_next; const VECTOR2I &v = l.CPoint( i ), v_next;
RVERTEX r ( false, 0xff ); RVERTEX r( false, 0xff );
if ( aRestrictedAreaEnable ) if( aRestrictedAreaEnable )
{ {
bool exiting = ( i > 0 && aRestrictedArea.Contains( v_prev ) && !aRestrictedArea.Contains(v) ); bool exiting = ( i > 0 && aRestrictedArea.Contains( v_prev ) && !aRestrictedArea.Contains( v ) );
bool entering = false; bool entering = false;
if( i != l.PointCount() - 1) if( i != l.PointCount() - 1 )
{ {
const VECTOR2I& v_next = l.CPoint(i + 1); const VECTOR2I& v_next = l.CPoint( i + 1 );
entering = ( !aRestrictedArea.Contains( v ) && aRestrictedArea.Contains( v_next ) ); entering = ( !aRestrictedArea.Contains( v ) && aRestrictedArea.Contains( v_next ) );
} }
if(entering) if( entering )
{ {
const SEG& sp = l.CSegment(i); const SEG& sp = l.CSegment( i );
r.allowedAngles = DIRECTION_45(sp).Mask(); r.allowedAngles = DIRECTION_45( sp ).Mask();
} else if (exiting) { }
const SEG& sp = l.CSegment(i - 1); else if( exiting )
r.allowedAngles = DIRECTION_45(sp).Mask(); {
} else { const SEG& sp = l.CSegment( i - 1 );
r.allowedAngles = (! aRestrictedArea.Contains ( v ) ) ? 0 : 0xff; r.allowedAngles = DIRECTION_45( sp ).Mask();
}
else
{
r.allowedAngles = ( !aRestrictedArea.Contains( v ) ) ? 0 : 0xff;
r.restricted = r.allowedAngles ? false : true; r.restricted = r.allowedAngles ? false : true;
} }
} }
v_prev = v; v_prev = v;
m_rs.push_back(r); m_rs.push_back( r );
} }
} }
void LINE_RESTRICTIONS::Dump() void LINE_RESTRICTIONS::Dump()
{ {
} }
bool LINE_RESTRICTIONS::Check ( int aVertex1, int aVertex2, const SHAPE_LINE_CHAIN& aReplacement )
bool LINE_RESTRICTIONS::Check( int aVertex1, int aVertex2, const SHAPE_LINE_CHAIN& aReplacement )
{ {
if( m_rs.empty( ) ) if( m_rs.empty( ) )
return true; return true;
for(int i = aVertex1; i <= aVertex2; i++) for( int i = aVertex1; i <= aVertex2; i++ )
if ( m_rs[i].restricted ) if ( m_rs[i].restricted )
return false; return false;
@ -361,18 +366,17 @@ bool LINE_RESTRICTIONS::Check ( int aVertex1, int aVertex2, const SHAPE_LINE_CHA
int m1 = DIRECTION_45( aReplacement.CSegment( 0 ) ).Mask(); int m1 = DIRECTION_45( aReplacement.CSegment( 0 ) ).Mask();
int m2; int m2;
if (aReplacement.SegmentCount() == 1)
if( aReplacement.SegmentCount() == 1 )
m2 = m1; m2 = m1;
else else
m2 = DIRECTION_45 ( aReplacement.CSegment( 1 ) ).Mask(); m2 = DIRECTION_45( aReplacement.CSegment( 1 ) ).Mask();
return ( ( v1.allowedAngles & m1 ) != 0 ) &&
return ((v1.allowedAngles & m1) != 0) && ( ( v2.allowedAngles & m2 ) != 0 );
((v2.allowedAngles & m2) != 0);
} }
bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache ) bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
{ {
CACHE_VISITOR v( aItem, m_world, m_collisionKindMask ); CACHE_VISITOR v( aItem, m_world, m_collisionKindMask );
@ -464,7 +468,6 @@ bool PNS_OPTIMIZER::mergeObtuse( PNS_LINE* aLine )
s2opt = SEG( ip, s2.B ); s2opt = SEG( ip, s2.B );
} }
if( DIRECTION_45( s1opt ).IsObtuse( DIRECTION_45( s2opt ) ) ) if( DIRECTION_45( s1opt ).IsObtuse( DIRECTION_45( s2opt ) ) )
{ {
SHAPE_LINE_CHAIN opt_path; SHAPE_LINE_CHAIN opt_path;
@ -928,13 +931,15 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE* aLine )
if(endPad) if(endPad)
{ {
endMatch = endPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID ); endMatch = endPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
} else { }
else
{
endMatch = aLine->EndsWithVia(); endMatch = aLine->EndsWithVia();
} }
if( startMatch && endMatch && len < thr ) if( startMatch && endMatch && len < thr )
{ {
for(int i = 0; i < 2; i++ ) for( int i = 0; i < 2; i++ )
{ {
SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i ); SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i );
PNS_LINE repl; PNS_LINE repl;
@ -951,20 +956,20 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE* aLine )
return false; return false;
} }
int findCoupledVertices ( const VECTOR2I& aVertex, const SEG& aOrigSeg, const SHAPE_LINE_CHAIN& aCoupled, PNS_DIFF_PAIR *aPair, int *aIndices )
int findCoupledVertices( const VECTOR2I& aVertex, const SEG& aOrigSeg, const SHAPE_LINE_CHAIN& aCoupled, PNS_DIFF_PAIR* aPair, int* aIndices )
{ {
int count = 0; int count = 0;
for ( int i = 0; i < aCoupled.SegmentCount(); i++ ) for ( int i = 0; i < aCoupled.SegmentCount(); i++ )
{ {
SEG s = aCoupled.CSegment(i); SEG s = aCoupled.CSegment( i );
VECTOR2I projOverCoupled = s.LineProject ( aVertex ); VECTOR2I projOverCoupled = s.LineProject ( aVertex );
if( s.ApproxParallel ( aOrigSeg ) ) if( s.ApproxParallel ( aOrigSeg ) )
{ {
int64_t dist = ( projOverCoupled - aVertex ).EuclideanNorm() - aPair->Width(); int64_t dist = ( projOverCoupled - aVertex ).EuclideanNorm() - aPair->Width();
if( aPair->GapConstraint().Matches(dist) ) if( aPair->GapConstraint().Matches( dist ) )
{ {
*aIndices++ = i; *aIndices++ = i;
count++; count++;
@ -975,45 +980,49 @@ int findCoupledVertices ( const VECTOR2I& aVertex, const SEG& aOrigSeg, const SH
return count; return count;
} }
bool verifyDpBypass ( PNS_NODE *aNode, PNS_DIFF_PAIR *aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aNewRef, const SHAPE_LINE_CHAIN& aNewCoupled )
bool verifyDpBypass( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aNewRef, const SHAPE_LINE_CHAIN& aNewCoupled )
{ {
PNS_LINE refLine ( aRefIsP ? aPair->PLine() : aPair->NLine(), aNewRef ); PNS_LINE refLine ( aRefIsP ? aPair->PLine() : aPair->NLine(), aNewRef );
PNS_LINE coupledLine ( aRefIsP ? aPair->NLine() : aPair->PLine(), aNewCoupled ); PNS_LINE coupledLine ( aRefIsP ? aPair->NLine() : aPair->PLine(), aNewCoupled );
if ( aNode->CheckColliding( &refLine, &coupledLine, PNS_ITEM::ANY, aPair->Gap() - 10 ) ) if( aNode->CheckColliding( &refLine, &coupledLine, PNS_ITEM::ANY, aPair->Gap() - 10 ) )
return false; return false;
if ( aNode->CheckColliding ( &refLine ) ) if( aNode->CheckColliding ( &refLine ) )
return false; return false;
if ( aNode->CheckColliding ( &coupledLine ) ) if( aNode->CheckColliding ( &coupledLine ) )
return false; return false;
return true; return true;
} }
bool coupledBypass ( PNS_NODE *aNode, PNS_DIFF_PAIR *aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aRef, const SHAPE_LINE_CHAIN& aRefBypass, const SHAPE_LINE_CHAIN& aCoupled, SHAPE_LINE_CHAIN& aNewCoupled )
bool coupledBypass( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aRef, const SHAPE_LINE_CHAIN& aRefBypass, const SHAPE_LINE_CHAIN& aCoupled, SHAPE_LINE_CHAIN& aNewCoupled )
{ {
int vStartIdx[1024]; // fixme: possible overflow int vStartIdx[1024]; // fixme: possible overflow
int nStarts = findCoupledVertices ( aRefBypass.CPoint(0), aRefBypass.CSegment(0), aCoupled, aPair, vStartIdx ); int nStarts = findCoupledVertices( aRefBypass.CPoint( 0 ), aRefBypass.CSegment( 0 ), aCoupled, aPair, vStartIdx );
DIRECTION_45 dir( aRefBypass.CSegment(0) ); DIRECTION_45 dir( aRefBypass.CSegment( 0 ) );
int64_t bestLength = -1; int64_t bestLength = -1;
bool found = false; bool found = false;
SHAPE_LINE_CHAIN bestBypass; SHAPE_LINE_CHAIN bestBypass;
int si, ei; int si, ei;
for(int i=0; i< nStarts ;i++) for( int i=0; i< nStarts; i++ )
for ( int j = 1; j < aCoupled.PointCount() - 1; j++) {
for( int j = 1; j < aCoupled.PointCount() - 1; j++ )
{ {
int delta = std::abs ( vStartIdx[i] - j ); int delta = std::abs ( vStartIdx[i] - j );
if(delta > 1)
if( delta > 1 )
{ {
const VECTOR2I& vs = aCoupled.CPoint( vStartIdx[i] ); const VECTOR2I& vs = aCoupled.CPoint( vStartIdx[i] );
SHAPE_LINE_CHAIN bypass = dir.BuildInitialTrace( vs, aCoupled.CPoint(j), dir.IsDiagonal() ); SHAPE_LINE_CHAIN bypass = dir.BuildInitialTrace( vs, aCoupled.CPoint(j), dir.IsDiagonal() );
int64_t coupledLength = aPair->CoupledLength ( aRef, bypass ); int64_t coupledLength = aPair->CoupledLength( aRef, bypass );
SHAPE_LINE_CHAIN newCoupled = aCoupled; SHAPE_LINE_CHAIN newCoupled = aCoupled;
@ -1025,7 +1034,7 @@ bool coupledBypass ( PNS_NODE *aNode, PNS_DIFF_PAIR *aPair, bool aRefIsP, const
else else
newCoupled.Replace( ei, si, bypass.Reverse() ); newCoupled.Replace( ei, si, bypass.Reverse() );
if(coupledLength > bestLength && verifyDpBypass ( aNode, aPair, aRefIsP, aRef, newCoupled) ) if(coupledLength > bestLength && verifyDpBypass( aNode, aPair, aRefIsP, aRef, newCoupled) )
{ {
bestBypass = newCoupled; bestBypass = newCoupled;
bestLength = coupledLength; bestLength = coupledLength;
@ -1033,15 +1042,17 @@ bool coupledBypass ( PNS_NODE *aNode, PNS_DIFF_PAIR *aPair, bool aRefIsP, const
} }
} }
} }
}
if(found) if( found )
aNewCoupled = bestBypass; aNewCoupled = bestBypass;
return found; return found;
} }
bool checkDpColliding ( PNS_NODE *aNode, PNS_DIFF_PAIR *aPair, bool aIsP, const SHAPE_LINE_CHAIN& aPath )
bool checkDpColliding( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aIsP, const SHAPE_LINE_CHAIN& aPath )
{ {
PNS_LINE tmp ( aIsP ? aPair->PLine() : aPair->NLine(), aPath ); PNS_LINE tmp ( aIsP ? aPair->PLine() : aPair->NLine(), aPath );
@ -1049,7 +1060,7 @@ bool checkDpColliding ( PNS_NODE *aNode, PNS_DIFF_PAIR *aPair, bool aIsP, const
} }
bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR *aPair, bool aTryP, int step ) bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR* aPair, bool aTryP, int step )
{ {
int n = 1; int n = 1;
@ -1058,7 +1069,7 @@ bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR *aPair, bool aTryP, int step )
int n_segs = currentPath.SegmentCount() - 1; int n_segs = currentPath.SegmentCount() - 1;
int64_t clenPre = aPair->CoupledLength ( currentPath, coupledPath ); int64_t clenPre = aPair->CoupledLength( currentPath, coupledPath );
int64_t budget = clenPre / 10; // fixme: come up with somethig more intelligent here... int64_t budget = clenPre / 10; // fixme: come up with somethig more intelligent here...
while( n < n_segs - step ) while( n < n_segs - step )
@ -1066,32 +1077,31 @@ bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR *aPair, bool aTryP, int step )
const SEG s1 = currentPath.CSegment( n ); const SEG s1 = currentPath.CSegment( n );
const SEG s2 = currentPath.CSegment( n + step ); const SEG s2 = currentPath.CSegment( n + step );
DIRECTION_45 dir1 (s1); DIRECTION_45 dir1( s1 );
DIRECTION_45 dir2 (s2); DIRECTION_45 dir2( s2 );
if( dir1.IsObtuse(dir2 ) ) if( dir1.IsObtuse( dir2 ) )
{ {
SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, dir1.IsDiagonal() ); SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, dir1.IsDiagonal() );
SHAPE_LINE_CHAIN newRef; SHAPE_LINE_CHAIN newRef;
SHAPE_LINE_CHAIN newCoup; SHAPE_LINE_CHAIN newCoup;
int64_t deltaCoupled = -1, deltaUni = -1; int64_t deltaCoupled = -1, deltaUni = -1;
newRef = currentPath; newRef = currentPath;
newRef.Replace( s1.Index(), s2.Index(), bypass ); newRef.Replace( s1.Index(), s2.Index(), bypass );
deltaUni = aPair->CoupledLength ( newRef, coupledPath ) - clenPre + budget; deltaUni = aPair->CoupledLength ( newRef, coupledPath ) - clenPre + budget;
if ( coupledBypass ( m_world, aPair, aTryP, newRef, bypass, coupledPath, newCoup ) ) if ( coupledBypass( m_world, aPair, aTryP, newRef, bypass, coupledPath, newCoup ) )
{ {
deltaCoupled = aPair->CoupledLength ( newRef, newCoup ) - clenPre + budget; deltaCoupled = aPair->CoupledLength( newRef, newCoup ) - clenPre + budget;
if(deltaCoupled >= 0) if( deltaCoupled >= 0 )
{ {
newRef.Simplify(); newRef.Simplify();
newCoup.Simplify(); newCoup.Simplify();
aPair->SetShape ( newRef, newCoup, !aTryP ); aPair->SetShape( newRef, newCoup, !aTryP );
return true; return true;
} }
} }
@ -1100,7 +1110,7 @@ bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR *aPair, bool aTryP, int step )
newRef.Simplify(); newRef.Simplify();
coupledPath.Simplify(); coupledPath.Simplify();
aPair->SetShape ( newRef, coupledPath, !aTryP ); aPair->SetShape( newRef, coupledPath, !aTryP );
return true; return true;
} }
} }
@ -1111,7 +1121,8 @@ bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR *aPair, bool aTryP, int step )
return false; return false;
} }
bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR *aPair )
bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR* aPair )
{ {
int step_p = aPair->CP().SegmentCount() - 2; int step_p = aPair->CP().SegmentCount() - 2;
int step_n = aPair->CN().SegmentCount() - 2; int step_n = aPair->CN().SegmentCount() - 2;
@ -1136,10 +1147,10 @@ bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR *aPair )
bool found_anything_p = false; bool found_anything_p = false;
bool found_anything_n = false; bool found_anything_n = false;
if(step_p > 1) if( step_p > 1 )
found_anything_p = mergeDpStep( aPair, true, step_p ); found_anything_p = mergeDpStep( aPair, true, step_p );
if(step_n > 1) if( step_n > 1 )
found_anything_n = mergeDpStep( aPair, false, step_n ); found_anything_n = mergeDpStep( aPair, false, step_n );
if( !found_anything_n && !found_anything_p ) if( !found_anything_n && !found_anything_p )
@ -1151,9 +1162,8 @@ bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR *aPair )
return true; return true;
} }
bool PNS_OPTIMIZER::Optimize( PNS_DIFF_PAIR* aPair ) bool PNS_OPTIMIZER::Optimize( PNS_DIFF_PAIR* aPair )
{ {
return mergeDpSegments( aPair );
return mergeDpSegments ( aPair );
} }

View File

@ -62,7 +62,7 @@ public:
void Remove( PNS_LINE& aLine ); void Remove( PNS_LINE& aLine );
void Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine ); void Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine );
bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTollerance, bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTolerance,
double aCornerTollerace ) const; double aCornerTollerace ) const;
double GetLengthCost() const { return m_lengthCost; } double GetLengthCost() const { return m_lengthCost; }

View File

@ -148,7 +148,6 @@ public:
*/ */
virtual void FlipPosture() virtual void FlipPosture()
{ {
} }
/** /**
@ -160,7 +159,6 @@ public:
*/ */
virtual void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes ) virtual void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
{ {
} }
/** /**
@ -172,7 +170,6 @@ public:
*/ */
virtual void SetOrthoMode ( bool aOrthoMode ) virtual void SetOrthoMode ( bool aOrthoMode )
{ {
} }
/** /**
@ -182,7 +179,6 @@ public:
*/ */
virtual void GetModifiedNets( std::vector<int> &aNets ) const virtual void GetModifiedNets( std::vector<int> &aNets ) const
{ {
} }
}; };

View File

@ -49,8 +49,6 @@
#include "pns_meander_skew_placer.h" #include "pns_meander_skew_placer.h"
#include "pns_dp_meander_placer.h" #include "pns_dp_meander_placer.h"
#include <router/router_preview_item.h> #include <router/router_preview_item.h>
#include <class_board.h> #include <class_board.h>
@ -87,11 +85,12 @@ PNS_PCBNEW_CLEARANCE_FUNC::PNS_PCBNEW_CLEARANCE_FUNC( BOARD* aBoard )
m_defaultClearance = 254000; // aBoard->m_NetClasses.Find ("Default clearance")->GetClearance(); m_defaultClearance = 254000; // aBoard->m_NetClasses.Find ("Default clearance")->GetClearance();
} }
PNS_PCBNEW_CLEARANCE_FUNC::~PNS_PCBNEW_CLEARANCE_FUNC() PNS_PCBNEW_CLEARANCE_FUNC::~PNS_PCBNEW_CLEARANCE_FUNC()
{ {
} }
int PNS_PCBNEW_CLEARANCE_FUNC::localPadClearance( const PNS_ITEM* aItem ) const int PNS_PCBNEW_CLEARANCE_FUNC::localPadClearance( const PNS_ITEM* aItem ) const
{ {
if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T ) if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T )
@ -101,6 +100,7 @@ int PNS_PCBNEW_CLEARANCE_FUNC::localPadClearance( const PNS_ITEM* aItem ) const
return pad->GetLocalClearance(); return pad->GetLocalClearance();
} }
int PNS_PCBNEW_CLEARANCE_FUNC::operator()( const PNS_ITEM* aA, const PNS_ITEM* aB ) int PNS_PCBNEW_CLEARANCE_FUNC::operator()( const PNS_ITEM* aA, const PNS_ITEM* aB )
{ {
int net_a = aA->Net(); int net_a = aA->Net();
@ -108,7 +108,7 @@ int PNS_PCBNEW_CLEARANCE_FUNC::operator()( const PNS_ITEM* aA, const PNS_ITEM* a
int net_b = aB->Net(); int net_b = aB->Net();
int cl_b = ( net_b >= 0 ? m_clearanceCache[net_b] : m_defaultClearance ); int cl_b = ( net_b >= 0 ? m_clearanceCache[net_b] : m_defaultClearance );
if(m_overrideEnabled && aA->OfKind(PNS_ITEM::SEGMENT) && aB->OfKind(PNS_ITEM::SEGMENT)) if( m_overrideEnabled && aA->OfKind( PNS_ITEM::SEGMENT ) && aB->OfKind( PNS_ITEM::SEGMENT ) )
{ {
if( net_a == m_overrideNetA && net_b == m_overrideNetB ) if( net_a == m_overrideNetA && net_b == m_overrideNetB )
return m_overrideClearance; return m_overrideClearance;
@ -123,10 +123,11 @@ int PNS_PCBNEW_CLEARANCE_FUNC::operator()( const PNS_ITEM* aA, const PNS_ITEM* a
cl_b = std::max( cl_b, pad_b ); cl_b = std::max( cl_b, pad_b );
return std::max( cl_a, cl_b ); return std::max( cl_a, cl_b );
}; }
// fixme: ugly hack to make the optimizer respect gap width for currently routed differential pair. // fixme: ugly hack to make the optimizer respect gap width for currently routed differential pair.
void PNS_PCBNEW_CLEARANCE_FUNC::OverrideClearance (bool aEnable, int aNetA , int aNetB , int aClearance ) void PNS_PCBNEW_CLEARANCE_FUNC::OverrideClearance( bool aEnable, int aNetA, int aNetB , int aClearance )
{ {
m_overrideEnabled = aEnable; m_overrideEnabled = aEnable;
m_overrideNetA = aNetA; m_overrideNetA = aNetA;
@ -249,6 +250,7 @@ PNS_ITEM* PNS_ROUTER::syncTrack( TRACK* aTrack )
if( aTrack->GetFlags( ) & DP_COUPLED ) if( aTrack->GetFlags( ) & DP_COUPLED )
s->Mark ( MK_DP_COUPLED ); s->Mark ( MK_DP_COUPLED );
s->SetWidth( aTrack->GetWidth() ); s->SetWidth( aTrack->GetWidth() );
s->SetLayers( PNS_LAYERSET( aTrack->GetLayer() ) ); s->SetLayers( PNS_LAYERSET( aTrack->GetLayer() ) );
s->SetParent( aTrack ); s->SetParent( aTrack );
@ -280,6 +282,7 @@ void PNS_ROUTER::SetBoard( BOARD* aBoard )
TRACE( 1, "m_board = %p\n", m_board ); TRACE( 1, "m_board = %p\n", m_board );
} }
void PNS_ROUTER::SyncWorld() void PNS_ROUTER::SyncWorld()
{ {
if( !m_board ) if( !m_board )
@ -488,7 +491,7 @@ bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLayer ) bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLayer )
{ {
switch (m_mode) switch( m_mode )
{ {
case PNS_MODE_ROUTE_SINGLE: case PNS_MODE_ROUTE_SINGLE:
m_placer = new PNS_LINE_PLACER( this ); m_placer = new PNS_LINE_PLACER( this );
@ -515,7 +518,7 @@ bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLa
bool rv = m_placer->Start( aP, aStartItem ); bool rv = m_placer->Start( aP, aStartItem );
if(!rv) if( !rv )
return false; return false;
m_currentEnd = aP; m_currentEnd = aP;
@ -524,11 +527,13 @@ bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLa
return rv; return rv;
} }
BOARD *PNS_ROUTER::GetBoard()
BOARD* PNS_ROUTER::GetBoard()
{ {
return m_board; return m_board;
} }
void PNS_ROUTER::eraseView() void PNS_ROUTER::eraseView()
{ {
BOOST_FOREACH( BOARD_ITEM* item, m_hiddenItems ) BOOST_FOREACH( BOARD_ITEM* item, m_hiddenItems )
@ -710,20 +715,18 @@ void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* aEndItem )
m_placer->Move( aP, aEndItem ); m_placer->Move( aP, aEndItem );
PNS_ITEMSET current = m_placer->Traces(); PNS_ITEMSET current = m_placer->Traces();
BOOST_FOREACH( const PNS_ITEM* item, current.CItems() ) BOOST_FOREACH( const PNS_ITEM* item, current.CItems() )
{ {
if( !item->OfKind ( PNS_ITEM::LINE ) ) if( !item->OfKind( PNS_ITEM::LINE ) )
continue; continue;
const PNS_LINE *l = static_cast <const PNS_LINE *> (item); const PNS_LINE* l = static_cast <const PNS_LINE*> (item);
DisplayItem(l); DisplayItem( l );
if( l->EndsWithVia() ) if( l->EndsWithVia() )
DisplayItem( &l->Via() ); DisplayItem( &l->Via() );
} }
//PNS_ITEMSET tmp( &current ); //PNS_ITEMSET tmp( &current );
updateView( m_placer->CurrentNode( true ), current ); updateView( m_placer->CurrentNode( true ), current );
@ -844,7 +847,6 @@ void PNS_ROUTER::StopRouting()
} }
} }
if( !RoutingInProgress() ) if( !RoutingInProgress() )
return; return;
@ -932,24 +934,26 @@ void PNS_ROUTER::DumpLog()
logger->Save( "/tmp/shove.log" ); logger->Save( "/tmp/shove.log" );
} }
bool PNS_ROUTER::IsPlacingVia() const bool PNS_ROUTER::IsPlacingVia() const
{ {
if(!m_placer) if( !m_placer )
return NULL; return NULL;
return m_placer->IsPlacingVia(); return m_placer->IsPlacingVia();
} }
void PNS_ROUTER::SetOrthoMode( bool aEnable ) void PNS_ROUTER::SetOrthoMode( bool aEnable )
{ {
if(!m_placer) if( !m_placer )
return; return;
m_placer->SetOrthoMode ( aEnable ); m_placer->SetOrthoMode( aEnable );
} }
void PNS_ROUTER::SetMode ( PNS_ROUTER_MODE aMode )
void PNS_ROUTER::SetMode( PNS_ROUTER_MODE aMode )
{ {
m_mode = aMode; m_mode = aMode;
} }

View File

@ -277,7 +277,6 @@ private:
wxString m_toolStatusbarName; wxString m_toolStatusbarName;
wxString m_failureReason; wxString m_failureReason;
}; };
#endif #endif

View File

@ -137,7 +137,6 @@ private:
PNS_MODE m_routingMode; PNS_MODE m_routingMode;
PNS_OPTIMIZATION_EFFORT m_optimizerEffort; PNS_OPTIMIZATION_EFFORT m_optimizerEffort;
int m_walkaroundIterationLimit; int m_walkaroundIterationLimit;
int m_shoveIterationLimit; int m_shoveIterationLimit;
TIME_LIMIT m_shoveTimeLimit; TIME_LIMIT m_shoveTimeLimit;

View File

@ -42,14 +42,13 @@
#include <profile.h> #include <profile.h>
void PNS_SHOVE::replaceItems ( PNS_ITEM *aOld, PNS_ITEM *aNew ) void PNS_SHOVE::replaceItems( PNS_ITEM* aOld, PNS_ITEM* aNew )
{ {
OPT_BOX2I changed_area = ChangedArea( aOld, aNew ); OPT_BOX2I changed_area = ChangedArea( aOld, aNew );
if( changed_area )
if(changed_area)
{ {
assert ( !changed_area->Contains ( VECTOR2I (0, 0 ) ) ); assert( !changed_area->Contains( VECTOR2I( 0, 0 ) ) );
m_affectedAreaSum = m_affectedAreaSum ? m_affectedAreaSum->Merge ( *changed_area ) : *changed_area; m_affectedAreaSum = m_affectedAreaSum ? m_affectedAreaSum->Merge ( *changed_area ) : *changed_area;
} }
@ -60,12 +59,13 @@ void PNS_SHOVE::replaceItems ( PNS_ITEM *aOld, PNS_ITEM *aNew )
int PNS_SHOVE::getClearance( PNS_ITEM *aA, PNS_ITEM *aB ) const int PNS_SHOVE::getClearance( PNS_ITEM *aA, PNS_ITEM *aB ) const
{ {
if(m_forceClearance >= 0) if( m_forceClearance >= 0 )
return m_forceClearance; return m_forceClearance;
return m_currentNode->GetClearance( aA, aB ); return m_currentNode->GetClearance( aA, aB );
} }
static void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew ) static void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew )
{ {
assert( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) ); assert( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) );
@ -99,6 +99,7 @@ PNS_LINE* PNS_SHOVE::assembleLine( const PNS_SEGMENT* aSeg, int* aIndex )
return l; return l;
} }
// A dumb function that checks if the shoved line is shoved the right way, e.g. // A dumb function that checks if the shoved line is shoved the right way, e.g.
// visually "outwards" of the line/via applying pressure on it. Unfortunately there's no // visually "outwards" of the line/via applying pressure on it. Unfortunately there's no
// mathematical concept of orientation of an open curve, so we use some primitive heuristics: // mathematical concept of orientation of an open curve, so we use some primitive heuristics:
@ -311,7 +312,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSegment( PNS_LINE* aCurrent, PNS_S
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, obstacleLine, shovedLine ); SHOVE_STATUS rv = ProcessSingleLine( aCurrent, obstacleLine, shovedLine );
assert ( obstacleLine->LayersOverlap( shovedLine ) ); assert( obstacleLine->LayersOverlap( shovedLine ) );
if( rv == SH_OK ) if( rv == SH_OK )
{ {
@ -351,13 +352,11 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE* aCurrent, PNS_LINE
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine ); SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine );
if( rv == SH_OK ) if( rv == SH_OK )
{ {
if( shovedLine->Marker() & MK_HEAD ) if( shovedLine->Marker() & MK_HEAD )
{ {
if (m_multiLineMode) if( m_multiLineMode )
return SH_INCOMPLETE; return SH_INCOMPLETE;
m_newHead = *shovedLine; m_newHead = *shovedLine;
@ -496,10 +495,9 @@ bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
SPRINGBACK_TAG st; SPRINGBACK_TAG st;
OPT_BOX2I prev_area; OPT_BOX2I prev_area;
if(!m_nodeStack.empty()) if( !m_nodeStack.empty() )
prev_area = m_nodeStack.back().m_affectedArea; prev_area = m_nodeStack.back().m_affectedArea;
st.m_node = aNode; st.m_node = aNode;
st.m_cost = aCost; st.m_cost = aCost;
st.m_headItems = aHeadItems; st.m_headItems = aHeadItems;
@ -522,18 +520,18 @@ bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun ) PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun )
{ {
LINE_PAIR_VEC draggedLines; LINE_PAIR_VEC draggedLines;
VECTOR2I p0 ( aVia->Pos() ); VECTOR2I p0( aVia->Pos() );
PNS_JOINT* jt = m_currentNode->FindJoint( p0, aVia ); PNS_JOINT* jt = m_currentNode->FindJoint( p0, aVia );
VECTOR2I p0_pushed( p0 + aForce ); VECTOR2I p0_pushed( p0 + aForce );
while (aForce.x != 0 || aForce.y != 0) while( aForce.x != 0 || aForce.y != 0 )
{ {
PNS_JOINT *jt_next = m_currentNode->FindJoint ( p0_pushed, aVia ); PNS_JOINT* jt_next = m_currentNode->FindJoint( p0_pushed, aVia );
if(!jt_next) if( !jt_next )
break; break;
p0_pushed += aForce.Resize ( 2 ); // make sure pushed via does not overlap with any existing joint p0_pushed += aForce.Resize( 2 ); // make sure pushed via does not overlap with any existing joint
} }
PNS_VIA* pushedVia = aVia->Clone(); PNS_VIA* pushedVia = aVia->Clone();
@ -554,7 +552,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
{ {
if( PNS_SEGMENT *seg = dyn_cast<PNS_SEGMENT *>( item ) ) if( PNS_SEGMENT* seg = dyn_cast<PNS_SEGMENT*>( item ) )
{ {
LINE_PAIR lp; LINE_PAIR lp;
int segIndex; int segIndex;
@ -569,12 +567,11 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
lp.second = clone( lp.first ); lp.second = clone( lp.first );
lp.second->ClearSegmentLinks(); lp.second->ClearSegmentLinks();
lp.second->DragCorner( p0_pushed, lp.second->CLine().Find( p0 ) ); lp.second->DragCorner( p0_pushed, lp.second->CLine().Find( p0 ) );
lp.second->AppendVia ( *pushedVia ); lp.second->AppendVia( *pushedVia );
draggedLines.push_back( lp ); draggedLines.push_back( lp );
if (aVia->Marker() & MK_HEAD ) if( aVia->Marker() & MK_HEAD )
m_draggedViaHeadSet.Add ( clone ( lp.second ) ); m_draggedViaHeadSet.Add( clone ( lp.second ) );
} }
} }
@ -955,10 +952,11 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveMainLoop()
return st; return st;
} }
OPT_BOX2I PNS_SHOVE::totalAffectedArea ( ) const
OPT_BOX2I PNS_SHOVE::totalAffectedArea() const
{ {
OPT_BOX2I area; OPT_BOX2I area;
if(!m_nodeStack.empty()) if( !m_nodeStack.empty() )
area = m_nodeStack.back().m_affectedArea; area = m_nodeStack.back().m_affectedArea;
if( area ) if( area )
@ -1047,7 +1045,6 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
} }
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet ) PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet )
{ {
SHOVE_STATUS st = SH_OK; SHOVE_STATUS st = SH_OK;
@ -1056,18 +1053,17 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
PNS_ITEMSET headSet; PNS_ITEMSET headSet;
BOOST_FOREACH ( const PNS_ITEM *item, aHeadSet.CItems() ) BOOST_FOREACH ( const PNS_ITEM* item, aHeadSet.CItems() )
{ {
const PNS_LINE *headOrig = static_cast<const PNS_LINE*> (item); const PNS_LINE* headOrig = static_cast<const PNS_LINE*>( item );
// empty head? nothing to shove... // empty head? nothing to shove...
if( !headOrig->SegmentCount() ) if( !headOrig->SegmentCount() )
return SH_INCOMPLETE; return SH_INCOMPLETE;
headSet.Add ( clone ( headOrig ) ); headSet.Add( clone( headOrig ) );
} }
m_lineStack.clear(); m_lineStack.clear();
m_optimizerQueue.clear(); m_optimizerQueue.clear();
m_logger.Clear(); m_logger.Clear();
@ -1079,10 +1075,10 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
m_currentNode = parent->Branch(); m_currentNode = parent->Branch();
m_currentNode->ClearRanks(); m_currentNode->ClearRanks();
int n = 0; int n = 0;
BOOST_FOREACH ( const PNS_ITEM *item, aHeadSet.CItems() ) BOOST_FOREACH ( const PNS_ITEM* item, aHeadSet.CItems() )
{ {
const PNS_LINE *headOrig = static_cast<const PNS_LINE*> (item); const PNS_LINE* headOrig = static_cast<const PNS_LINE*>( item );
PNS_LINE *head = clone ( headOrig ); PNS_LINE* head = clone( headOrig );
head->ClearSegmentLinks(); head->ClearSegmentLinks();
m_currentNode->Add( head ); m_currentNode->Add( head );
@ -1128,12 +1124,12 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
return st; return st;
} }
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere, PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere,
PNS_VIA** aNewVia ) PNS_VIA** aNewVia )
{ {
SHOVE_STATUS st = SH_OK; SHOVE_STATUS st = SH_OK;
m_lineStack.clear(); m_lineStack.clear();
m_optimizerQueue.clear(); m_optimizerQueue.clear();
m_newHead = OPT_LINE(); m_newHead = OPT_LINE();
@ -1160,7 +1156,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
if( st == SH_OK || st == SH_HEAD_MODIFIED ) if( st == SH_OK || st == SH_HEAD_MODIFIED )
{ {
pushSpringback( m_currentNode, m_draggedViaHeadSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum); pushSpringback( m_currentNode, m_draggedViaHeadSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum );
} }
else else
{ {
@ -1193,9 +1189,9 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
maxWidth = std::max ( (*i)->Width(), maxWidth ); maxWidth = std::max ( (*i)->Width(), maxWidth );
} }
if(area) if( area )
{ {
area->Inflate ( 10 * maxWidth ); area->Inflate( 10 * maxWidth );
} }
switch( effort ) switch( effort )
@ -1209,7 +1205,7 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS; optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS;
if( area ) if( area )
optimizer.SetRestrictArea ( *area ); optimizer.SetRestrictArea( *area );
n_passes = 2; n_passes = 2;
break; break;
@ -1223,7 +1219,6 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
break; break;
} }
if( Settings().SmartPads() ) if( Settings().SmartPads() )
optFlags |= PNS_OPTIMIZER::SMART_PADS ; optFlags |= PNS_OPTIMIZER::SMART_PADS ;
@ -1254,6 +1249,7 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
} }
} }
PNS_NODE* PNS_SHOVE::CurrentNode() PNS_NODE* PNS_SHOVE::CurrentNode()
{ {
return m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node; return m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;

View File

@ -115,8 +115,7 @@ private:
SHOVE_STATUS onReverseCollidingVia( PNS_LINE* aCurrent, PNS_VIA* aObstacleVia ); SHOVE_STATUS onReverseCollidingVia( PNS_LINE* aCurrent, PNS_VIA* aObstacleVia );
SHOVE_STATUS pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun = false ); SHOVE_STATUS pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun = false );
OPT_BOX2I totalAffectedArea ( ) const; OPT_BOX2I totalAffectedArea() const;
void unwindStack( PNS_SEGMENT* aSeg ); void unwindStack( PNS_SEGMENT* aSeg );
void unwindStack( PNS_ITEM* aItem ); void unwindStack( PNS_ITEM* aItem );
@ -128,7 +127,7 @@ private:
PNS_LINE* assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL ); PNS_LINE* assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL );
void replaceItems ( PNS_ITEM *aOld, PNS_ITEM *aNew ); void replaceItems( PNS_ITEM *aOld, PNS_ITEM *aNew );
template<class T> T* clone ( const T* aItem ) template<class T> T* clone ( const T* aItem )
{ {
@ -140,7 +139,6 @@ private:
OPT_BOX2I m_affectedAreaSum; OPT_BOX2I m_affectedAreaSum;
SHOVE_STATUS shoveIteration( int aIter ); SHOVE_STATUS shoveIteration( int aIter );
SHOVE_STATUS shoveMainLoop(); SHOVE_STATUS shoveMainLoop();

View File

@ -66,6 +66,7 @@ int PNS_SIZES_SETTINGS::inheritTrackWidth( PNS_ITEM* aItem )
return ( mval == INT_MAX ? 0 : mval ); return ( mval == INT_MAX ? 0 : mval );
} }
void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet ) void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet )
{ {
BOARD_DESIGN_SETTINGS &bds = aBoard->GetDesignSettings(); BOARD_DESIGN_SETTINGS &bds = aBoard->GetDesignSettings();
@ -121,11 +122,13 @@ void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet )
m_layerPairs.clear(); m_layerPairs.clear();
} }
void PNS_SIZES_SETTINGS::ClearLayerPairs() void PNS_SIZES_SETTINGS::ClearLayerPairs()
{ {
m_layerPairs.clear(); m_layerPairs.clear();
} }
void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 ) void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 )
{ {
int top = std::min( aL1, aL2 ); int top = std::min( aL1, aL2 );
@ -135,6 +138,7 @@ void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 )
m_layerPairs[top] = bottom; m_layerPairs[top] = bottom;
} }
void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings ) void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings )
{ {
m_trackWidth = aSettings.GetCurrentTrackWidth(); m_trackWidth = aSettings.GetCurrentTrackWidth();
@ -142,6 +146,7 @@ void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings )
m_viaDrill = aSettings.GetCurrentViaDrill(); m_viaDrill = aSettings.GetCurrentViaDrill();
} }
int PNS_SIZES_SETTINGS::GetLayerTop() const int PNS_SIZES_SETTINGS::GetLayerTop() const
{ {
if( m_layerPairs.empty() ) if( m_layerPairs.empty() )
@ -150,6 +155,7 @@ int PNS_SIZES_SETTINGS::GetLayerTop() const
return m_layerPairs.begin()->first; return m_layerPairs.begin()->first;
} }
int PNS_SIZES_SETTINGS::GetLayerBottom() const int PNS_SIZES_SETTINGS::GetLayerBottom() const
{ {
if( m_layerPairs.empty() ) if( m_layerPairs.empty() )

View File

@ -47,7 +47,7 @@ public:
~PNS_SIZES_SETTINGS() {}; ~PNS_SIZES_SETTINGS() {};
void Init( BOARD* aBoard, PNS_ITEM* aStartItem = NULL, int aNet = -1 ); void Init( BOARD* aBoard, PNS_ITEM* aStartItem = NULL, int aNet = -1 );
void ImportCurrent ( BOARD_DESIGN_SETTINGS& aSettings ); void ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings );
void ClearLayerPairs(); void ClearLayerPairs();
void AddLayerPair( int aL1, int aL2 ); void AddLayerPair( int aL1, int aL2 );
@ -83,7 +83,7 @@ public:
if( m_layerPairs.find(aLayerId) == m_layerPairs.end() ) if( m_layerPairs.find(aLayerId) == m_layerPairs.end() )
return boost::optional<int>(); return boost::optional<int>();
return m_layerPairs [ aLayerId ]; return m_layerPairs[aLayerId];
} }
int GetLayerTop() const; int GetLayerTop() const;

View File

@ -62,7 +62,7 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
} }
PNS_ITEM* PNS_SOLID::Clone ( ) const PNS_ITEM* PNS_SOLID::Clone() const
{ {
PNS_ITEM* solid = new PNS_SOLID( *this ); PNS_ITEM* solid = new PNS_SOLID( *this );
return solid; return solid;

View File

@ -43,7 +43,7 @@ public:
} }
PNS_SOLID( const PNS_SOLID& aSolid ) : PNS_SOLID( const PNS_SOLID& aSolid ) :
PNS_ITEM ( aSolid ) PNS_ITEM( aSolid )
{ {
m_shape = aSolid.m_shape->Clone(); m_shape = aSolid.m_shape->Clone();
m_pos = aSolid.m_pos; m_pos = aSolid.m_pos;

View File

@ -95,6 +95,7 @@ void PNS_TOOL_BASE::Reset( RESET_REASON aReason )
m_router->SetView( getView() ); m_router->SetView( getView() );
} }
PNS_ITEM* PNS_TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer ) PNS_ITEM* PNS_TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer )
{ {
int tl = getView()->GetTopLayer(); int tl = getView()->GetTopLayer();
@ -138,7 +139,7 @@ PNS_ITEM* PNS_TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int a
} }
PNS_ITEM* rv = NULL; PNS_ITEM* rv = NULL;
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME> (); PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)frame->GetDisplayOptions(); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)frame->GetDisplayOptions();
for( int i = 0; i < 4; i++ ) for( int i = 0; i < 4; i++ )
@ -178,6 +179,7 @@ void PNS_TOOL_BASE::highlightNet( bool aEnabled, int aNetcode )
getView()->UpdateAllLayersColor(); getView()->UpdateAllLayersColor();
} }
void PNS_TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent ) void PNS_TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent )
{ {
int tl = getView()->GetTopLayer(); int tl = getView()->GetTopLayer();
@ -227,6 +229,7 @@ void PNS_TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent )
} }
} }
void PNS_TOOL_BASE::updateEndItem( TOOL_EVENT& aEvent ) void PNS_TOOL_BASE::updateEndItem( TOOL_EVENT& aEvent )
{ {
VECTOR2I mp = m_ctls->GetMousePosition(); VECTOR2I mp = m_ctls->GetMousePosition();

View File

@ -65,9 +65,9 @@ protected:
///> Flag marking that the router's world needs syncing. ///> Flag marking that the router's world needs syncing.
bool m_needsSync; bool m_needsSync;
PCB_EDIT_FRAME *m_frame; PCB_EDIT_FRAME* m_frame;
KIGFX::VIEW_CONTROLS *m_ctls; KIGFX::VIEW_CONTROLS* m_ctls;
BOARD *m_board; BOARD* m_board;
}; };

View File

@ -30,31 +30,31 @@
#include <class_board.h> #include <class_board.h>
bool PNS_TOPOLOGY::SimplifyLine ( PNS_LINE *aLine ) bool PNS_TOPOLOGY::SimplifyLine( PNS_LINE* aLine )
{ {
if( !aLine->LinkedSegments() || !aLine->SegmentCount() ) if( !aLine->LinkedSegments() || !aLine->SegmentCount() )
return false; return false;
PNS_SEGMENT *root = (*aLine->LinkedSegments())[0]; PNS_SEGMENT* root = ( *aLine->LinkedSegments() )[0];
std::auto_ptr<PNS_LINE> l ( m_world->AssembleLine( root ) ); std::auto_ptr<PNS_LINE> l( m_world->AssembleLine( root ) );
SHAPE_LINE_CHAIN simplified ( l->CLine() ); SHAPE_LINE_CHAIN simplified( l->CLine() );
simplified.Simplify(); simplified.Simplify();
if( simplified.PointCount() != l->PointCount() ) if( simplified.PointCount() != l->PointCount() )
{ {
std::auto_ptr<PNS_LINE> lnew ( l->Clone() ); std::auto_ptr<PNS_LINE> lnew( l->Clone() );
m_world -> Remove( l.get() ); m_world->Remove( l.get() );
lnew->SetShape( simplified ); lnew->SetShape( simplified );
m_world -> Add( lnew.get() ); m_world->Add( lnew.get() );
return true; return true;
} }
return false; return false;
} }
const PNS_TOPOLOGY::JOINT_SET PNS_TOPOLOGY::ConnectedJoints ( PNS_JOINT* aStart )
const PNS_TOPOLOGY::JOINT_SET PNS_TOPOLOGY::ConnectedJoints( PNS_JOINT* aStart )
{ {
std::deque<PNS_JOINT*> searchQueue; std::deque<PNS_JOINT*> searchQueue;
JOINT_SET processed; JOINT_SET processed;
@ -69,9 +69,9 @@ const PNS_TOPOLOGY::JOINT_SET PNS_TOPOLOGY::ConnectedJoints ( PNS_JOINT* aStart
BOOST_FOREACH( PNS_ITEM* item, current->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, current->LinkList() )
{ {
if ( item->OfKind( PNS_ITEM::SEGMENT ) ) if( item->OfKind( PNS_ITEM::SEGMENT ) )
{ {
PNS_SEGMENT* seg = static_cast<PNS_SEGMENT *>( item ); PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
PNS_JOINT* a = m_world->FindJoint( seg->Seg().A, seg ); PNS_JOINT* a = m_world->FindJoint( seg->Seg().A, seg );
PNS_JOINT* b = m_world->FindJoint( seg->Seg().B, seg ); PNS_JOINT* b = m_world->FindJoint( seg->Seg().B, seg );
PNS_JOINT* next = ( *a == *current ) ? b : a; PNS_JOINT* next = ( *a == *current ) ? b : a;
@ -89,29 +89,31 @@ const PNS_TOPOLOGY::JOINT_SET PNS_TOPOLOGY::ConnectedJoints ( PNS_JOINT* aStart
} }
bool PNS_TOPOLOGY::LeadingRatLine( const PNS_LINE *aTrack, SHAPE_LINE_CHAIN& aRatLine ) bool PNS_TOPOLOGY::LeadingRatLine( const PNS_LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine )
{ {
PNS_LINE track ( *aTrack ); PNS_LINE track( *aTrack );
VECTOR2I end; VECTOR2I end;
if( !track.PointCount() ) if( !track.PointCount() )
return false; return false;
std::auto_ptr<PNS_NODE> tmpNode ( m_world->Branch() ); std::auto_ptr<PNS_NODE> tmpNode( m_world->Branch() );
tmpNode->Add( &track ); tmpNode->Add( &track );
PNS_JOINT* jt = tmpNode->FindJoint( track.CPoint( -1 ), &track ); PNS_JOINT* jt = tmpNode->FindJoint( track.CPoint( -1 ), &track );
if ( !jt ) if( !jt )
return false; return false;
if( (!track.EndsWithVia() && jt->LinkCount() >= 2) || (track.EndsWithVia() && jt->LinkCount() >= 3 )) // we got something connected if( ( !track.EndsWithVia() && jt->LinkCount() >= 2 ) || ( track.EndsWithVia() && jt->LinkCount() >= 3 ) ) // we got something connected
{ {
end = jt->Pos(); end = jt->Pos();
} else { }
else
{
int anchor; int anchor;
PNS_TOPOLOGY topo ( tmpNode.get() ); PNS_TOPOLOGY topo( tmpNode.get() );
PNS_ITEM* it = topo.NearestUnconnectedItem( jt, &anchor ); PNS_ITEM* it = topo.NearestUnconnectedItem( jt, &anchor );
if( !it ) if( !it )
@ -121,8 +123,8 @@ bool PNS_TOPOLOGY::LeadingRatLine( const PNS_LINE *aTrack, SHAPE_LINE_CHAIN& aRa
} }
aRatLine.Clear(); aRatLine.Clear();
aRatLine.Append ( track.CPoint( -1 ) ); aRatLine.Append( track.CPoint( -1 ) );
aRatLine.Append ( end ); aRatLine.Append( end );
return true; return true;
} }
@ -132,7 +134,7 @@ PNS_ITEM* PNS_TOPOLOGY::NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor,
m_world->AllItemsInNet( aStart->Net(), disconnected ); m_world->AllItemsInNet( aStart->Net(), disconnected );
BOOST_FOREACH( const PNS_JOINT *jt, ConnectedJoints ( aStart ) ) BOOST_FOREACH( const PNS_JOINT* jt, ConnectedJoints( aStart ) )
{ {
BOOST_FOREACH( PNS_ITEM* link, jt->LinkList() ) BOOST_FOREACH( PNS_ITEM* link, jt->LinkList() )
{ {
@ -169,63 +171,67 @@ PNS_ITEM* PNS_TOPOLOGY::NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor,
} }
bool PNS_TOPOLOGY::followTrivialPath ( PNS_LINE *aLine, bool aLeft, PNS_ITEMSET& aSet, std::set<PNS_ITEM *>& aVisited ) bool PNS_TOPOLOGY::followTrivialPath( PNS_LINE* aLine, bool aLeft, PNS_ITEMSET& aSet, std::set<PNS_ITEM*>& aVisited )
{ {
VECTOR2I anchor = aLeft ? aLine->CPoint(0) : aLine->CPoint(-1); VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
PNS_SEGMENT *last = aLeft ? aLine->LinkedSegments()->front() : aLine->LinkedSegments()->back(); PNS_SEGMENT* last = aLeft ? aLine->LinkedSegments()->front() : aLine->LinkedSegments()->back();
PNS_JOINT *jt = m_world->FindJoint ( anchor, aLine ); PNS_JOINT* jt = m_world->FindJoint( anchor, aLine );
assert (jt != NULL); assert( jt != NULL );
aVisited.insert( last ); aVisited.insert( last );
if( jt->IsNonFanoutVia() ) if( jt->IsNonFanoutVia() )
{ {
PNS_ITEM *via = NULL; PNS_ITEM* via = NULL;
PNS_SEGMENT *next_seg = NULL; PNS_SEGMENT* next_seg = NULL;
BOOST_FOREACH ( PNS_ITEM *link, jt->Links().Items() ) BOOST_FOREACH( PNS_ITEM* link, jt->Links().Items() )
{ {
if( link->OfKind ( PNS_ITEM::VIA ) ) if( link->OfKind( PNS_ITEM::VIA ) )
via = link; via = link;
else if( aVisited.find(link) == aVisited.end() ) else if( aVisited.find( link ) == aVisited.end() )
next_seg = static_cast <PNS_SEGMENT *> (link); next_seg = static_cast<PNS_SEGMENT*>( link );
} }
if(!next_seg) if( !next_seg )
return false; return false;
PNS_LINE *l = m_world->AssembleLine ( next_seg ); PNS_LINE* l = m_world->AssembleLine( next_seg );
VECTOR2I nextAnchor = (aLeft ? l->CLine().CPoint(-1) : l->CLine().CPoint(0) ); VECTOR2I nextAnchor = ( aLeft ? l->CLine().CPoint( -1 ) : l->CLine().CPoint( 0 ) );
if (nextAnchor != anchor) if( nextAnchor != anchor )
{ {
l->Reverse(); l->Reverse();
} }
if (aLeft) if( aLeft )
{ {
aSet.Prepend ( via ); aSet.Prepend( via );
aSet.Prepend ( l ); aSet.Prepend( l );
} else { }
aSet.Add ( via ); else
aSet.Add ( l ); {
aSet.Add( via );
aSet.Add( l );
} }
return followTrivialPath ( l, aLeft, aSet, aVisited ); return followTrivialPath( l, aLeft, aSet, aVisited );
} }
return false; return false;
} }
const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath ( PNS_SEGMENT *aStart )
const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath( PNS_SEGMENT* aStart )
{ {
PNS_ITEMSET path; PNS_ITEMSET path;
std::set<PNS_ITEM *> visited; std::set<PNS_ITEM*> visited;
PNS_LINE *l = m_world->AssembleLine ( aStart ); PNS_LINE* l = m_world->AssembleLine( aStart );
path.Add ( l ); path.Add( l );
followTrivialPath( l, false, path, visited ); followTrivialPath( l, false, path, visited );
followTrivialPath( l, true, path, visited ); followTrivialPath( l, true, path, visited );
@ -233,39 +239,47 @@ const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath ( PNS_SEGMENT *aStart )
return path; return path;
} }
const PNS_ITEMSET PNS_TOPOLOGY::ConnectedItems( PNS_JOINT* aStart, int aKindMask ) const PNS_ITEMSET PNS_TOPOLOGY::ConnectedItems( PNS_JOINT* aStart, int aKindMask )
{ {
return PNS_ITEMSET(); return PNS_ITEMSET();
} }
const PNS_ITEMSET PNS_TOPOLOGY::ConnectedItems( PNS_ITEM* aStart, int aKindMask ) const PNS_ITEMSET PNS_TOPOLOGY::ConnectedItems( PNS_ITEM* aStart, int aKindMask )
{ {
return PNS_ITEMSET(); return PNS_ITEMSET();
} }
int PNS_TOPOLOGY::MatchDpSuffix ( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
int PNS_TOPOLOGY::MatchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
{ {
int rv = 0; int rv = 0;
if (aNetName.EndsWith("+"))
if( aNetName.EndsWith( "+" ) )
{ {
aComplementNet = "-"; aComplementNet = "-";
rv = 1; rv = 1;
} else if (aNetName.EndsWith("_P")) }
else if( aNetName.EndsWith( "_P" ) )
{ {
aComplementNet = "_N"; aComplementNet = "_N";
rv = 1; rv = 1;
} else if (aNetName.EndsWith("-")) }
else if( aNetName.EndsWith( "-" ) )
{ {
aComplementNet = "+"; aComplementNet = "+";
rv = -1; rv = -1;
} else if (aNetName.EndsWith("_N")) }
else if( aNetName.EndsWith( "_N" ) )
{ {
aComplementNet = "_P"; aComplementNet = "_P";
rv = -1; rv = -1;
} }
if (rv != 0) { if( rv != 0 )
aBaseDpName = aNetName.Left ( aNetName.Length() - aComplementNet.Length() ); {
aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
aComplementNet = aBaseDpName + aComplementNet; aComplementNet = aBaseDpName + aComplementNet;
} }
@ -275,16 +289,16 @@ int PNS_TOPOLOGY::MatchDpSuffix ( wxString aNetName, wxString& aComplementNet, w
int PNS_TOPOLOGY::DpCoupledNet( int aNet ) int PNS_TOPOLOGY::DpCoupledNet( int aNet )
{ {
BOARD *brd = PNS_ROUTER::GetInstance()->GetBoard(); BOARD* brd = PNS_ROUTER::GetInstance()->GetBoard();
wxString refName = brd->FindNet ( aNet )->GetNetname(); wxString refName = brd->FindNet( aNet )->GetNetname();
wxString dummy, coupledNetName; wxString dummy, coupledNetName;
if ( MatchDpSuffix ( refName, coupledNetName, dummy ) ) if( MatchDpSuffix( refName, coupledNetName, dummy ) )
{ {
NETINFO_ITEM *net = brd->FindNet ( coupledNetName ); NETINFO_ITEM* net = brd->FindNet( coupledNetName );
if(!net) if( !net )
return -1; return -1;
return net->GetNet(); return net->GetNet();
@ -297,24 +311,24 @@ int PNS_TOPOLOGY::DpCoupledNet( int aNet )
int PNS_TOPOLOGY::DpNetPolarity( int aNet ) int PNS_TOPOLOGY::DpNetPolarity( int aNet )
{ {
BOARD *brd = PNS_ROUTER::GetInstance()->GetBoard(); BOARD* brd = PNS_ROUTER::GetInstance()->GetBoard();
wxString refName = brd->FindNet ( aNet )->GetNetname(); wxString refName = brd->FindNet( aNet )->GetNetname();
wxString dummy1, dummy2; wxString dummy1, dummy2;
return MatchDpSuffix ( refName, dummy1, dummy2 ); return MatchDpSuffix( refName, dummy1, dummy2 );
} }
bool PNS_TOPOLOGY::AssembleDiffPair ( PNS_ITEM *aStart, PNS_DIFF_PAIR& aPair ) bool PNS_TOPOLOGY::AssembleDiffPair( PNS_ITEM* aStart, PNS_DIFF_PAIR& aPair )
{ {
int refNet = aStart->Net(); int refNet = aStart->Net();
int coupledNet = DpCoupledNet ( refNet ); int coupledNet = DpCoupledNet( refNet );
if(coupledNet < 0) if( coupledNet < 0 )
return false; return false;
std::set<PNS_ITEM *> coupledItems; std::set<PNS_ITEM*> coupledItems;
m_world->AllItemsInNet( coupledNet, coupledItems ); m_world->AllItemsInNet( coupledNet, coupledItems );
@ -323,15 +337,15 @@ bool PNS_TOPOLOGY::AssembleDiffPair ( PNS_ITEM *aStart, PNS_DIFF_PAIR& aPair )
if( ( refSeg = dyn_cast<PNS_SEGMENT*>( aStart ) ) != NULL ) if( ( refSeg = dyn_cast<PNS_SEGMENT*>( aStart ) ) != NULL )
{ {
BOOST_FOREACH ( PNS_ITEM *item, coupledItems ) BOOST_FOREACH( PNS_ITEM* item, coupledItems )
{ {
if ( PNS_SEGMENT *s = dyn_cast<PNS_SEGMENT* >(item) ) if( PNS_SEGMENT* s = dyn_cast<PNS_SEGMENT*>( item ) )
{ {
if( s->Layers().Start() == refSeg->Layers().Start() && s->Width() == refSeg->Width() ) if( s->Layers().Start() == refSeg->Layers().Start() && s->Width() == refSeg->Width() )
{ {
int dist = s->Seg().Distance( refSeg->Seg() ); int dist = s->Seg().Distance( refSeg->Seg() );
if(dist < minDist) if( dist < minDist )
{ {
minDist = dist; minDist = dist;
coupledSeg = s; coupledSeg = s;
@ -342,19 +356,20 @@ bool PNS_TOPOLOGY::AssembleDiffPair ( PNS_ITEM *aStart, PNS_DIFF_PAIR& aPair )
} else } else
return false; return false;
if(!coupledSeg) if( !coupledSeg )
return false; return false;
std::auto_ptr<PNS_LINE> lp ( m_world->AssembleLine ( refSeg ) ); std::auto_ptr<PNS_LINE> lp ( m_world->AssembleLine( refSeg ) );
std::auto_ptr<PNS_LINE> ln ( m_world->AssembleLine ( coupledSeg ) ); std::auto_ptr<PNS_LINE> ln ( m_world->AssembleLine( coupledSeg ) );
if(DpNetPolarity(refNet) < 0) if( DpNetPolarity( refNet ) < 0 )
{ {
std::swap (lp, ln); std::swap( lp, ln );
} }
aPair = PNS_DIFF_PAIR ( *lp, *ln ); aPair = PNS_DIFF_PAIR( *lp, *ln );
aPair.SetWidth ( lp->Width() ); aPair.SetWidth( lp->Width() );
aPair.SetLayers ( lp->Layers() ); aPair.SetLayers( lp->Layers() );
return true; return true;
} }

View File

@ -35,39 +35,34 @@ class PNS_DIFF_PAIR;
class PNS_TOPOLOGY class PNS_TOPOLOGY
{ {
public: public:
typedef std::set<PNS_JOINT *> JOINT_SET; typedef std::set<PNS_JOINT*> JOINT_SET;
PNS_TOPOLOGY ( PNS_NODE *aNode ): PNS_TOPOLOGY( PNS_NODE* aNode ):
m_world ( aNode ) {}; m_world( aNode ) {};
~PNS_TOPOLOGY ( ) {}; ~PNS_TOPOLOGY() {};
bool SimplifyLine ( PNS_LINE *aLine ); bool SimplifyLine( PNS_LINE *aLine );
PNS_ITEM* NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor = NULL, int aKindMask = PNS_ITEM::ANY ); PNS_ITEM* NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor = NULL, int aKindMask = PNS_ITEM::ANY );
bool LeadingRatLine( const PNS_LINE *aTrack, SHAPE_LINE_CHAIN& aRatLine ); bool LeadingRatLine( const PNS_LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine );
const JOINT_SET ConnectedJoints ( PNS_JOINT* aStart ); const JOINT_SET ConnectedJoints( PNS_JOINT* aStart );
const PNS_ITEMSET ConnectedItems ( PNS_JOINT* aStart, int aKindMask = PNS_ITEM::ANY ); const PNS_ITEMSET ConnectedItems( PNS_JOINT* aStart, int aKindMask = PNS_ITEM::ANY );
const PNS_ITEMSET ConnectedItems ( PNS_ITEM* aStart, int aKindMask = PNS_ITEM::ANY ); const PNS_ITEMSET ConnectedItems( PNS_ITEM* aStart, int aKindMask = PNS_ITEM::ANY );
int64_t ShortestConnectionLength ( PNS_ITEM *aFrom, PNS_ITEM *aTo ); int64_t ShortestConnectionLength( PNS_ITEM* aFrom, PNS_ITEM* aTo );
const PNS_ITEMSET AssembleTrivialPath( PNS_SEGMENT* aStart );
const PNS_DIFF_PAIR AssembleDiffPair( PNS_SEGMENT* aStart );
int MatchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
const PNS_ITEMSET AssembleTrivialPath ( PNS_SEGMENT *aStart );
const PNS_DIFF_PAIR AssembleDiffPair ( PNS_SEGMENT *aStart );
int MatchDpSuffix ( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
int DpCoupledNet( int aNet ); int DpCoupledNet( int aNet );
int DpNetPolarity( int aNet ); int DpNetPolarity( int aNet );
const PNS_LINE DpCoupledLine( PNS_LINE *aLine ); const PNS_LINE DpCoupledLine( PNS_LINE* aLine );
bool AssembleDiffPair ( PNS_ITEM *aStart, PNS_DIFF_PAIR& aPair ); bool AssembleDiffPair( PNS_ITEM* aStart, PNS_DIFF_PAIR& aPair );
private:
bool followTrivialPath( PNS_LINE* aLine, bool aLeft, PNS_ITEMSET& aSet, std::set<PNS_ITEM*>& aVisited );
private:
bool followTrivialPath ( PNS_LINE *aLine, bool aLeft, PNS_ITEMSET& aSet, std::set<PNS_ITEM *>& aVisited );
PNS_NODE *m_world; PNS_NODE *m_world;
}; };

View File

@ -22,47 +22,47 @@
#include "pns_router.h" #include "pns_router.h"
#include "pns_meander_placer.h" #include "pns_meander_placer.h"
PNS_TUNE_STATUS_POPUP::PNS_TUNE_STATUS_POPUP ( PCB_EDIT_FRAME *parent ) : PNS_TUNE_STATUS_POPUP::PNS_TUNE_STATUS_POPUP( PCB_EDIT_FRAME* aParent ) :
WX_STATUS_POPUP ( parent ) WX_STATUS_POPUP( aParent )
{ {
m_panel->SetBackgroundColour( wxColour(64,64,64) ); m_panel->SetBackgroundColour( wxColour( 64, 64, 64 ) );
m_statusLine = new wxStaticText( m_panel, wxID_ANY, m_statusLine = new wxStaticText( m_panel, wxID_ANY, wxT( "Status text 1\n" ) ) ;
wxT("Status text 1\n") ) ;
m_topSizer->Add( m_statusLine, 1, wxALL | wxEXPAND, 5 ); m_topSizer->Add( m_statusLine, 1, wxALL | wxEXPAND, 5 );
updateSize(); updateSize();
} }
PNS_TUNE_STATUS_POPUP::~PNS_TUNE_STATUS_POPUP() PNS_TUNE_STATUS_POPUP::~PNS_TUNE_STATUS_POPUP()
{ {
} }
void PNS_TUNE_STATUS_POPUP::Update( PNS_ROUTER *aRouter )
{
PNS_MEANDER_PLACER_BASE *placer = dynamic_cast <PNS_MEANDER_PLACER_BASE *> ( aRouter->Placer() );
if(!placer) void PNS_TUNE_STATUS_POPUP::Update( PNS_ROUTER* aRouter )
{
PNS_MEANDER_PLACER_BASE* placer = dynamic_cast<PNS_MEANDER_PLACER_BASE*>( aRouter->Placer() );
if( !placer )
return; return;
m_statusLine->SetLabel ( placer->TuningInfo() ); m_statusLine->SetLabel( placer->TuningInfo() );
wxColour color; wxColour color;
switch ( placer->TuningStatus() ) switch( placer->TuningStatus() )
{ {
case PNS_MEANDER_PLACER::TUNED: case PNS_MEANDER_PLACER::TUNED:
color = wxColour ( 0, 255, 0 ); color = wxColour( 0, 255, 0 );
break; break;
case PNS_MEANDER_PLACER::TOO_SHORT: case PNS_MEANDER_PLACER::TOO_SHORT:
color = wxColour ( 255, 128, 128 ); color = wxColour( 255, 128, 128 );
break; break;
case PNS_MEANDER_PLACER::TOO_LONG: case PNS_MEANDER_PLACER::TOO_LONG:
color = wxColour ( 128, 128, 255 ); color = wxColour( 128, 128, 255 );
break; break;
} }
m_statusLine->SetForegroundColour (color); m_statusLine->SetForegroundColour( color );
updateSize(); updateSize();
} }

View File

@ -32,14 +32,13 @@ class PNS_ROUTER;
class PNS_TUNE_STATUS_POPUP : public WX_STATUS_POPUP class PNS_TUNE_STATUS_POPUP : public WX_STATUS_POPUP
{ {
public: public:
PNS_TUNE_STATUS_POPUP ( PCB_EDIT_FRAME *parent ); PNS_TUNE_STATUS_POPUP( PCB_EDIT_FRAME* aParent );
~PNS_TUNE_STATUS_POPUP(); ~PNS_TUNE_STATUS_POPUP();
void Update( PNS_ROUTER* aRouter );
void Update( PNS_ROUTER *aRouter );
private: private:
wxStaticText *m_statusLine; wxStaticText* m_statusLine;
}; };
#endif /* __PNS_TUNE_STATUS_POPUP_H_*/ #endif /* __PNS_TUNE_STATUS_POPUP_H_*/

View File

@ -93,82 +93,86 @@ SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg )
std::abs( p1.x - p0.x ), std::abs( p1.y - p0.y ) ); std::abs( p1.x - p0.x ), std::abs( p1.y - p0.y ) );
} }
void DrawDebugPoint ( VECTOR2I p, int color )
void DrawDebugPoint( VECTOR2I aP, int aColor )
{ {
SHAPE_LINE_CHAIN l; SHAPE_LINE_CHAIN l;
l.Append ( p - VECTOR2I(-50000, -50000) ); l.Append( aP - VECTOR2I( -50000, -50000 ) );
l.Append ( p + VECTOR2I(-50000, -50000) ); l.Append( aP + VECTOR2I( -50000, -50000 ) );
//printf("router @ %p\n", PNS_ROUTER::GetInstance()); //printf("router @ %p\n", PNS_ROUTER::GetInstance());
PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 ); PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, aColor, 10000 );
l.Clear(); l.Clear();
l.Append ( p - VECTOR2I(50000, -50000) ); l.Append( aP - VECTOR2I( 50000, -50000 ) );
l.Append ( p + VECTOR2I(50000, -50000) ); l.Append( aP + VECTOR2I( 50000, -50000 ) );
PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 ); PNS_ROUTER::GetInstance()->DisplayDebugLine( l, aColor, 10000 );
} }
void DrawDebugBox ( BOX2I b, int color )
void DrawDebugBox( BOX2I aB, int aColor )
{ {
SHAPE_LINE_CHAIN l; SHAPE_LINE_CHAIN l;
VECTOR2I o = b.GetOrigin(); VECTOR2I o = aB.GetOrigin();
VECTOR2I s = b.GetSize(); VECTOR2I s = aB.GetSize();
l.Append ( o ); l.Append( o );
l.Append ( o.x + s.x, o.y ); l.Append( o.x + s.x, o.y );
l.Append ( o.x + s.x, o.y + s.y ); l.Append( o.x + s.x, o.y + s.y );
l.Append ( o.x, o.y + s.y ); l.Append( o.x, o.y + s.y );
l.Append ( o ); l.Append( o );
//printf("router @ %p\n", PNS_ROUTER::GetInstance()); //printf("router @ %p\n", PNS_ROUTER::GetInstance());
PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 ); PNS_ROUTER::GetInstance()->DisplayDebugLine( l, aColor, 10000 );
} }
void DrawDebugSeg ( SEG s, int color )
void DrawDebugSeg( SEG aS, int aColor )
{ {
SHAPE_LINE_CHAIN l; SHAPE_LINE_CHAIN l;
l.Append ( s.A ); l.Append( aS.A );
l.Append ( s.B ); l.Append( aS.B );
PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 ); PNS_ROUTER::GetInstance()->DisplayDebugLine( l, aColor, 10000 );
} }
void DrawDebugDirs ( VECTOR2D p, int mask, int color )
void DrawDebugDirs( VECTOR2D aP, int aMask, int aColor )
{ {
BOX2I b ( p - VECTOR2I ( 10000, 10000 ), VECTOR2I ( 20000, 20000 ) ); BOX2I b( aP - VECTOR2I( 10000, 10000 ), VECTOR2I( 20000, 20000 ) );
DrawDebugBox ( b, color ); DrawDebugBox( b, aColor );
for (int i = 0; i < 8; i++) for( int i = 0; i < 8; i++ )
{ {
if ( (1<<i) & mask ) if( ( 1 << i ) & aMask )
{ {
VECTOR2I v = DIRECTION_45((DIRECTION_45::Directions)i).ToVector() * 100000; VECTOR2I v = DIRECTION_45( ( DIRECTION_45::Directions ) i ).ToVector() * 100000;
DrawDebugSeg ( SEG (p, p+v), color ); DrawDebugSeg( SEG( aP, aP + v ), aColor );
} }
} }
} }
OPT_BOX2I ChangedArea ( const PNS_ITEM *aItemA, const PNS_ITEM *aItemB ) OPT_BOX2I ChangedArea( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB )
{ {
if ( aItemA->OfKind ( PNS_ITEM::VIA ) && aItemB->OfKind ( PNS_ITEM::VIA ) ) if( aItemA->OfKind( PNS_ITEM::VIA ) && aItemB->OfKind( PNS_ITEM::VIA ) )
{ {
const PNS_VIA *va = static_cast <const PNS_VIA *> (aItemA); const PNS_VIA* va = static_cast<const PNS_VIA*>( aItemA );
const PNS_VIA *vb = static_cast <const PNS_VIA *> (aItemB); const PNS_VIA* vb = static_cast<const PNS_VIA*>( aItemB );
return va->ChangedArea (vb); return va->ChangedArea( vb );
} else if ( aItemA->OfKind ( PNS_ITEM::LINE ) && aItemB->OfKind ( PNS_ITEM::LINE ) )
{
const PNS_LINE *la = static_cast <const PNS_LINE *> (aItemA);
const PNS_LINE *lb = static_cast <const PNS_LINE *> (aItemB);
return la->ChangedArea (lb);
} }
else if( aItemA->OfKind( PNS_ITEM::LINE ) && aItemB->OfKind( PNS_ITEM::LINE ) )
{
const PNS_LINE* la = static_cast<const PNS_LINE*> ( aItemA );
const PNS_LINE* lb = static_cast<const PNS_LINE*> ( aItemB );
return la->ChangedArea( lb );
}
return OPT_BOX2I(); return OPT_BOX2I();
} }

View File

@ -41,12 +41,12 @@ const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg ); SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg );
void DrawDebugPoint ( VECTOR2I p, int color ); void DrawDebugPoint( VECTOR2I aP, int aColor );
void DrawDebugBox ( BOX2I b, int color ); void DrawDebugBox( BOX2I aB, int aColor );
void DrawDebugSeg ( SEG s, int color ); void DrawDebugSeg( SEG aS, int aColor );
void DrawDebugDirs ( VECTOR2D p, int mask, int color ); void DrawDebugDirs( VECTOR2D aP, int aMask, int aColor );
OPT_BOX2I ChangedArea ( const PNS_ITEM *aItemA, const PNS_ITEM *aItemB ); OPT_BOX2I ChangedArea( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB );
#endif // __PNS_UTILS_H #endif // __PNS_UTILS_H

View File

@ -96,12 +96,13 @@ PNS_VIA* PNS_VIA::Clone ( ) const
return v; return v;
} }
OPT_BOX2I PNS_VIA::ChangedArea ( const PNS_VIA *aOther ) const
OPT_BOX2I PNS_VIA::ChangedArea ( const PNS_VIA* aOther ) const
{ {
if ( aOther->Pos() != Pos() ) if ( aOther->Pos() != Pos() )
{ {
BOX2I tmp = Shape()->BBox( ); BOX2I tmp = Shape()->BBox();
tmp.Merge ( aOther->Shape()->BBox( ) ); tmp.Merge ( aOther->Shape()->BBox() );
return tmp; return tmp;
} }

View File

@ -146,7 +146,7 @@ public:
return 1; return 1;
} }
OPT_BOX2I ChangedArea ( const PNS_VIA *aOther ) const; OPT_BOX2I ChangedArea( const PNS_VIA* aOther ) const;
private: private:
int m_diameter; int m_diameter;

View File

@ -99,7 +99,7 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
pnew.Append( path_walk[1] ); pnew.Append( path_walk[1] );
pnew.Append( path_post[1] ); pnew.Append( path_post[1] );
if(!path_post[1].PointCount() || !path_walk[1].PointCount()) if( !path_post[1].PointCount() || !path_walk[1].PointCount() )
current_obs = nearestObstacle( PNS_LINE( aPath, path_pre[1] ) ); current_obs = nearestObstacle( PNS_LINE( aPath, path_pre[1] ) );
else else
current_obs = nearestObstacle( PNS_LINE( aPath, path_post[1] ) ); current_obs = nearestObstacle( PNS_LINE( aPath, path_post[1] ) );
@ -111,7 +111,7 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
pnew.Append( path_walk[0] ); pnew.Append( path_walk[0] );
pnew.Append( path_post[0] ); pnew.Append( path_post[0] );
if(!path_post[0].PointCount() || !path_walk[0].PointCount()) if( !path_post[0].PointCount() || !path_walk[0].PointCount() )
current_obs = nearestObstacle( PNS_LINE( aPath, path_pre[0] ) ); current_obs = nearestObstacle( PNS_LINE( aPath, path_pre[0] ) );
else else
current_obs = nearestObstacle( PNS_LINE( aPath, path_walk[0] ) ); current_obs = nearestObstacle( PNS_LINE( aPath, path_walk[0] ) );
@ -146,14 +146,12 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::Route( const PNS_LINE& aInitia
aWalkPath = aInitialPath; aWalkPath = aInitialPath;
if(m_forceWinding) if( m_forceWinding )
{ {
s_cw = m_forceCw ? IN_PROGRESS : STUCK; s_cw = m_forceCw ? IN_PROGRESS : STUCK;
s_ccw = m_forceCw ? STUCK : IN_PROGRESS; s_ccw = m_forceCw ? STUCK : IN_PROGRESS;
m_forceSingleDirection = true; m_forceSingleDirection = true;
} else { } else {
m_forceSingleDirection = false; m_forceSingleDirection = false;
} }
@ -171,9 +169,9 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::Route( const PNS_LINE& aInitia
int len_ccw = path_ccw.CLine().Length(); int len_ccw = path_ccw.CLine().Length();
if( m_forceLongerPath ) if( m_forceLongerPath )
aWalkPath = (len_cw > len_ccw ? path_cw : path_ccw); aWalkPath = ( len_cw > len_ccw ? path_cw : path_ccw );
else else
aWalkPath = (len_cw < len_ccw ? path_cw : path_ccw); aWalkPath = ( len_cw < len_ccw ? path_cw : path_ccw );
break; break;
} }
@ -253,7 +251,5 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::Route( const PNS_LINE& aInitia
PNS_OPTIMIZER::Optimize( &aWalkPath, PNS_OPTIMIZER::MERGE_OBTUSE, m_world ); PNS_OPTIMIZER::Optimize( &aWalkPath, PNS_OPTIMIZER::MERGE_OBTUSE, m_world );
} }
return st; return st;
} }

View File

@ -24,7 +24,7 @@
template<class T> template<class T>
class RANGE class RANGE
{ {
public: public:
RANGE( T aMin, T aMax ) : RANGE( T aMin, T aMax ) :
m_min( aMin ), m_min( aMin ),
m_max( aMax ), m_max( aMax ),
@ -85,7 +85,7 @@ class RANGE
return m_defined; return m_defined;
} }
private: private:
T m_min, m_max; T m_min, m_max;
bool m_defined; bool m_defined;
}; };

View File

@ -23,10 +23,10 @@
template <class T> class RANGED_NUM { template <class T> class RANGED_NUM {
public: public:
RANGED_NUM ( T aValue = 0, T aTollerancePlus = 0, T aTolleranceMinus = 0) : RANGED_NUM( T aValue = 0, T aTolerancePlus = 0, T aToleranceMinus = 0 ) :
m_value (aValue), m_value( aValue ),
m_tollerancePlus ( aTollerancePlus ), m_tolerancePlus( aTolerancePlus ),
m_tolleranceMinus ( aTolleranceMinus ) m_toleranceMinus( aToleranceMinus )
{} {}
operator T() operator T()
@ -34,20 +34,19 @@ template <class T> class RANGED_NUM {
return m_value; return m_value;
} }
RANGED_NUM& operator= ( const T aValue ) RANGED_NUM& operator=( const T aValue )
{ {
m_value = aValue; m_value = aValue;
return *this; return *this;
} }
bool Matches ( const T& aOther ) const bool Matches( const T& aOther ) const
{ {
return ( aOther >= m_value - m_tolleranceMinus && aOther <= m_value + m_tollerancePlus ); return ( aOther >= m_value - m_toleranceMinus && aOther <= m_value + m_tolerancePlus );
} }
private: private:
T m_value, m_tollerancePlus, m_tolleranceMinus; T m_value, m_tolerancePlus, m_toleranceMinus;
}; };
#endif #endif

View File

@ -166,11 +166,11 @@ public:
if( bds.m_ViasDimensionsList[i].m_Drill <= 0 ) if( bds.m_ViasDimensionsList[i].m_Drill <= 0 )
{ {
msg << _ (", drill: default"); msg << _(", drill: default");
} }
else else
{ {
msg << _ (", drill: ") << drill; msg << _(", drill: ") << drill;
} }
if( i == 0 ) if( i == 0 )
@ -274,7 +274,7 @@ ROUTER_TOOL::~ROUTER_TOOL()
void ROUTER_TOOL::Reset( RESET_REASON aReason ) void ROUTER_TOOL::Reset( RESET_REASON aReason )
{ {
printf("RESET\n"); //printf("RESET\n");
if( m_router ) if( m_router )
delete m_router; delete m_router;
@ -299,6 +299,7 @@ void ROUTER_TOOL::Reset( RESET_REASON aReason )
Go( &ROUTER_TOOL::TuneSingleTrace, COMMON_ACTIONS::routerActivateTuneSingleTrace.MakeEvent() ); Go( &ROUTER_TOOL::TuneSingleTrace, COMMON_ACTIONS::routerActivateTuneSingleTrace.MakeEvent() );
} }
int ROUTER_TOOL::getDefaultWidth( int aNetCode ) int ROUTER_TOOL::getDefaultWidth( int aNetCode )
{ {
int w, d1, d2; int w, d1, d2;
@ -452,9 +453,9 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
} }
else if( aEvent.IsAction( &ACT_SetLengthTune ) ) else if( aEvent.IsAction( &ACT_SetLengthTune ) )
{ {
PNS_MEANDER_PLACER *placer = dynamic_cast <PNS_MEANDER_PLACER *> ( m_router->Placer() ); PNS_MEANDER_PLACER *placer = dynamic_cast <PNS_MEANDER_PLACER*> ( m_router->Placer() );
if(!placer) if( !placer )
return; return;
PNS_MEANDER_SETTINGS settings = placer->Settings(); PNS_MEANDER_SETTINGS settings = placer->Settings();
@ -479,10 +480,9 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) ) else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) )
{ {
PNS_SIZES_SETTINGS sizes( m_savedSizes );
PNS_SIZES_SETTINGS sizes ( m_savedSizes ); sizes.ImportCurrent( m_board->GetDesignSettings() );
sizes.ImportCurrent ( m_board->GetDesignSettings() ); m_router->UpdateSizes( sizes );
m_router->UpdateSizes ( sizes );
} }
} }
@ -581,6 +581,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent )
TRACE( 0, "%s, layer : %d", m_endItem->KindStr().c_str() % m_endItem->Layers().Start() ); TRACE( 0, "%s, layer : %d", m_endItem->KindStr().c_str() % m_endItem->Layers().Start() );
} }
int ROUTER_TOOL::getStartLayer( const PNS_ITEM* aItem ) int ROUTER_TOOL::getStartLayer( const PNS_ITEM* aItem )
{ {
int tl = getView()->GetTopLayer(); int tl = getView()->GetTopLayer();
@ -597,6 +598,8 @@ int ROUTER_TOOL::getStartLayer( const PNS_ITEM* aItem )
return tl; return tl;
} }
void ROUTER_TOOL::switchLayerOnViaPlacement() void ROUTER_TOOL::switchLayerOnViaPlacement()
{ {
int al = m_frame->GetActiveLayer(); int al = m_frame->GetActiveLayer();
@ -616,6 +619,7 @@ void ROUTER_TOOL::switchLayerOnViaPlacement()
} }
} }
bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType ) bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType )
{ {
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
@ -651,7 +655,6 @@ bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType )
return false; return false;
} }
sizes.SetViaType ( aType ); sizes.SetViaType ( aType );
m_router->ToggleViaPlacement( ); m_router->ToggleViaPlacement( );
m_router->UpdateSizes( sizes ); m_router->UpdateSizes( sizes );
@ -668,8 +671,8 @@ void ROUTER_TOOL::performRouting()
{ {
bool saveUndoBuffer = true; bool saveUndoBuffer = true;
int routingLayer = getStartLayer ( m_startItem ); int routingLayer = getStartLayer( m_startItem );
m_frame->SetActiveLayer( ToLAYER_ID ( routingLayer ) ); m_frame->SetActiveLayer( ToLAYER_ID( routingLayer ) );
// fixme: switch on invisible layer // fixme: switch on invisible layer
if( m_startItem && m_startItem->Net() >= 0 ) if( m_startItem && m_startItem->Net() >= 0 )
@ -686,19 +689,18 @@ void ROUTER_TOOL::performRouting()
PNS_SIZES_SETTINGS sizes ( m_savedSizes ); PNS_SIZES_SETTINGS sizes ( m_savedSizes );
sizes.Init ( m_board, m_startItem ); sizes.Init ( m_board, m_startItem );
sizes.AddLayerPair ( m_frame->GetScreen()->m_Route_Layer_TOP, sizes.AddLayerPair( m_frame->GetScreen()->m_Route_Layer_TOP,
m_frame->GetScreen()->m_Route_Layer_BOTTOM ); m_frame->GetScreen()->m_Route_Layer_BOTTOM );
m_router->UpdateSizes( sizes ); m_router->UpdateSizes( sizes );
if ( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) ) if ( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) )
{ {
wxMessageBox ( m_router->FailureReason(), _("Error") ); wxMessageBox( m_router->FailureReason(), _( "Error" ) );
highlightNet ( false ); highlightNet( false );
return; return;
} }
m_tuneStatusPopup = new PNS_TUNE_STATUS_POPUP( m_frame );
m_tuneStatusPopup = new PNS_TUNE_STATUS_POPUP ( m_frame );
m_tuneStatusPopup->Popup(); m_tuneStatusPopup->Popup();
m_endItem = NULL; m_endItem = NULL;
@ -715,16 +717,14 @@ void ROUTER_TOOL::performRouting()
} }
else if( evt->IsMotion() ) else if( evt->IsMotion() )
{ {
wxPoint p = wxGetMousePosition(); wxPoint p = wxGetMousePosition();
p.x+=20; p.x += 20;
p.y+=20; p.y += 20;
m_tuneStatusPopup->Update (m_router); m_tuneStatusPopup->Update( m_router );
m_tuneStatusPopup->Move(p); m_tuneStatusPopup->Move( p );
updateEndItem( *evt ); updateEndItem( *evt );
m_router->SetOrthoMode ( evt->Modifier ( MD_CTRL ) ); m_router->SetOrthoMode( evt->Modifier ( MD_CTRL ) );
m_router->Move( m_endSnapPoint, m_endItem ); m_router->Move( m_endSnapPoint, m_endItem );
} }
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
@ -796,24 +796,28 @@ void ROUTER_TOOL::performRouting()
highlightNet( false ); highlightNet( false );
} }
int ROUTER_TOOL::RouteSingleTrace( TOOL_EVENT& aEvent ) int ROUTER_TOOL::RouteSingleTrace( TOOL_EVENT& aEvent )
{ {
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Route Track" ) ); m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Route Track" ) );
return mainLoop( PNS_MODE_ROUTE_SINGLE ); return mainLoop( PNS_MODE_ROUTE_SINGLE );
} }
int ROUTER_TOOL::RouteDiffPair( TOOL_EVENT& aEvent ) int ROUTER_TOOL::RouteDiffPair( TOOL_EVENT& aEvent )
{ {
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Router Differential Pair" ) ); m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Router Differential Pair" ) );
return mainLoop( PNS_MODE_ROUTE_DIFF_PAIR ); return mainLoop( PNS_MODE_ROUTE_DIFF_PAIR );
} }
int ROUTER_TOOL::TuneSingleTrace( TOOL_EVENT& aEvent ) int ROUTER_TOOL::TuneSingleTrace( TOOL_EVENT& aEvent )
{ {
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Track Length" ) ); m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Track Length" ) );
return mainLoop( PNS_MODE_TUNE_SINGLE ); return mainLoop( PNS_MODE_TUNE_SINGLE );
} }
int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode ) int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
{ {
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>(); PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
@ -875,7 +879,8 @@ int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
return 0; return 0;
} }
int ROUTER_TOOL::InlineDrag ( TOOL_EVENT& aEvent )
int ROUTER_TOOL::InlineDrag( TOOL_EVENT& aEvent )
{ {
return 0; return 0;
@ -919,6 +924,7 @@ int ROUTER_TOOL::InlineDrag ( TOOL_EVENT& aEvent )
} }
void ROUTER_TOOL::performDragging() void ROUTER_TOOL::performDragging()
{ {
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>(); PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();

View File

@ -57,11 +57,10 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
{ {
m_originLayer = aItem->Layers().Start(); m_originLayer = aItem->Layers().Start();
if( aItem->OfKind ( PNS_ITEM::LINE ) )
if (aItem->OfKind ( PNS_ITEM::LINE ))
{ {
const PNS_LINE *l=static_cast<const PNS_LINE *> (aItem); const PNS_LINE* l=static_cast<const PNS_LINE*>( aItem );
if(!l->SegmentCount()) if( !l->SegmentCount() )
return; return;
} }
@ -139,7 +138,7 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
} }
void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN &aL, KIGFX::GAL* aGal ) const void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN& aL, KIGFX::GAL* aGal ) const
{ {
for( int s = 0; s < aL.SegmentCount(); s++ ) for( int s = 0; s < aL.SegmentCount(); s++ )
aGal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B ); aGal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );

View File

@ -94,12 +94,12 @@ bool EDIT_TOOL::Init()
bool EDIT_TOOL::invokeInlineRouter() bool EDIT_TOOL::invokeInlineRouter()
{ {
TRACK *track = uniqueSelected<TRACK> (); TRACK *track = uniqueSelected<TRACK>();
VIA *via = uniqueSelected<VIA> (); VIA *via = uniqueSelected<VIA>();
if( track || via ) if( track || via )
{ {
printf("Calling interactive drag\n"); //printf("Calling interactive drag\n");
m_toolMgr->RunAction( COMMON_ACTIONS::routerInlineDrag, true ); m_toolMgr->RunAction( COMMON_ACTIONS::routerInlineDrag, true );
return true; return true;
} }
@ -184,15 +184,12 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
VECTOR2I mousePos = evt->Position(); VECTOR2I mousePos = evt->Position();
m_cursor = grid.Align ( evt->Position() ); m_cursor = grid.Align( evt->Position() );
isDragAndDrop = evt->IsDrag( BUT_LEFT ); isDragAndDrop = evt->IsDrag( BUT_LEFT );
if( m_dragging ) if( m_dragging )
{ {
m_cursor = grid.BestSnapAnchor( evt->Position(), selection.Item<BOARD_ITEM>( 0 ) );
m_cursor = grid.BestSnapAnchor ( evt->Position(), selection.Item<BOARD_ITEM>( 0 ) );
getViewControls()->ForceCursorPosition ( true, m_cursor ); getViewControls()->ForceCursorPosition ( true, m_cursor );
wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) - wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) -
@ -206,17 +203,17 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
} }
else // Prepare to start dragging else // Prepare to start dragging
{ {
m_selectionTool->SanitizeSelection( ); m_selectionTool->SanitizeSelection();
if ( selection.Empty() ) if( selection.Empty() )
break; break;
// deal with locked items (override lock or abort the operation) // deal with locked items (override lock or abort the operation)
SELECTION_LOCK_FLAGS lockFlags = m_selectionTool->CheckLock(); SELECTION_LOCK_FLAGS lockFlags = m_selectionTool->CheckLock();
if ( lockFlags == SELECTION_LOCKED ) if( lockFlags == SELECTION_LOCKED )
break; break;
else if ( lockFlags == SELECTION_LOCK_OVERRIDE ) else if( lockFlags == SELECTION_LOCK_OVERRIDE )
lockOverride = true; lockOverride = true;
// Save items, so changes can be undone // Save items, so changes can be undone
@ -225,21 +222,20 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
VECTOR2I origin; VECTOR2I origin;
if( evt->IsDrag( BUT_LEFT ) ) if( evt->IsDrag( BUT_LEFT ) )
mousePos = evt->DragOrigin(); mousePos = evt->DragOrigin();
// origin = grid.Align ( evt->DragOrigin() ); // origin = grid.Align ( evt->DragOrigin() );
//else //else
origin = grid.Align ( mousePos ); origin = grid.Align( mousePos );
if( selection.Size() == 1 ) if( selection.Size() == 1 )
{ {
// Set the current cursor position to the first dragged item origin, so the // Set the current cursor position to the first dragged item origin, so the
// movement vector could be computed later // movement vector could be computed later
m_cursor = grid.BestDragOrigin ( mousePos, selection.Item<BOARD_ITEM>( 0 ) ); m_cursor = grid.BestDragOrigin( mousePos, selection.Item<BOARD_ITEM>( 0 ) );
getViewControls()->ForceCursorPosition ( true, m_cursor ); getViewControls()->ForceCursorPosition ( true, m_cursor );
grid.SetAuxAxes ( true, m_cursor ); grid.SetAuxAxes( true, m_cursor );
VECTOR2I o = VECTOR2I( selection.Item<BOARD_ITEM>( 0 )->GetPosition() ); VECTOR2I o = VECTOR2I( selection.Item<BOARD_ITEM>( 0 )->GetPosition() );
m_offset.x = o.x - m_cursor.x; m_offset.x = o.x - m_cursor.x;
@ -249,9 +245,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
{ {
m_offset = static_cast<BOARD_ITEM*>( selection.items.GetPickedItem( 0 ) )->GetPosition() - m_offset = static_cast<BOARD_ITEM*>( selection.items.GetPickedItem( 0 ) )->GetPosition() -
wxPoint( origin.x, origin.y ); wxPoint( origin.x, origin.y );
getViewControls()->ForceCursorPosition( true, origin );
getViewControls()->ForceCursorPosition ( true, origin );
} }
controls->SetAutoPan( true ); controls->SetAutoPan( true );
@ -264,7 +258,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
{ {
if (!isDragAndDrop || !lockOverride ) if( !isDragAndDrop || !lockOverride )
break; // Finish break; // Finish
lockOverride = false; lockOverride = false;
@ -543,7 +537,6 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem )
if( m_editModules ) if( m_editModules )
{ {
MODULE* module = static_cast<MODULE*>( aItem->GetParent() ); MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
module->SetLastEditTime(); module->SetLastEditTime();
board->m_Status_Pcb = 0; // it is done in the legacy view board->m_Status_Pcb = 0; // it is done in the legacy view
@ -562,13 +555,14 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem )
board->m_Status_Pcb = 0; // it is done in the legacy view board->m_Status_Pcb = 0; // it is done in the legacy view
if(!m_editModules) if( !m_editModules )
{ {
if(aItem->Type() == PCB_PAD_T && module->GetPadCount() == 1) if( aItem->Type() == PCB_PAD_T && module->GetPadCount() == 1 )
{ {
DisplayError( getEditFrame<PCB_BASE_FRAME>(), _( "Cannot delete the only remaining pad of the module (modules on PCB must have at least one pad)." ) ); DisplayError( getEditFrame<PCB_BASE_FRAME>(), _( "Cannot delete the only remaining pad of the module (modules on PCB must have at least one pad)." ) );
return; return;
} }
getView()->Remove( aItem ); getView()->Remove( aItem );
board->Remove( aItem ); board->Remove( aItem );
} }
@ -653,17 +647,17 @@ bool EDIT_TOOL::hoverSelection( const SELECTION& aSelection, bool aSanitize )
{ {
m_toolMgr->RunAction( COMMON_ACTIONS::selectionCursor, true ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionCursor, true );
if ( m_selectionTool->CheckLock() == SELECTION_LOCKED ) if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
{ {
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
return false; return false;
} }
} }
if ( aSanitize ) if( aSanitize )
m_selectionTool->SanitizeSelection(); m_selectionTool->SanitizeSelection();
if ( aSelection.Empty() ) if( aSelection.Empty() )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
return !aSelection.Empty(); return !aSelection.Empty();
@ -707,9 +701,10 @@ void EDIT_TOOL::processChanges( const PICKED_ITEMS_LIST* aList )
} }
} }
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent ) int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
{ {
MODULE *mod = uniqueSelected <MODULE> (); MODULE *mod = uniqueSelected<MODULE>();
if( !mod ) if( !mod )
return 0; return 0;
@ -726,7 +721,7 @@ int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_PCB_MODULE_EDITOR, true ); FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
editor->Load_Module_From_BOARD( (MODULE*)editFrame->GetCurItem() ); editor->Load_Module_From_BOARD( (MODULE*) editFrame->GetCurItem() );
editFrame->SetCurItem( NULL ); // the current module could be deleted by editFrame->SetCurItem( NULL ); // the current module could be deleted by
editor->Show( true ); editor->Show( true );

View File

@ -156,15 +156,15 @@ private:
bool invokeInlineRouter(); bool invokeInlineRouter();
template <class T> T* uniqueSelected() template<class T> T* uniqueSelected()
{ {
const SELECTION& selection = m_selectionTool->GetSelection(); const SELECTION& selection = m_selectionTool->GetSelection();
if(selection.items.GetCount() > 1) if( selection.items.GetCount() > 1 )
return NULL; return NULL;
BOARD_ITEM *item = selection.Item<BOARD_ITEM>( 0 ); BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
return dyn_cast<T*> (item); return dyn_cast<T*>( item );
} }
}; };

View File

@ -40,71 +40,77 @@
#include "grid_helper.h" #include "grid_helper.h"
GRID_HELPER::GRID_HELPER ( PCB_BASE_FRAME *aFrame ) : GRID_HELPER::GRID_HELPER( PCB_BASE_FRAME* aFrame ) :
m_frame ( aFrame ) m_frame( aFrame )
{
}
GRID_HELPER::~GRID_HELPER ()
{
}
void GRID_HELPER::SetGrid ( int aSize )
{
assert ( false );
}
void GRID_HELPER::SetOrigin ( const VECTOR2I& aOrigin )
{ {
} }
VECTOR2I GRID_HELPER::GetGrid ()
GRID_HELPER::~GRID_HELPER()
{ {
PCB_SCREEN *screen = m_frame->GetScreen(); }
void GRID_HELPER::SetGrid( int aSize )
{
assert( false );
}
void GRID_HELPER::SetOrigin( const VECTOR2I& aOrigin )
{
}
VECTOR2I GRID_HELPER::GetGrid()
{
PCB_SCREEN* screen = m_frame->GetScreen();
const wxRealPoint& size = screen->GetGridSize(); const wxRealPoint& size = screen->GetGridSize();
return VECTOR2I ( KiROUND ( size.x ), KiROUND ( size.y ) ); return VECTOR2I ( KiROUND( size.x ), KiROUND( size.y ) );
} }
VECTOR2I GRID_HELPER::GetOrigin ()
VECTOR2I GRID_HELPER::GetOrigin()
{ {
return VECTOR2I ( 0, 0 ); return VECTOR2I( 0, 0 );
} }
void GRID_HELPER::SetAuxAxes ( bool aEnable, const VECTOR2I aOrigin, bool aEnableDiagonal)
void GRID_HELPER::SetAuxAxes( bool aEnable, const VECTOR2I aOrigin, bool aEnableDiagonal )
{ {
if( aEnable ) if( aEnable )
m_auxAxis = aOrigin; m_auxAxis = aOrigin;
else else
m_auxAxis = boost::optional <VECTOR2I> (); m_auxAxis = boost::optional<VECTOR2I>();
m_diagonalAuxAxesEnable = aEnable; m_diagonalAuxAxesEnable = aEnable;
} }
VECTOR2I GRID_HELPER::Align ( const VECTOR2I& aPoint )
{
const VECTOR2D gridOffset ( GetOrigin () );
const VECTOR2D gridSize ( GetGrid() );
VECTOR2I nearest ( round( ( aPoint.x - gridOffset.x ) / gridSize.x ) * gridSize.x + gridOffset.x, VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint )
{
const VECTOR2D gridOffset( GetOrigin () );
const VECTOR2D gridSize( GetGrid() );
VECTOR2I nearest( round( ( aPoint.x - gridOffset.x ) / gridSize.x ) * gridSize.x + gridOffset.x,
round( ( aPoint.y - gridOffset.y ) / gridSize.y ) * gridSize.y + gridOffset.y ); round( ( aPoint.y - gridOffset.y ) / gridSize.y ) * gridSize.y + gridOffset.y );
if ( !m_auxAxis ) if( !m_auxAxis )
return nearest; return nearest;
if ( std::abs ( m_auxAxis->x - aPoint.x) < std::abs ( nearest.x - aPoint.x ) ) if( std::abs( m_auxAxis->x - aPoint.x) < std::abs( nearest.x - aPoint.x ) )
nearest.x = m_auxAxis->x; nearest.x = m_auxAxis->x;
if ( std::abs ( m_auxAxis->y - aPoint.y) < std::abs ( nearest.y - aPoint.y ) ) if( std::abs( m_auxAxis->y - aPoint.y) < std::abs( nearest.y - aPoint.y ) )
nearest.y = m_auxAxis->y; nearest.y = m_auxAxis->y;
return nearest; return nearest;
} }
VECTOR2I GRID_HELPER::BestDragOrigin ( const VECTOR2I &aMousePos, BOARD_ITEM *aItem )
VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, BOARD_ITEM* aItem )
{ {
clearAnchors(); clearAnchors();
computeAnchors( aItem, aMousePos ); computeAnchors( aItem, aMousePos );
@ -112,41 +118,42 @@ VECTOR2I GRID_HELPER::BestDragOrigin ( const VECTOR2I &aMousePos, BOARD_ITEM *aI
double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale(); double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
double lineSnapMinCornerDistance = 50.0 / worldScale; double lineSnapMinCornerDistance = 50.0 / worldScale;
ANCHOR* nearestOutline = nearestAnchor ( aMousePos, OUTLINE, LSET::AllLayersMask() ); ANCHOR* nearestOutline = nearestAnchor( aMousePos, OUTLINE, LSET::AllLayersMask() );
ANCHOR* nearestCorner = nearestAnchor ( aMousePos, CORNER, LSET::AllLayersMask() ); ANCHOR* nearestCorner = nearestAnchor( aMousePos, CORNER, LSET::AllLayersMask() );
ANCHOR* nearestOrigin = nearestAnchor ( aMousePos, ORIGIN, LSET::AllLayersMask() ); ANCHOR* nearestOrigin = nearestAnchor( aMousePos, ORIGIN, LSET::AllLayersMask() );
ANCHOR* best = NULL; ANCHOR* best = NULL;
double minDist = std::numeric_limits<double>::max(); double minDist = std::numeric_limits<double>::max();
if (nearestOrigin) if( nearestOrigin )
{ {
minDist = nearestOrigin->Distance(aMousePos); minDist = nearestOrigin->Distance( aMousePos );
best = nearestOrigin; best = nearestOrigin;
} }
if (nearestCorner) if( nearestCorner )
{ {
double dist = nearestCorner->Distance(aMousePos); double dist = nearestCorner->Distance( aMousePos );
if (dist < minDist) if( dist < minDist )
{ {
minDist = dist; minDist = dist;
best = nearestCorner; best = nearestCorner;
} }
} }
if (nearestOutline) if( nearestOutline )
{ {
double dist = nearestOutline->Distance(aMousePos); double dist = nearestOutline->Distance( aMousePos );
if (minDist > lineSnapMinCornerDistance && dist < minDist) if( minDist > lineSnapMinCornerDistance && dist < minDist )
best = nearestOutline; best = nearestOutline;
} }
return best ? best->pos : aMousePos; return best ? best->pos : aMousePos;
} }
std::set<BOARD_ITEM *> GRID_HELPER::queryVisible ( const BOX2I& aArea )
std::set<BOARD_ITEM*> GRID_HELPER::queryVisible( const BOX2I& aArea )
{ {
std::set <BOARD_ITEM *> items; std::set<BOARD_ITEM*> items;
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems; std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end; std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
@ -163,50 +170,51 @@ std::set<BOARD_ITEM *> GRID_HELPER::queryVisible ( const BOX2I& aArea )
return items; return items;
} }
VECTOR2I GRID_HELPER::BestSnapAnchor ( const VECTOR2I &aOrigin, BOARD_ITEM *aDraggedItem )
VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I &aOrigin, BOARD_ITEM* aDraggedItem )
{ {
double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale(); double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
int snapRange = (int) (100.0 / worldScale); int snapRange = (int) ( 100.0 / worldScale );
BOX2I bb ( VECTOR2I ( aOrigin.x - snapRange / 2, aOrigin.y - snapRange/2) , VECTOR2I (snapRange, snapRange) ); BOX2I bb( VECTOR2I( aOrigin.x - snapRange / 2, aOrigin.y - snapRange/2 ), VECTOR2I( snapRange, snapRange ) );
clearAnchors(); clearAnchors();
BOOST_FOREACH ( BOARD_ITEM *item, queryVisible ( bb ) ) BOOST_FOREACH( BOARD_ITEM* item, queryVisible( bb ) )
{ {
computeAnchors(item, aOrigin); computeAnchors( item, aOrigin );
} }
LSET layers ( aDraggedItem->GetLayer() ); LSET layers( aDraggedItem->GetLayer() );
ANCHOR *nearest = nearestAnchor ( aOrigin, CORNER | SNAPPABLE, layers ); ANCHOR* nearest = nearestAnchor( aOrigin, CORNER | SNAPPABLE, layers );
VECTOR2I nearestGrid = Align ( aOrigin ); VECTOR2I nearestGrid = Align( aOrigin );
double gridDist = (nearestGrid - aOrigin).EuclideanNorm(); double gridDist = ( nearestGrid - aOrigin ).EuclideanNorm();
if (nearest) if( nearest )
{ {
double snapDist = nearest->Distance ( aOrigin ); double snapDist = nearest->Distance( aOrigin );
if(nearest && snapDist < gridDist) if( nearest && snapDist < gridDist )
return nearest->pos; return nearest->pos;
} }
return nearestGrid; return nearestGrid;
} }
void GRID_HELPER::computeAnchors ( BOARD_ITEM *aItem, const VECTOR2I& aRefPos )
void GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos )
{ {
VECTOR2I origin; VECTOR2I origin;
switch( aItem->Type() )
switch ( aItem->Type() )
{ {
case PCB_MODULE_T: case PCB_MODULE_T:
{ {
MODULE *mod = static_cast <MODULE *> (aItem); MODULE* mod = static_cast<MODULE*>( aItem );
addAnchor ( mod->GetPosition(), ORIGIN | SNAPPABLE, mod ); addAnchor( mod->GetPosition(), ORIGIN | SNAPPABLE, mod );
for (D_PAD *pad = mod->Pads(); pad; pad = pad->Next() ) for( D_PAD* pad = mod->Pads(); pad; pad = pad->Next() )
addAnchor ( pad->GetPosition(), CORNER | SNAPPABLE, pad ); addAnchor( pad->GetPosition(), CORNER | SNAPPABLE, pad );
break; break;
} }
@ -214,32 +222,31 @@ void GRID_HELPER::computeAnchors ( BOARD_ITEM *aItem, const VECTOR2I& aRefPos )
case PCB_MODULE_EDGE_T: case PCB_MODULE_EDGE_T:
case PCB_LINE_T: case PCB_LINE_T:
{ {
DRAWSEGMENT *dseg = static_cast <DRAWSEGMENT*> (aItem); DRAWSEGMENT* dseg = static_cast<DRAWSEGMENT*>( aItem );
VECTOR2I start = dseg->GetStart(); VECTOR2I start = dseg->GetStart();
VECTOR2I end = dseg->GetEnd(); VECTOR2I end = dseg->GetEnd();
//LAYER_ID layer = dseg->GetLayer(); //LAYER_ID layer = dseg->GetLayer();
switch( dseg->GetShape() ) switch( dseg->GetShape() )
{ {
case S_CIRCLE: case S_CIRCLE:
{ {
int r = (start - end).EuclideanNorm(); int r = ( start - end ).EuclideanNorm();
addAnchor ( start, ORIGIN | SNAPPABLE, dseg ); addAnchor( start, ORIGIN | SNAPPABLE, dseg );
addAnchor ( start + VECTOR2I ( -r, 0 ) , OUTLINE | SNAPPABLE, dseg ); addAnchor( start + VECTOR2I ( -r, 0 ), OUTLINE | SNAPPABLE, dseg );
addAnchor ( start + VECTOR2I ( r, 0 ) , OUTLINE | SNAPPABLE, dseg ); addAnchor( start + VECTOR2I ( r, 0 ), OUTLINE | SNAPPABLE, dseg );
addAnchor ( start + VECTOR2I ( 0, -r ) , OUTLINE | SNAPPABLE, dseg); addAnchor( start + VECTOR2I ( 0, -r ), OUTLINE | SNAPPABLE, dseg);
addAnchor ( start + VECTOR2I ( 0, r ) , OUTLINE | SNAPPABLE, dseg ); addAnchor( start + VECTOR2I ( 0, r ), OUTLINE | SNAPPABLE, dseg );
break; break;
} }
case S_ARC: case S_ARC:
{ {
origin = dseg->GetCenter(); origin = dseg->GetCenter();
addAnchor ( dseg->GetArcStart(), CORNER | SNAPPABLE, dseg ); addAnchor( dseg->GetArcStart(), CORNER | SNAPPABLE, dseg );
addAnchor ( dseg->GetArcEnd(), CORNER | SNAPPABLE, dseg ); addAnchor( dseg->GetArcEnd(), CORNER | SNAPPABLE, dseg );
addAnchor ( origin, ORIGIN | SNAPPABLE, dseg ); addAnchor( origin, ORIGIN | SNAPPABLE, dseg );
break; break;
} }
@ -247,16 +254,16 @@ void GRID_HELPER::computeAnchors ( BOARD_ITEM *aItem, const VECTOR2I& aRefPos )
{ {
origin.x = start.x + ( start.x - end.x ) / 2; origin.x = start.x + ( start.x - end.x ) / 2;
origin.y = start.y + ( start.y - end.y ) / 2; origin.y = start.y + ( start.y - end.y ) / 2;
addAnchor ( start, CORNER | SNAPPABLE, dseg ); addAnchor( start, CORNER | SNAPPABLE, dseg );
addAnchor ( end, CORNER | SNAPPABLE, dseg ); addAnchor( end, CORNER | SNAPPABLE, dseg );
addAnchor ( origin, ORIGIN, dseg ); addAnchor( origin, ORIGIN, dseg );
break; break;
} }
default: default:
{ {
origin = dseg->GetStart(); origin = dseg->GetStart();
addAnchor ( origin, ORIGIN | SNAPPABLE, dseg ); addAnchor( origin, ORIGIN | SNAPPABLE, dseg );
break; break;
} }
} }
@ -265,14 +272,14 @@ void GRID_HELPER::computeAnchors ( BOARD_ITEM *aItem, const VECTOR2I& aRefPos )
case PCB_TRACE_T: case PCB_TRACE_T:
{ {
TRACK *track = static_cast <TRACK*> (aItem); TRACK* track = static_cast<TRACK*>( aItem );
VECTOR2I start = track->GetStart(); VECTOR2I start = track->GetStart();
VECTOR2I end = track->GetEnd(); VECTOR2I end = track->GetEnd();
origin.x = start.x + ( start.x - end.x ) / 2; origin.x = start.x + ( start.x - end.x ) / 2;
origin.y = start.y + ( start.y - end.y ) / 2; origin.y = start.y + ( start.y - end.y ) / 2;
addAnchor ( start, CORNER | SNAPPABLE, track ); addAnchor( start, CORNER | SNAPPABLE, track );
addAnchor ( end, CORNER | SNAPPABLE, track ); addAnchor( end, CORNER | SNAPPABLE, track );
addAnchor ( origin, ORIGIN, track); addAnchor( origin, ORIGIN, track);
break; break;
} }
@ -282,47 +289,46 @@ void GRID_HELPER::computeAnchors ( BOARD_ITEM *aItem, const VECTOR2I& aRefPos )
int cornersCount = outline->GetCornersCount(); int cornersCount = outline->GetCornersCount();
SHAPE_LINE_CHAIN lc; SHAPE_LINE_CHAIN lc;
lc.SetClosed ( true ); lc.SetClosed( true );
for( int i = 0; i < cornersCount; ++i ) for( int i = 0; i < cornersCount; ++i )
{ {
const VECTOR2I p ( outline->GetPos( i ) ); const VECTOR2I p ( outline->GetPos( i ) );
addAnchor ( p, CORNER, aItem ); addAnchor( p, CORNER, aItem );
lc.Append ( p ); lc.Append( p );
} }
addAnchor( lc.NearestPoint ( aRefPos ), OUTLINE, aItem ); addAnchor( lc.NearestPoint( aRefPos ), OUTLINE, aItem );
break; break;
} }
case PCB_MODULE_TEXT_T: case PCB_MODULE_TEXT_T:
case PCB_TEXT_T: case PCB_TEXT_T:
addAnchor ( aItem->GetPosition(), ORIGIN, aItem ); addAnchor( aItem->GetPosition(), ORIGIN, aItem );
default: default:
break; break;
} }
} }
GRID_HELPER::ANCHOR* GRID_HELPER::nearestAnchor ( VECTOR2I aPos, int aFlags, LSET aMatchLayers )
GRID_HELPER::ANCHOR* GRID_HELPER::nearestAnchor( VECTOR2I aPos, int aFlags, LSET aMatchLayers )
{ {
double minDist = std::numeric_limits<double>::max(); double minDist = std::numeric_limits<double>::max();
ANCHOR *best = NULL; ANCHOR* best = NULL;
BOOST_FOREACH( ANCHOR& a, m_anchors ) BOOST_FOREACH( ANCHOR& a, m_anchors )
{ {
if ( !aMatchLayers [ a.item->GetLayer() ] ) if( !aMatchLayers[a.item->GetLayer()] )
continue; continue;
if ( ( aFlags & a.flags ) != aFlags ) if( ( aFlags & a.flags ) != aFlags )
continue; continue;
double dist = a.Distance(aPos); double dist = a.Distance( aPos );
if(dist < minDist) if( dist < minDist )
{ {
minDist = dist; minDist = dist;
best = &a; best = &a;
@ -330,5 +336,4 @@ GRID_HELPER::ANCHOR* GRID_HELPER::nearestAnchor ( VECTOR2I aPos, int aFlags, LSE
} }
return best; return best;
} }

View File

@ -37,24 +37,23 @@ class PCB_BASE_FRAME;
class GRID_HELPER { class GRID_HELPER {
public: public:
GRID_HELPER ( PCB_BASE_FRAME *aFrame ); GRID_HELPER( PCB_BASE_FRAME* aFrame );
~GRID_HELPER (); ~GRID_HELPER();
void SetGrid ( int aSize ); void SetGrid( int aSize );
void SetOrigin ( const VECTOR2I& aOrigin ); void SetOrigin( const VECTOR2I& aOrigin );
VECTOR2I GetGrid (); VECTOR2I GetGrid();
VECTOR2I GetOrigin (); VECTOR2I GetOrigin();
void SetAuxAxes ( bool aEnable, const VECTOR2I aOrigin = VECTOR2I(0, 0), bool aEnableDiagonal = false ); void SetAuxAxes( bool aEnable, const VECTOR2I aOrigin = VECTOR2I( 0, 0 ), bool aEnableDiagonal = false );
VECTOR2I Align ( const VECTOR2I& aPoint ); VECTOR2I Align( const VECTOR2I& aPoint );
VECTOR2I BestDragOrigin ( const VECTOR2I &aMousePos, BOARD_ITEM *aItem ); VECTOR2I BestDragOrigin ( const VECTOR2I &aMousePos, BOARD_ITEM* aItem );
VECTOR2I BestSnapAnchor ( const VECTOR2I &aOrigin, BOARD_ITEM *aDraggedItem ); VECTOR2I BestSnapAnchor ( const VECTOR2I &aOrigin, BOARD_ITEM* aDraggedItem );
private: private:
enum ANCHOR_FLAGS { enum ANCHOR_FLAGS {
CORNER = 0x1, CORNER = 0x1,
OUTLINE = 0x2, OUTLINE = 0x2,
@ -64,33 +63,33 @@ private:
struct ANCHOR struct ANCHOR
{ {
ANCHOR ( VECTOR2I aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM *aItem = NULL ): ANCHOR( VECTOR2I aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM* aItem = NULL ):
pos (aPos), flags (aFlags), item (aItem) {} ; pos( aPos ), flags( aFlags ), item( aItem ) {} ;
VECTOR2I pos; VECTOR2I pos;
int flags; int flags;
BOARD_ITEM *item; BOARD_ITEM* item;
double Distance ( const VECTOR2I& aP ) double Distance( const VECTOR2I& aP )
{ {
return (aP - pos).EuclideanNorm(); return ( aP - pos ).EuclideanNorm();
} }
bool CanSnapItem ( const BOARD_ITEM *aItem ); bool CanSnapItem( const BOARD_ITEM* aItem );
}; };
std::vector<ANCHOR> m_anchors; std::vector<ANCHOR> m_anchors;
std::set<BOARD_ITEM *> queryVisible ( const BOX2I& aArea ); std::set<BOARD_ITEM*> queryVisible( const BOX2I& aArea );
void addAnchor( VECTOR2I aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM *aItem = NULL ) void addAnchor( VECTOR2I aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM* aItem = NULL )
{ {
m_anchors.push_back( ANCHOR( aPos, aFlags, aItem ) ); m_anchors.push_back( ANCHOR( aPos, aFlags, aItem ) );
} }
ANCHOR* nearestAnchor ( VECTOR2I aPos, int aFlags, LSET aMatchLayers ); ANCHOR* nearestAnchor( VECTOR2I aPos, int aFlags, LSET aMatchLayers );
void computeAnchors ( BOARD_ITEM *aItem, const VECTOR2I& aRefPos ); void computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos );
void clearAnchors () void clearAnchors ()
{ {

View File

@ -36,7 +36,6 @@
#include <class_pcb_text.h> #include <class_pcb_text.h>
#include <class_drawsegment.h> #include <class_drawsegment.h>
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <collectors.h> #include <collectors.h>
#include <confirm.h> #include <confirm.h>
@ -277,7 +276,7 @@ bool SELECTION_TOOL::selectCursor( const VECTOR2I& aWhere, bool aOnDrag )
// Remove unselectable items // Remove unselectable items
for( int i = collector.GetCount() - 1; i >= 0; --i ) for( int i = collector.GetCount() - 1; i >= 0; --i )
{ {
if( !selectable( collector[i] ) || ( aOnDrag && collector[i]->IsLocked() )) if( !selectable( collector[i] ) || ( aOnDrag && collector[i]->IsLocked() ) )
collector.Remove( i ); collector.Remove( i );
} }
@ -295,7 +294,6 @@ bool SELECTION_TOOL::selectCursor( const VECTOR2I& aWhere, bool aOnDrag )
return true; return true;
default: default:
// Apply some ugly heuristics to avoid disambiguation menus whenever possible // Apply some ugly heuristics to avoid disambiguation menus whenever possible
guessSelectionCandidates( collector ); guessSelectionCandidates( collector );
@ -414,6 +412,7 @@ void SELECTION_TOOL::setTransitions()
Go( &SELECTION_TOOL::findMove, COMMON_ACTIONS::findMove.MakeEvent() ); Go( &SELECTION_TOOL::findMove, COMMON_ACTIONS::findMove.MakeEvent() );
} }
SELECTION_LOCK_FLAGS SELECTION_TOOL::CheckLock() SELECTION_LOCK_FLAGS SELECTION_TOOL::CheckLock()
{ {
if( !m_locked || m_editModules ) if( !m_locked || m_editModules )
@ -521,6 +520,7 @@ void SELECTION_TOOL::findCallback( BOARD_ITEM* aItem )
{ {
clearSelection(); clearSelection();
select( aItem ); select( aItem );
getView()->SetCenter( VECTOR2D( aItem->GetPosition() ) );
// Inform other potentially interested tools // Inform other potentially interested tools
m_toolMgr->ProcessEvent( SelectedEvent ); m_toolMgr->ProcessEvent( SelectedEvent );
@ -571,9 +571,9 @@ void SELECTION_TOOL::clearSelection()
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it ); BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
item->ViewHide ( false ); item->ViewHide( false );
item->ClearSelected(); item->ClearSelected();
item->ViewUpdate ( KIGFX::VIEW_ITEM::GEOMETRY ) ; item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ) ;
} }
m_selection.clear(); m_selection.clear();
@ -742,6 +742,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
case PCB_MODULE_TEXT_T: case PCB_MODULE_TEXT_T:
if( m_multiple && !m_editModules ) if( m_multiple && !m_editModules )
return false; return false;
return aItem->ViewIsVisible() && board->IsLayerVisible( aItem->GetLayer() ); return aItem->ViewIsVisible() && board->IsLayerVisible( aItem->GetLayer() );
// These are not selectable // These are not selectable
@ -751,7 +752,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
if( m_multiple && !m_editModules ) if( m_multiple && !m_editModules )
return false; return false;
MODULE *mod = static_cast<const D_PAD *> (aItem) -> GetParent(); MODULE* mod = static_cast<const D_PAD*>( aItem )->GetParent();
if( mod && mod->IsLocked() ) if( mod && mod->IsLocked() )
return false; return false;
@ -781,7 +782,7 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem )
module->RunOnChildren( boost::bind( &SELECTION_TOOL::selectVisually, this, _1 ) ); module->RunOnChildren( boost::bind( &SELECTION_TOOL::selectVisually, this, _1 ) );
} }
if ( aItem->Type() == PCB_PAD_T ) if( aItem->Type() == PCB_PAD_T )
{ {
MODULE* module = static_cast<MODULE*>( aItem->GetParent() ); MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
@ -838,7 +839,7 @@ void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem ) const
m_selection.group->Add( aItem ); m_selection.group->Add( aItem );
// Hide the original item, so it is shown only on overlay // Hide the original item, so it is shown only on overlay
aItem->ViewHide (true); aItem->ViewHide( true );
aItem->SetSelected(); aItem->SetSelected();
} }
@ -848,7 +849,7 @@ void SELECTION_TOOL::unselectVisually( BOARD_ITEM* aItem ) const
m_selection.group->Remove( aItem ); m_selection.group->Remove( aItem );
// Restore original item visibility // Restore original item visibility
aItem->ViewHide (false); aItem->ViewHide( false );
aItem->ClearSelected(); aItem->ClearSelected();
aItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); aItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
} }
@ -897,16 +898,17 @@ void SELECTION_TOOL::highlightNet( const VECTOR2I& aPoint )
} }
} }
static double calcArea ( BOARD_ITEM *aItem )
static double calcArea( BOARD_ITEM* aItem )
{ {
switch (aItem -> Type() ) switch( aItem -> Type() )
{ {
case PCB_MODULE_T: case PCB_MODULE_T:
return static_cast <MODULE *> (aItem)->GetFootprintRect().GetArea(); return static_cast <MODULE*>( aItem )->GetFootprintRect().GetArea();
case PCB_TRACE_T: case PCB_TRACE_T:
{ {
TRACK *t = static_cast<TRACK *> (aItem); TRACK* t = static_cast<TRACK*>( aItem );
return ( t->GetWidth() + t->GetLength() ) * t->GetWidth(); return ( t->GetWidth() + t->GetLength() ) * t->GetWidth();
} }
@ -915,40 +917,43 @@ static double calcArea ( BOARD_ITEM *aItem )
} }
} }
static double calcMinArea ( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
static double calcMinArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
{ {
double best = std::numeric_limits<double>::max(); double best = std::numeric_limits<double>::max();
if(!aCollector.GetCount()) if( !aCollector.GetCount() )
return 0.0; return 0.0;
for(int i = 0; i < aCollector.GetCount(); i++) for( int i = 0; i < aCollector.GetCount(); i++ )
{ {
BOARD_ITEM *item = aCollector[i]; BOARD_ITEM* item = aCollector[i];
if(item->Type() == aType) if( item->Type() == aType )
best = std::min(best, calcArea ( item )); best = std::min( best, calcArea( item ) );
} }
return best; return best;
} }
static double calcMaxArea ( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
static double calcMaxArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
{ {
double best = 0.0; double best = 0.0;
for(int i = 0; i < aCollector.GetCount(); i++) for( int i = 0; i < aCollector.GetCount(); i++ )
{ {
BOARD_ITEM *item = aCollector[i]; BOARD_ITEM* item = aCollector[i];
if(item->Type() == aType) if( item->Type() == aType )
best = std::max(best, calcArea ( item )); best = std::max(best, calcArea( item ) );
} }
return best; return best;
} }
double calcRatio ( double a, double b )
double calcRatio( double a, double b )
{ {
if ( a == 0.0 && b == 0.0 ) if ( a == 0.0 && b == 0.0 )
return 1.0; return 1.0;
@ -958,10 +963,11 @@ double calcRatio ( double a, double b )
return a / b; return a / b;
} }
// todo: explain the selection heuristics // todo: explain the selection heuristics
void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) const void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) const
{ {
std::set<BOARD_ITEM *> rejected; std::set<BOARD_ITEM*> rejected;
const double footprintAreaRatio = 0.2; const double footprintAreaRatio = 0.2;
const double modulePadMinCoverRatio = 0.45; const double modulePadMinCoverRatio = 0.45;
@ -973,60 +979,61 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
LAYER_ID actLayer = m_frame->GetActiveLayer(); LAYER_ID actLayer = m_frame->GetActiveLayer();
LSET silkLayers(2, B_SilkS, F_SilkS ); LSET silkLayers( 2, B_SilkS, F_SilkS );
if( silkLayers[ actLayer ] ) if( silkLayers[actLayer] )
{ {
std::set<BOARD_ITEM *> preferred; std::set<BOARD_ITEM*> preferred;
for( int i = 0; i < aCollector.GetCount(); ++i ) for( int i = 0; i < aCollector.GetCount(); ++i )
{ {
BOARD_ITEM *item = aCollector[i]; BOARD_ITEM* item = aCollector[i];
if ( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_TEXT_T || item->Type() == PCB_LINE_T ) if ( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_TEXT_T || item->Type() == PCB_LINE_T )
if ( silkLayers[item->GetLayer() ] ) if ( silkLayers[item->GetLayer()] )
preferred.insert ( item ); preferred.insert ( item );
} }
if( preferred.size() != 0) if( preferred.size() != 0 )
{ {
aCollector.Empty(); aCollector.Empty();
BOOST_FOREACH( BOARD_ITEM *item, preferred ) BOOST_FOREACH( BOARD_ITEM* item, preferred )
aCollector.Append( item ); aCollector.Append( item );
return; return;
} }
} }
if (aCollector.CountType ( PCB_MODULE_TEXT_T ) > 0 ) if( aCollector.CountType( PCB_MODULE_TEXT_T ) > 0 )
{ {
for( int i = 0; i < aCollector.GetCount(); ++i ) for( int i = 0; i < aCollector.GetCount(); ++i )
if ( TEXTE_MODULE *txt = dyn_cast<TEXTE_MODULE *> ( aCollector[i] ) ) if( TEXTE_MODULE* txt = dyn_cast<TEXTE_MODULE*>( aCollector[i] ) )
{ {
double textArea = calcArea ( txt ); double textArea = calcArea( txt );
for( int j = 0; j < aCollector.GetCount(); ++j ) for( int j = 0; j < aCollector.GetCount(); ++j )
{ {
BOARD_ITEM *item = aCollector[j]; BOARD_ITEM* item = aCollector[j];
double areaRatio = calcRatio ( textArea, calcArea ( item ) ); double areaRatio = calcRatio( textArea, calcArea( item ) );
if (item->Type () == PCB_MODULE_T && areaRatio < textToFootprintMinRatio ) if( item->Type() == PCB_MODULE_T && areaRatio < textToFootprintMinRatio )
{ {
printf("rejectModuleN\n"); //printf("rejectModuleN\n");
rejected.insert ( item ); rejected.insert( item );
} }
switch (item->Type())
switch( item->Type() )
{ {
case PCB_TRACE_T: case PCB_TRACE_T:
case PCB_PAD_T: case PCB_PAD_T:
case PCB_LINE_T: case PCB_LINE_T:
case PCB_VIA_T: case PCB_VIA_T:
case PCB_MODULE_T: case PCB_MODULE_T:
if ( areaRatio > textToFeatureMinRatio ) if( areaRatio > textToFeatureMinRatio )
{ {
printf("t after moduleRejected\n"); //printf("t after moduleRejected\n");
rejected.insert ( txt ); rejected.insert( txt );
} }
break; break;
default: default:
@ -1036,22 +1043,21 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
} }
} }
if( aCollector.CountType ( PCB_MODULE_T ) > 0 ) if( aCollector.CountType( PCB_MODULE_T ) > 0 )
{ {
double minArea = calcMinArea ( aCollector, PCB_MODULE_T ); double minArea = calcMinArea( aCollector, PCB_MODULE_T );
double maxArea = calcMaxArea ( aCollector, PCB_MODULE_T ); double maxArea = calcMaxArea( aCollector, PCB_MODULE_T );
if( calcRatio( minArea, maxArea ) <= footprintAreaRatio )
if( calcRatio(minArea, maxArea) <= footprintAreaRatio )
{ {
for( int i = 0; i < aCollector.GetCount(); ++i ) for( int i = 0; i < aCollector.GetCount(); ++i )
if ( MODULE *mod = dyn_cast<MODULE*> ( aCollector[i] ) ) if( MODULE* mod = dyn_cast<MODULE*>( aCollector[i] ) )
{ {
double normalizedArea = calcRatio ( calcArea(mod), maxArea ); double normalizedArea = calcRatio( calcArea(mod), maxArea );
if(normalizedArea > footprintAreaRatio) if( normalizedArea > footprintAreaRatio )
{ {
printf("rejectModule1\n"); //printf("rejectModule1\n");
rejected.insert( mod ); rejected.insert( mod );
} }
@ -1062,26 +1068,29 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
if( aCollector.CountType ( PCB_PAD_T ) > 0 ) if( aCollector.CountType ( PCB_PAD_T ) > 0 )
{ {
for( int i = 0; i < aCollector.GetCount(); ++i ) for( int i = 0; i < aCollector.GetCount(); ++i )
if ( D_PAD *pad = dyn_cast<D_PAD*> ( aCollector[i] ) ) {
if ( D_PAD* pad = dyn_cast<D_PAD*>( aCollector[i] ) )
{ {
double ratio = pad->GetParent()->PadCoverageRatio(); double ratio = pad->GetParent()->PadCoverageRatio();
if(ratio < modulePadMinCoverRatio) if( ratio < modulePadMinCoverRatio )
rejected.insert( pad->GetParent() ); rejected.insert( pad->GetParent() );
} }
} }
}
if( aCollector.CountType ( PCB_VIA_T ) > 0 ) if( aCollector.CountType( PCB_VIA_T ) > 0 )
{ {
for( int i = 0; i < aCollector.GetCount(); ++i ) for( int i = 0; i < aCollector.GetCount(); ++i )
if ( VIA *via = dyn_cast<VIA*> ( aCollector[i] ) )
{ {
double viaArea = calcArea ( via ); if( VIA* via = dyn_cast<VIA*>( aCollector[i] ) )
{
double viaArea = calcArea( via );
for( int j = 0; j < aCollector.GetCount(); ++j ) for( int j = 0; j < aCollector.GetCount(); ++j )
{ {
BOARD_ITEM *item = aCollector[j]; BOARD_ITEM* item = aCollector[j];
double areaRatio = calcRatio ( viaArea, calcArea ( item ) ); double areaRatio = calcRatio ( viaArea, calcArea( item ) );
if( item->Type() == PCB_MODULE_T && areaRatio < modulePadMinCoverRatio ) if( item->Type() == PCB_MODULE_T && areaRatio < modulePadMinCoverRatio )
rejected.insert( item ); rejected.insert( item );
@ -1089,12 +1098,12 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
if( item->Type() == PCB_PAD_T && areaRatio < padViaAreaRatio ) if( item->Type() == PCB_PAD_T && areaRatio < padViaAreaRatio )
rejected.insert( item ); rejected.insert( item );
if ( TRACK *track = dyn_cast<TRACK*> ( item ) ) if( TRACK* track = dyn_cast<TRACK*>( item ) )
{ {
if( track->GetNetCode() != via->GetNetCode() ) if( track->GetNetCode() != via->GetNetCode() )
continue; continue;
double lenRatio = (double) ( track->GetLength() + track->GetWidth()) / (double) via->GetWidth(); double lenRatio = (double) ( track->GetLength() + track->GetWidth() ) / (double) via->GetWidth();
if( lenRatio > trackViaLengthRatio ) if( lenRatio > trackViaLengthRatio )
rejected.insert( track ); rejected.insert( track );
@ -1102,6 +1111,7 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
} }
} }
} }
}
int nTracks = aCollector.CountType ( PCB_TRACE_T ); int nTracks = aCollector.CountType ( PCB_TRACE_T );
@ -1123,79 +1133,84 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
maxArea = std::max(area, maxArea); maxArea = std::max(area, maxArea);
} }
if(maxLength > 0.0 && minLength/maxLength < trackTrackLengthRatio && nTracks > 1 ) if( maxLength > 0.0 && minLength/maxLength < trackTrackLengthRatio && nTracks > 1 )
{
for( int i = 0; i < aCollector.GetCount(); ++i ) for( int i = 0; i < aCollector.GetCount(); ++i )
if ( TRACK *track = dyn_cast<TRACK*> ( aCollector[i] ) ) {
if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
{ {
double ratio = std::max( (double) track->GetWidth(), track->GetLength()) / maxLength; double ratio = std::max( (double) track->GetWidth(), track->GetLength()) / maxLength;
if( ratio > trackTrackLengthRatio)
rejected.insert(track);
}
if( ratio > trackTrackLengthRatio )
rejected.insert( track) ;
}
}
}
for( int j = 0; j < aCollector.GetCount(); ++j ) for( int j = 0; j < aCollector.GetCount(); ++j )
{ {
if ( MODULE *mod = dyn_cast<MODULE*> ( aCollector[j] ) ) if( MODULE* mod = dyn_cast<MODULE*>( aCollector[j] ) )
{ {
double ratio = maxArea / mod->GetFootprintRect().GetArea(); double ratio = maxArea / mod->GetFootprintRect().GetArea();
if( ratio < modulePadMinCoverRatio ) if( ratio < modulePadMinCoverRatio )
{ {
printf("rejectModule\n"); //printf("rejectModule\n");
rejected.insert( mod ); rejected.insert( mod );
} }
} }
} }
} }
BOOST_FOREACH(BOARD_ITEM *item, rejected) BOOST_FOREACH( BOARD_ITEM* item, rejected )
{ {
aCollector.Remove(item); aCollector.Remove( item );
} }
printf("Post-selection: %d\n", aCollector.GetCount() );
//printf("Post-selection: %d\n", aCollector.GetCount() );
} }
bool SELECTION_TOOL::SanitizeSelection() bool SELECTION_TOOL::SanitizeSelection()
{ {
std::set <BOARD_ITEM *> rejected; std::set<BOARD_ITEM*> rejected;
if ( !m_editModules ) if( !m_editModules )
{ {
for( unsigned int i = 0; i < m_selection.items.GetCount(); ++i ) for( unsigned int i = 0; i < m_selection.items.GetCount(); ++i )
{ {
BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i ); BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
if( item->Type() == PCB_PAD_T ) if( item->Type() == PCB_PAD_T )
{ {
MODULE *mod = static_cast <MODULE*> ( item->GetParent( ) ); MODULE* mod = static_cast <MODULE*>( item->GetParent() );
// case 1: module (or its pads) are locked // case 1: module (or its pads) are locked
if( mod && ( mod->PadsLocked( ) || mod->IsLocked( ) ) ) if( mod && ( mod->PadsLocked() || mod->IsLocked() ) )
rejected.insert ( item ); rejected.insert( item );
// case 2: multi-item selection contains both the module and its pads - remove the pads // case 2: multi-item selection contains both the module and its pads - remove the pads
if (mod && m_selection.items.FindItem ( mod ) >= 0 ) if( mod && m_selection.items.FindItem( mod ) >= 0 )
rejected.insert ( item ); rejected.insert( item );
} }
} }
} }
while ( !rejected.empty () ) while( !rejected.empty () )
{ {
BOARD_ITEM *item = *rejected.begin(); BOARD_ITEM* item = *rejected.begin();
int itemIdx = m_selection.items.FindItem( item ); int itemIdx = m_selection.items.FindItem( item );
if( itemIdx >= 0 ) if( itemIdx >= 0 )
m_selection.items.RemovePicker( itemIdx ); m_selection.items.RemovePicker( itemIdx );
rejected.erase(item); rejected.erase( item );
} }
return true; return true;
} }
void SELECTION_TOOL::generateMenu() void SELECTION_TOOL::generateMenu()
{ {
// Create a copy of the master context menu // Create a copy of the master context menu
@ -1225,7 +1240,6 @@ void SELECTION::clear()
} }
const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" ); const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" ); const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" ); const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );

View File

@ -166,7 +166,7 @@ public:
///> Makes sure a group selection does not contain items that would cause ///> Makes sure a group selection does not contain items that would cause
///> conflicts when moving/rotating together (e.g. a footprint and one of the same footprint's pads) ///> conflicts when moving/rotating together (e.g. a footprint and one of the same footprint's pads)
bool SanitizeSelection( ); bool SanitizeSelection();
///> Item selection event handler. ///> Item selection event handler.
int SelectItem( const TOOL_EVENT& aEvent ); int SelectItem( const TOOL_EVENT& aEvent );
@ -194,7 +194,7 @@ private:
* a menu is shown, otherise function finishes without selecting anything. * a menu is shown, otherise function finishes without selecting anything.
* @return True if an item was selected, false otherwise. * @return True if an item was selected, false otherwise.
*/ */
bool selectCursor( const VECTOR2I& aWhere, bool aOnDrag = false); bool selectCursor( const VECTOR2I& aWhere, bool aOnDrag = false );
/** /**
* Function selectMultiple() * Function selectMultiple()

View File

@ -1,3 +1,27 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2015 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 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <io_mgr.h> #include <io_mgr.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
@ -14,7 +38,7 @@
#include <router/router_tool.h> #include <router/router_tool.h>
#include <router/length_tuner_tool.h> #include <router/length_tuner_tool.h>
void registerAllTools ( TOOL_MANAGER *aToolManager ) void registerAllTools( TOOL_MANAGER *aToolManager )
{ {
aToolManager->RegisterTool( new SELECTION_TOOL ); aToolManager->RegisterTool( new SELECTION_TOOL );
aToolManager->RegisterTool( new ROUTER_TOOL ); aToolManager->RegisterTool( new ROUTER_TOOL );

View File

@ -486,7 +486,6 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule,
m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true ); m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
GetGalCanvas()->ForceRefresh(); GetGalCanvas()->ForceRefresh();
} }
} }
else else