Code formatting.
This commit is contained in:
parent
112adccbcb
commit
4fb9bce354
|
@ -35,7 +35,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const
|
|||
{
|
||||
VECTOR2I d = B - A;
|
||||
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 t = d.Dot( aP - A );
|
||||
|
|
|
@ -29,35 +29,37 @@
|
|||
#include <wx_status_popup.h>
|
||||
#include <wxPcbStruct.h>
|
||||
|
||||
WX_STATUS_POPUP::WX_STATUS_POPUP ( PCB_EDIT_FRAME *parent ) :
|
||||
wxPopupWindow ( parent )
|
||||
WX_STATUS_POPUP::WX_STATUS_POPUP( PCB_EDIT_FRAME* aParent ) :
|
||||
wxPopupWindow( aParent )
|
||||
{
|
||||
m_panel = new wxPanel( this, wxID_ANY );
|
||||
m_panel->SetBackgroundColour( *wxLIGHT_GREY );
|
||||
|
||||
m_topSizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_panel->SetSizer( m_topSizer );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WX_STATUS_POPUP::updateSize()
|
||||
{
|
||||
m_topSizer->Fit( m_panel );
|
||||
SetClientSize( m_panel->GetSize( ) );
|
||||
SetClientSize( m_panel->GetSize() );
|
||||
}
|
||||
|
||||
|
||||
WX_STATUS_POPUP::~WX_STATUS_POPUP()
|
||||
{
|
||||
}
|
||||
|
||||
void WX_STATUS_POPUP::Popup(wxWindow *focus)
|
||||
|
||||
void WX_STATUS_POPUP::Popup( wxWindow* )
|
||||
{
|
||||
Show(true);
|
||||
Show( true );
|
||||
Raise();
|
||||
}
|
||||
|
||||
|
||||
void WX_STATUS_POPUP::Move( const wxPoint& aWhere )
|
||||
{
|
||||
SetPosition ( aWhere );
|
||||
}
|
||||
|
|
@ -35,14 +35,14 @@
|
|||
|
||||
#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
|
||||
m_units = g_UserUnit;
|
||||
m_textCtrl = aTextInput;
|
||||
m_textCtrl->SetValue ( wxT("0") );
|
||||
m_textCtrl->SetValue( wxT( "0" ) );
|
||||
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 )
|
||||
{
|
||||
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
|
||||
{
|
||||
wxString s = m_textCtrl->GetValue();
|
||||
|
@ -66,8 +68,9 @@ int WX_UNIT_BINDER::GetValue() const
|
|||
return ValueFromString( m_units, s );
|
||||
}
|
||||
|
||||
void WX_UNIT_BINDER::Enable ( bool aEnable )
|
||||
|
||||
void WX_UNIT_BINDER::Enable( bool aEnable )
|
||||
{
|
||||
m_textCtrl->Enable ( aEnable );
|
||||
m_unitLabel->Enable ( aEnable );
|
||||
}
|
||||
m_textCtrl->Enable( aEnable );
|
||||
m_unitLabel->Enable( aEnable );
|
||||
}
|
|
@ -147,7 +147,7 @@ public:
|
|||
#define BRIGHTENED (1 << 26) ///< item is drawn with a bright contour
|
||||
|
||||
#define DP_COUPLED (1 << 27) ///< item is coupled with another item making a differential pair
|
||||
///< (applies to segments only)
|
||||
///< (applies to segments only)
|
||||
|
||||
#define EDA_ITEM_ALL_FLAGS -1
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ public:
|
|||
* removes the item aItem (if exists in the collector).
|
||||
* @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++ )
|
||||
{
|
||||
|
@ -257,7 +257,6 @@ public:
|
|||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Collect
|
||||
* scans an EDA_ITEM using this class's Inspector method, which does
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
/**
|
||||
* Function GetSize()
|
||||
* Returns information about number of vertices stored.
|
||||
* @param Number of vertices.
|
||||
* @return Number of vertices.
|
||||
*/
|
||||
inline unsigned int GetSize() const
|
||||
{
|
||||
|
|
|
@ -206,7 +206,7 @@ public:
|
|||
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;
|
||||
qB = B.x - A.x;
|
||||
|
@ -223,8 +223,8 @@ public:
|
|||
bool Collinear( const SEG& aSeg ) const
|
||||
{
|
||||
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 d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
|
||||
|
||||
|
@ -234,23 +234,23 @@ public:
|
|||
bool ApproxCollinear( const SEG& aSeg ) const
|
||||
{
|
||||
ecoord p, q, r;
|
||||
CanonicalCoefs ( p, q, r );
|
||||
|
||||
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 );
|
||||
CanonicalCoefs( p, q, r );
|
||||
|
||||
return std::abs(dist1) <= 1 && std::abs(dist2) <= 1;
|
||||
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 );
|
||||
|
||||
return std::abs( dist1 ) <= 1 && std::abs( dist2 ) <= 1;
|
||||
}
|
||||
|
||||
bool ApproxParallel ( const SEG& aSeg ) const
|
||||
{
|
||||
ecoord p, q, r;
|
||||
CanonicalCoefs ( p, q, r );
|
||||
|
||||
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 );
|
||||
CanonicalCoefs( p, q, r );
|
||||
|
||||
return std::abs(dist1 - dist2) <= 1;
|
||||
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 );
|
||||
|
||||
return std::abs( dist1 - dist2 ) <= 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -291,7 +291,7 @@ public:
|
|||
return ( A - B ).SquaredEuclideanNorm();
|
||||
}
|
||||
|
||||
ecoord TCoef ( const VECTOR2I& aP ) const;
|
||||
ecoord TCoef( const VECTOR2I& aP ) const;
|
||||
|
||||
/**
|
||||
* Function Index()
|
||||
|
@ -310,7 +310,7 @@ public:
|
|||
|
||||
void Reverse()
|
||||
{
|
||||
std::swap ( A, B );
|
||||
std::swap( A, B );
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -320,7 +320,6 @@ private:
|
|||
int m_index;
|
||||
};
|
||||
|
||||
|
||||
inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
|
||||
{
|
||||
VECTOR2I d = B - A;
|
||||
|
@ -337,7 +336,6 @@ inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
|
|||
return A + VECTOR2I( xp, yp );
|
||||
}
|
||||
|
||||
|
||||
inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
inline SEG::ecoord SEG::TCoef ( const VECTOR2I& aP ) const
|
||||
inline SEG::ecoord SEG::TCoef( const VECTOR2I& aP ) const
|
||||
{
|
||||
VECTOR2I d = B - A;
|
||||
return d.Dot ( aP - A);
|
||||
return d.Dot( aP - A);
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg )
|
||||
{
|
||||
aStream << "[ " << aSeg.A << " - " << aSeg.B << " ]";
|
||||
|
|
|
@ -76,16 +76,15 @@ public:
|
|||
ALL = 0xff
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum VIEW_VISIBILITY_FLAGS.
|
||||
* Defines the visibility of the item (temporarily hidden, invisible, etc).
|
||||
/**
|
||||
* Enum VIEW_VISIBILITY_FLAGS.
|
||||
* Defines the visibility of the item (temporarily hidden, invisible, etc).
|
||||
*/
|
||||
enum VIEW_VISIBILITY_FLAGS {
|
||||
VISIBLE = 0x01, /// Item is visible (in general)
|
||||
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 ),
|
||||
m_groups( NULL ), m_groupsSize( 0 ) {}
|
||||
|
||||
|
@ -141,13 +140,14 @@ public:
|
|||
void ViewSetVisible( bool aIsVisible = true )
|
||||
{
|
||||
bool cur_visible = m_flags & VISIBLE;
|
||||
|
||||
|
||||
if( cur_visible != aIsVisible )
|
||||
{
|
||||
if(aIsVisible)
|
||||
if( aIsVisible )
|
||||
m_flags |= VISIBLE;
|
||||
else
|
||||
m_flags &= ~VISIBLE;
|
||||
|
||||
ViewUpdate( APPEARANCE | COLOR );
|
||||
}
|
||||
}
|
||||
|
@ -158,12 +158,12 @@ public:
|
|||
*
|
||||
* @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;
|
||||
|
||||
if(aHide)
|
||||
if( aHide )
|
||||
m_flags |= HIDDEN;
|
||||
else
|
||||
m_flags &= ~HIDDEN;
|
||||
|
@ -242,7 +242,7 @@ protected:
|
|||
}
|
||||
|
||||
VIEW* m_view; ///< Current dynamic view the item is assigned to.
|
||||
int m_flags; ///< Visibility flags
|
||||
int m_flags; ///< Visibility flags
|
||||
int m_requiredUpdate; ///< Flag required for updating
|
||||
|
||||
///* Helper for storing cached items group ids
|
||||
|
@ -341,7 +341,7 @@ protected:
|
|||
* Function isRenderable()
|
||||
* Returns if the item should be drawn or not.
|
||||
*/
|
||||
bool isRenderable() const
|
||||
bool isRenderable() const
|
||||
{
|
||||
return m_flags == VISIBLE;
|
||||
}
|
||||
|
|
|
@ -41,18 +41,18 @@ class PCB_EDIT_FRAME;
|
|||
class WX_STATUS_POPUP: public wxPopupWindow
|
||||
{
|
||||
public:
|
||||
WX_STATUS_POPUP ( PCB_EDIT_FRAME *parent );
|
||||
WX_STATUS_POPUP( PCB_EDIT_FRAME* aParent );
|
||||
virtual ~WX_STATUS_POPUP();
|
||||
|
||||
virtual void Popup(wxWindow *focus = NULL);
|
||||
virtual void Popup(wxWindow* aFocus = NULL);
|
||||
virtual void Move( const wxPoint &aWhere );
|
||||
|
||||
protected:
|
||||
|
||||
void updateSize();
|
||||
|
||||
wxPanel *m_panel;
|
||||
wxBoxSizer *m_topSizer;
|
||||
wxPanel* m_panel;
|
||||
wxBoxSizer* m_topSizer;
|
||||
};
|
||||
|
||||
#endif /* __WX_STATUS_POPUP_H_*/
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
* @param aUnitLabel is the units label displayed next to the text field.
|
||||
* @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();
|
||||
|
||||
|
@ -64,20 +64,20 @@ public:
|
|||
* Function Enable
|
||||
* Enables/diasables the binded widgets
|
||||
*/
|
||||
void Enable ( bool aEnable );
|
||||
void Enable( bool aEnable );
|
||||
|
||||
protected:
|
||||
|
||||
void onTextChanged ( wxEvent& aEvent );
|
||||
void onTextChanged( wxEvent& aEvent );
|
||||
|
||||
///> Text input control.
|
||||
wxTextCtrl* m_textCtrl;
|
||||
|
||||
///> Label showing currently used units.
|
||||
wxStaticText* m_unitLabel;
|
||||
wxStaticText* m_unitLabel;
|
||||
|
||||
///> Currently used units.
|
||||
EDA_UNITS_T m_units;
|
||||
EDA_UNITS_T m_units;
|
||||
|
||||
///> Step size (added/subtracted difference if spin buttons are used).
|
||||
int m_step;
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
/// skip the linked list stuff, and parent
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -815,12 +815,14 @@ void MODULE::RunOnChildren( boost::function<void (BOARD_ITEM*)> aFunction )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const BOX2I MODULE::ViewBBox() const
|
||||
{
|
||||
return BOX2I( VECTOR2I( GetFootprintRect().GetOrigin() ),
|
||||
VECTOR2I( GetFootprintRect().GetSize() ) );
|
||||
VECTOR2I( GetFootprintRect().GetSize() ) );
|
||||
}
|
||||
|
||||
|
||||
void MODULE::ViewUpdate( int aUpdateFlags )
|
||||
{
|
||||
if( !m_view )
|
||||
|
@ -1115,6 +1117,7 @@ void MODULE::SetOrientation( double newangle )
|
|||
CalculateBoundingBox();
|
||||
}
|
||||
|
||||
|
||||
double MODULE::PadCoverageRatio() const
|
||||
{
|
||||
double padArea = 0.0;
|
||||
|
@ -1128,5 +1131,5 @@ double MODULE::PadCoverageRatio() const
|
|||
|
||||
double ratio = padArea / moduleArea;
|
||||
|
||||
return std::min(ratio, 1.0);
|
||||
return std::min( ratio, 1.0 );
|
||||
}
|
||||
|
|
|
@ -262,7 +262,8 @@ public:
|
|||
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 )
|
||||
{
|
||||
if( aPadsLocked )
|
||||
|
@ -569,9 +570,9 @@ public:
|
|||
m_initial_comments = aInitialComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function PadCoverageRatio
|
||||
* Calculates the ratio of total area of the footprint pads to the area of the
|
||||
/**
|
||||
* Function PadCoverageRatio
|
||||
* Calculates the ratio of total area of the footprint pads to the area of the
|
||||
* footprint. Used by selection tool heuristics.
|
||||
* @return the ratio
|
||||
*/
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
///< used for edge board connectors
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
|
||||
~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();
|
||||
}
|
||||
|
|
|
@ -313,9 +313,9 @@ void DIALOG_MODULE_BOARD_EDITOR::InitModeditProperties()
|
|||
break;
|
||||
}
|
||||
|
||||
if (m_CurrentModule->IsLocked() )
|
||||
if( m_CurrentModule->IsLocked() )
|
||||
m_AutoPlaceCtrl->SetSelection( 2 );
|
||||
else if (m_CurrentModule->PadsLocked() )
|
||||
else if( m_CurrentModule->PadsLocked() )
|
||||
m_AutoPlaceCtrl->SetSelection( 1 );
|
||||
else
|
||||
m_AutoPlaceCtrl->SetSelection( 0 );
|
||||
|
|
|
@ -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_BASE( aParent ),
|
||||
m_traceWidth ( this, m_traceWidthText, m_traceWidthUnit ),
|
||||
m_traceGap (this, m_traceGapText, m_traceGapUnit ),
|
||||
m_viaGap ( this, m_viaGapText, m_viaGapUnit ),
|
||||
m_traceWidth( this, m_traceWidthText, m_traceWidthUnit ),
|
||||
m_traceGap( this, m_traceGapText, m_traceGapUnit ),
|
||||
m_viaGap( this, m_viaGapText, m_viaGapUnit ),
|
||||
m_sizes( aSizes )
|
||||
|
||||
{
|
||||
m_traceWidth.SetValue ( aSizes.DiffPairWidth() );
|
||||
m_traceGap.SetValue ( aSizes.DiffPairGap() );
|
||||
m_viaGap.SetValue ( aSizes.DiffPairViaGap() );
|
||||
m_viaTraceGapEqual->SetValue ( m_sizes.DiffPairViaGapSameAsTraceGap() );
|
||||
|
||||
m_traceWidth.SetValue( aSizes.DiffPairWidth() );
|
||||
m_traceGap.SetValue( aSizes.DiffPairGap() );
|
||||
m_viaGap.SetValue( aSizes.DiffPairViaGap() );
|
||||
m_viaTraceGapEqual->SetValue( m_sizes.DiffPairViaGapSameAsTraceGap() );
|
||||
|
||||
updateCheckbox();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::updateCheckbox()
|
||||
{
|
||||
printf("Checked: %d", m_viaTraceGapEqual->GetValue());
|
||||
if( m_viaTraceGapEqual->GetValue() )
|
||||
{
|
||||
m_sizes.SetDiffPairViaGapSameAsTraceGap( true );
|
||||
|
@ -58,6 +57,7 @@ void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::updateCheckbox()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnClose( wxCloseEvent& aEvent )
|
||||
{
|
||||
// Do nothing, it is result of ESC pressing
|
||||
|
@ -71,7 +71,7 @@ void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnOkClick( wxCommandEvent& aEvent )
|
|||
m_sizes.SetDiffPairGap ( m_traceGap.GetValue() );
|
||||
m_sizes.SetDiffPairViaGap ( m_viaGap.GetValue() );
|
||||
m_sizes.SetDiffPairWidth ( m_traceWidth.GetValue() );
|
||||
|
||||
|
||||
// todo: verify against design rules
|
||||
EndModal( 1 );
|
||||
}
|
||||
|
@ -83,9 +83,10 @@ void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnCancelClick( wxCommandEvent& aEvent )
|
|||
EndModal( 0 );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnViaTraceGapEqualCheck( wxCommandEvent& event )
|
||||
{
|
||||
event.Skip();
|
||||
updateCheckbox();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,23 +33,22 @@ class PNS_SIZES_SETTINGS;
|
|||
|
||||
class DIALOG_PNS_DIFF_PAIR_DIMENSIONS : public DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes );
|
||||
public:
|
||||
DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes );
|
||||
|
||||
virtual void OnClose( wxCloseEvent& aEvent );
|
||||
virtual void OnOkClick( wxCommandEvent& aEvent );
|
||||
virtual void OnCancelClick( wxCommandEvent& aEvent );
|
||||
virtual void OnViaTraceGapEqualCheck( wxCommandEvent& event );
|
||||
|
||||
virtual void OnClose( wxCloseEvent& aEvent );
|
||||
virtual void OnOkClick( wxCommandEvent& aEvent );
|
||||
virtual void OnCancelClick( wxCommandEvent& aEvent );
|
||||
virtual void OnViaTraceGapEqualCheck( wxCommandEvent& event );
|
||||
|
||||
private:
|
||||
void updateCheckbox( );
|
||||
private:
|
||||
void updateCheckbox();
|
||||
|
||||
WX_UNIT_BINDER m_traceWidth;
|
||||
WX_UNIT_BINDER m_traceGap;
|
||||
WX_UNIT_BINDER m_viaGap;
|
||||
WX_UNIT_BINDER m_traceWidth;
|
||||
WX_UNIT_BINDER m_traceGap;
|
||||
WX_UNIT_BINDER m_viaGap;
|
||||
|
||||
PNS_SIZES_SETTINGS& m_sizes;
|
||||
PNS_SIZES_SETTINGS& m_sizes;
|
||||
};
|
||||
|
||||
#endif // __dialog_pns_settings__
|
||||
|
|
|
@ -20,63 +20,59 @@
|
|||
|
||||
/**
|
||||
* Length tuner settings dialog.
|
||||
*/
|
||||
*/
|
||||
|
||||
#include "dialog_pns_length_tuning_settings.h"
|
||||
#include <router/pns_meander_placer.h>
|
||||
|
||||
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 ),
|
||||
m_minAmpl ( this, m_minAmplText, m_minAmplUnit ),
|
||||
m_maxAmpl (this, m_maxAmplText, m_maxAmplUnit ),
|
||||
m_spacing ( this, m_spacingText, m_spacingUnit ),
|
||||
m_targetLength ( this, m_targetLengthText, m_targetLengthUnit ),
|
||||
m_minAmpl( this, m_minAmplText, m_minAmplUnit ),
|
||||
m_maxAmpl( this, m_maxAmplText, m_maxAmplUnit ),
|
||||
m_spacing( this, m_spacingText, m_spacingUnit ),
|
||||
m_targetLength( this, m_targetLengthText, m_targetLengthUnit ),
|
||||
m_settings( aSettings ),
|
||||
m_mode ( aMode )
|
||||
m_mode( aMode )
|
||||
{
|
||||
|
||||
m_miterStyle->Enable ( false );
|
||||
m_radiusText->Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR );
|
||||
m_miterStyle->Enable( false );
|
||||
m_radiusText->Enable( aMode != PNS_MODE_TUNE_DIFF_PAIR );
|
||||
//m_minAmpl.Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR_SKEW );
|
||||
|
||||
m_minAmpl.SetValue ( m_settings.m_minAmplitude );
|
||||
m_maxAmpl.SetValue ( m_settings.m_maxAmplitude );
|
||||
|
||||
m_spacing.SetValue ( m_settings.m_spacing );
|
||||
m_radiusText->SetValue ( wxString::Format(wxT("%i"), m_settings.m_cornerRadiusPercentage) );
|
||||
m_minAmpl.SetValue( m_settings.m_minAmplitude );
|
||||
m_maxAmpl.SetValue( m_settings.m_maxAmplitude );
|
||||
|
||||
|
||||
m_miterStyle->SetSelection ( m_settings.m_cornerType == PNS_MEANDER_SETTINGS::ROUND ? 1 : 0 );
|
||||
m_spacing.SetValue( m_settings.m_spacing );
|
||||
m_radiusText->SetValue( wxString::Format( wxT( "%i" ), m_settings.m_cornerRadiusPercentage ) );
|
||||
|
||||
m_miterStyle->SetSelection( m_settings.m_cornerType == PNS_MEANDER_SETTINGS::ROUND ? 1 : 0 );
|
||||
|
||||
switch( aMode )
|
||||
{
|
||||
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_targetLength.SetValue ( m_settings.m_targetLength );
|
||||
|
||||
m_targetLength.SetValue( m_settings.m_targetLength );
|
||||
break;
|
||||
|
||||
|
||||
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_targetLength.SetValue ( m_settings.m_targetLength );
|
||||
|
||||
m_targetLength.SetValue( m_settings.m_targetLength );
|
||||
break;
|
||||
|
||||
|
||||
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_targetLengthLabel->SetLabel( _("Target skew: ") );
|
||||
m_targetLengthLabel->SetLabel( _( "Target skew: " ) );
|
||||
m_targetLength.SetValue ( m_settings.m_targetSkew );
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_stdButtonsOK->SetDefault();
|
||||
m_targetLengthText->SetSelection(-1, -1);
|
||||
m_targetLengthText->SetSelection( -1, -1 );
|
||||
m_targetLengthText->SetFocus();
|
||||
}
|
||||
|
||||
|
@ -90,26 +86,22 @@ void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnClose( wxCloseEvent& aEvent )
|
|||
|
||||
void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
|
||||
{
|
||||
|
||||
// fixme: use validators and TransferDataFromWindow
|
||||
m_settings.m_minAmplitude = m_minAmpl.GetValue();
|
||||
m_settings.m_maxAmplitude = m_maxAmpl.GetValue();
|
||||
m_settings.m_spacing = m_spacing.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();
|
||||
else
|
||||
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_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 );
|
||||
}
|
||||
|
|
|
@ -35,22 +35,21 @@ class PNS_MEANDER_SETTINGS;
|
|||
|
||||
class DIALOG_PNS_LENGTH_TUNING_SETTINGS : public DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode );
|
||||
public:
|
||||
DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode );
|
||||
|
||||
virtual void OnClose( wxCloseEvent& aEvent );
|
||||
virtual void OnOkClick( wxCommandEvent& aEvent );
|
||||
virtual void OnCancelClick( wxCommandEvent& aEvent );
|
||||
|
||||
private:
|
||||
virtual void OnClose( wxCloseEvent& aEvent );
|
||||
virtual void OnOkClick( wxCommandEvent& aEvent );
|
||||
virtual void OnCancelClick( wxCommandEvent& aEvent );
|
||||
|
||||
WX_UNIT_BINDER m_minAmpl;
|
||||
WX_UNIT_BINDER m_maxAmpl;
|
||||
WX_UNIT_BINDER m_spacing;
|
||||
WX_UNIT_BINDER m_targetLength;
|
||||
private:
|
||||
WX_UNIT_BINDER m_minAmpl;
|
||||
WX_UNIT_BINDER m_maxAmpl;
|
||||
WX_UNIT_BINDER m_spacing;
|
||||
WX_UNIT_BINDER m_targetLength;
|
||||
|
||||
PNS_MEANDER_SETTINGS& m_settings;
|
||||
PNS_ROUTER_MODE m_mode;
|
||||
PNS_MEANDER_SETTINGS& m_settings;
|
||||
PNS_ROUTER_MODE m_mode;
|
||||
};
|
||||
|
||||
#endif // __dialog_pns_settings__
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,16 +42,16 @@ DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SE
|
|||
m_viaDrill.SetValue( m_settings.GetCustomViaDrill() );
|
||||
|
||||
m_trackWidthText->SetFocus();
|
||||
m_trackWidthText->SetSelection(-1, -1);
|
||||
m_trackWidthText->SetSelection( -1, -1 );
|
||||
m_stdButtonsOK->SetDefault();
|
||||
|
||||
|
||||
// Pressing ENTER when any of the text input fields is active applies changes
|
||||
#if wxCHECK_VERSION( 3, 0, 0 )
|
||||
Connect( wxEVT_TEXT_ENTER, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE::onOkClick ), NULL, this );
|
||||
#else
|
||||
Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE::onOkClick ), NULL, this );
|
||||
#endif
|
||||
|
||||
|
||||
Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_TRACK_VIA_SIZE::onClose ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -34,26 +34,25 @@ class BOARD_DESIGN_SETTINGS;
|
|||
/** Implementing DIALOG_TRACK_VIA_SIZE_BASE */
|
||||
class DIALOG_TRACK_VIA_SIZE : public DIALOG_TRACK_VIA_SIZE_BASE
|
||||
{
|
||||
public:
|
||||
/** Constructor */
|
||||
DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings );
|
||||
public:
|
||||
/** Constructor */
|
||||
DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings );
|
||||
|
||||
protected:
|
||||
protected:
|
||||
WX_UNIT_BINDER m_trackWidth;
|
||||
WX_UNIT_BINDER m_viaDiameter;
|
||||
WX_UNIT_BINDER m_viaDrill;
|
||||
|
||||
WX_UNIT_BINDER m_trackWidth;
|
||||
WX_UNIT_BINDER m_viaDiameter;
|
||||
WX_UNIT_BINDER m_viaDrill;
|
||||
// Routings settings that are modified by the dialog.
|
||||
BOARD_DESIGN_SETTINGS& m_settings;
|
||||
|
||||
// Routings settings that are modified by the dialog.
|
||||
BOARD_DESIGN_SETTINGS& m_settings;
|
||||
///> Checks if values given in the dialog are sensible.
|
||||
bool check();
|
||||
|
||||
///> Checks if values given in the dialog are sensible.
|
||||
bool check();
|
||||
|
||||
// Handlers for DIALOG_TRACK_VIA_SIZE_BASE events.
|
||||
void onClose( wxCloseEvent& aEvent );
|
||||
void onOkClick( wxCommandEvent& aEvent );
|
||||
void onCancelClick( wxCommandEvent& aEvent );
|
||||
// Handlers for DIALOG_TRACK_VIA_SIZE_BASE events.
|
||||
void onClose( wxCloseEvent& aEvent );
|
||||
void onOkClick( wxCommandEvent& aEvent );
|
||||
void onCancelClick( wxCommandEvent& aEvent );
|
||||
};
|
||||
|
||||
#endif // __dialog_track_via_size__
|
||||
|
|
|
@ -63,7 +63,7 @@ static void DisplayCmpDoc( wxString& aName, void* aData );
|
|||
|
||||
static FOOTPRINT_LIST MList;
|
||||
|
||||
static void clearModuleItemFlags ( BOARD_ITEM *aItem )
|
||||
static void clearModuleItemFlags( BOARD_ITEM* aItem )
|
||||
{
|
||||
aItem->ClearFlags();
|
||||
}
|
||||
|
|
|
@ -515,7 +515,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
|||
_( "Configure Interactive Routing." ),
|
||||
KiBitmap( add_tracks_xpm ) ); // fixme: icon
|
||||
|
||||
|
||||
//--- dimensions submenu ------------------------------------------------------
|
||||
wxMenu* dimensionsMenu = new wxMenu;
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
#include <tool/tool_dispatcher.h>
|
||||
#include <tools/common_actions.h>
|
||||
|
||||
|
||||
#include <scripting/python_console_frame.h>
|
||||
|
||||
#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
|
||||
|
@ -537,7 +536,7 @@ void PCB_EDIT_FRAME::setupTools()
|
|||
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
|
||||
|
||||
// Register tools
|
||||
registerAllTools ( m_toolManager );
|
||||
registerAllTools( m_toolManager );
|
||||
|
||||
m_toolManager->ResetTools( TOOL_BASE::RUN );
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ enum pcbnew_ids
|
|||
ID_MENU_ADD_TEARDROPS,
|
||||
ID_MENU_DIFF_PAIR_DIMENSIONS,
|
||||
ID_MENU_INTERACTIVE_ROUTER_SETTINGS,
|
||||
|
||||
|
||||
ID_PCB_MASK_CLEARANCE,
|
||||
ID_PCB_LAYERS_SETUP,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
|
@ -180,7 +180,7 @@ public:
|
|||
return ( m_dir % 2 ) == 1;
|
||||
}
|
||||
|
||||
bool IsDefined() const
|
||||
bool IsDefined() const
|
||||
{
|
||||
return m_dir != UNDEFINED;
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ public:
|
|||
l.m_dir = NW;
|
||||
else
|
||||
l.m_dir = static_cast<Directions>( m_dir - 1 );
|
||||
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
|
@ -303,10 +303,10 @@ public:
|
|||
case NW: return VECTOR2I( -1, 1 );
|
||||
case SE: return VECTOR2I( 1, -1 );
|
||||
case SW: return VECTOR2I( -1, -1 );
|
||||
|
||||
|
||||
default:
|
||||
return VECTOR2I( 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Mask() const
|
||||
|
@ -320,7 +320,8 @@ private:
|
|||
* Function construct()
|
||||
* 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.
|
||||
* @param aVec our vector */
|
||||
* @param aVec our vector
|
||||
*/
|
||||
void construct_( const VECTOR2I& aVec )
|
||||
{
|
||||
m_dir = UNDEFINED;
|
||||
|
@ -343,40 +344,14 @@ private:
|
|||
|
||||
if( dir < 0 )
|
||||
dir = dir + 8;
|
||||
|
||||
|
||||
m_dir = (Directions) dir;
|
||||
|
||||
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
|
||||
Directions m_dir;
|
||||
Directions m_dir;
|
||||
};
|
||||
|
||||
#endif // __DIRECTION_H
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
TUNER_TOOL_MENU( BOARD* aBoard )
|
||||
{
|
||||
SetTitle( wxT( "Length Tuner" ) );
|
||||
|
||||
|
||||
//Add( ACT_StartTuning );
|
||||
//Add( ACT_EndTuning );
|
||||
|
||||
|
@ -96,7 +96,7 @@ public:
|
|||
Add( ACT_SpacingDecrease );
|
||||
Add( ACT_AmplIncrease );
|
||||
Add( ACT_AmplDecrease );
|
||||
Add( ACT_Settings );
|
||||
Add( ACT_Settings );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -106,10 +106,11 @@ LENGTH_TUNER_TOOL::~LENGTH_TUNER_TOOL()
|
|||
delete m_router;
|
||||
}
|
||||
|
||||
|
||||
void LENGTH_TUNER_TOOL::Reset( RESET_REASON aReason )
|
||||
{
|
||||
PNS_TOOL_BASE::Reset( aReason );
|
||||
|
||||
|
||||
Go( &LENGTH_TUNER_TOOL::TuneSingleTrace, COMMON_ACTIONS::routerActivateTuneSingleTrace.MakeEvent() );
|
||||
Go( &LENGTH_TUNER_TOOL::TuneDiffPair, COMMON_ACTIONS::routerActivateTuneDiffPair.MakeEvent() );
|
||||
Go( &LENGTH_TUNER_TOOL::TuneDiffPairSkew, COMMON_ACTIONS::routerActivateTuneDiffPairSkew.MakeEvent() );
|
||||
|
@ -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;
|
||||
|
||||
if( aEvent.IsAction( &ACT_Settings ) )
|
||||
|
@ -143,15 +144,16 @@ void LENGTH_TUNER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent )
|
|||
placer->UpdateSettings ( settings );
|
||||
}
|
||||
|
||||
m_savedMeanderSettings = placer->MeanderSettings( );
|
||||
m_savedMeanderSettings = placer->MeanderSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LENGTH_TUNER_TOOL::performTuning()
|
||||
{
|
||||
bool saveUndoBuffer = true;
|
||||
|
||||
if(m_startItem)
|
||||
|
||||
if( m_startItem )
|
||||
{
|
||||
m_frame->SetActiveLayer( ToLAYER_ID ( m_startItem->Layers().Start() ) );
|
||||
|
||||
|
@ -162,22 +164,21 @@ void LENGTH_TUNER_TOOL::performTuning()
|
|||
m_ctls->ForceCursorPosition( false );
|
||||
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") );
|
||||
highlightNet ( false );
|
||||
wxMessageBox( m_router->FailureReason(), _( "Error" ) );
|
||||
highlightNet( false );
|
||||
return;
|
||||
}
|
||||
|
||||
PNS_TUNE_STATUS_POPUP statusPopup ( m_frame );
|
||||
PNS_TUNE_STATUS_POPUP statusPopup( m_frame );
|
||||
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;
|
||||
|
||||
placer->UpdateSettings( m_savedMeanderSettings );
|
||||
|
||||
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
if( evt->IsCancel() || evt->IsActivate() )
|
||||
|
@ -194,10 +195,10 @@ void LENGTH_TUNER_TOOL::performTuning()
|
|||
|
||||
wxPoint p = wxGetMousePosition();
|
||||
|
||||
p.x+=20;
|
||||
p.y+=20;
|
||||
p.x += 20;
|
||||
p.y += 20;
|
||||
|
||||
statusPopup.Update ( m_router );
|
||||
statusPopup.Update( m_router );
|
||||
statusPopup.Move( p );
|
||||
}
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
|
@ -209,16 +210,24 @@ void LENGTH_TUNER_TOOL::performTuning()
|
|||
{
|
||||
if( m_router->FixRoute( end, NULL ) )
|
||||
break;
|
||||
} else if (evt->IsAction ( &ACT_AmplDecrease ) ) {
|
||||
}
|
||||
else if( evt->IsAction( &ACT_AmplDecrease ) )
|
||||
{
|
||||
placer->AmplitudeStep( -1 );
|
||||
m_router->Move( end, NULL );
|
||||
} else if (evt->IsAction ( &ACT_AmplIncrease ) ) {
|
||||
}
|
||||
else if( evt->IsAction( &ACT_AmplIncrease ) )
|
||||
{
|
||||
placer->AmplitudeStep( 1 );
|
||||
m_router->Move( end, NULL );
|
||||
} else if (evt->IsAction ( &ACT_SpacingDecrease ) ) {
|
||||
}
|
||||
else if(evt->IsAction( &ACT_SpacingDecrease ) )
|
||||
{
|
||||
placer->SpacingStep( -1 );
|
||||
m_router->Move( end, NULL );
|
||||
} else if (evt->IsAction ( &ACT_SpacingIncrease ) ) {
|
||||
}
|
||||
else if( evt->IsAction( &ACT_SpacingIncrease ) )
|
||||
{
|
||||
placer->SpacingStep( 1 );
|
||||
m_router->Move( end, NULL );
|
||||
}
|
||||
|
@ -244,27 +253,29 @@ void LENGTH_TUNER_TOOL::performTuning()
|
|||
m_ctls->SetAutoPan( false );
|
||||
m_ctls->ForceCursorPosition( 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" ) );
|
||||
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" ) );
|
||||
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" ) );
|
||||
return mainLoop( PNS_MODE_TUNE_DIFF_PAIR_SKEW );
|
||||
}
|
||||
|
||||
|
||||
|
||||
int LENGTH_TUNER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
||||
{
|
||||
|
@ -273,13 +284,13 @@ int LENGTH_TUNER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
|||
|
||||
Activate();
|
||||
|
||||
m_router->SetMode ( aMode );
|
||||
|
||||
m_router->SetMode( aMode );
|
||||
|
||||
m_ctls->SetSnapping( true );
|
||||
m_ctls->ShowCursor( true );
|
||||
|
||||
std::auto_ptr<TUNER_TOOL_MENU> ctxMenu ( new TUNER_TOOL_MENU( m_board ) );
|
||||
SetContextMenu ( ctxMenu.get() );
|
||||
std::auto_ptr<TUNER_TOOL_MENU> ctxMenu( new TUNER_TOOL_MENU( m_board ) );
|
||||
SetContextMenu( ctxMenu.get() );
|
||||
|
||||
// Main loop: keep receiving events
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
|
@ -300,7 +311,7 @@ int LENGTH_TUNER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
|||
else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_StartTuning ) )
|
||||
{
|
||||
updateStartItem( *evt );
|
||||
performTuning( );
|
||||
performTuning( );
|
||||
}
|
||||
|
||||
handleCommonEvents( *evt );
|
||||
|
@ -316,4 +327,4 @@ int LENGTH_TUNER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
|||
m_savedSizes = m_router->Sizes();
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,16 +35,15 @@ public:
|
|||
|
||||
void Reset( RESET_REASON aReason );
|
||||
|
||||
int TuneSingleTrace ( const TOOL_EVENT& aEvent );
|
||||
int TuneDiffPair ( const TOOL_EVENT& aEvent );
|
||||
int TuneDiffPairSkew ( const TOOL_EVENT& aEvent );
|
||||
int ClearMeanders ( const TOOL_EVENT& aEvent );
|
||||
int TuneSingleTrace( const TOOL_EVENT& aEvent );
|
||||
int TuneDiffPair( const TOOL_EVENT& aEvent );
|
||||
int TuneDiffPairSkew( const TOOL_EVENT& aEvent );
|
||||
int ClearMeanders( const TOOL_EVENT& aEvent );
|
||||
|
||||
private:
|
||||
|
||||
void performTuning( );
|
||||
int mainLoop( PNS_ROUTER_MODE aMode );
|
||||
void handleCommonEvents( const TOOL_EVENT& evt );
|
||||
void handleCommonEvents( const TOOL_EVENT& aEvent );
|
||||
|
||||
PNS_MEANDER_SETTINGS m_savedMeanderSettings;
|
||||
};
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
|
||||
PNS_ROUTING_SETTINGS& PNS_ALGO_BASE::Settings() const
|
||||
{
|
||||
return m_router->Settings();
|
||||
return m_router->Settings();
|
||||
}
|
||||
|
||||
PNS_LOGGER *PNS_ALGO_BASE::Logger()
|
||||
PNS_LOGGER *PNS_ALGO_BASE::Logger()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#define __PNS_ALGO_BASE_H
|
||||
|
||||
#include <wx/wx.h> // for wxString
|
||||
|
||||
|
||||
#include "pns_routing_settings.h"
|
||||
|
||||
class PNS_ROUTER;
|
||||
|
@ -33,32 +33,30 @@ class PNS_LOGGER;
|
|||
*
|
||||
* 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)
|
||||
**/
|
||||
|
||||
*/
|
||||
class PNS_ALGO_BASE
|
||||
{
|
||||
public:
|
||||
PNS_ALGO_BASE( PNS_ROUTER *aRouter ) :
|
||||
m_router ( aRouter )
|
||||
{}
|
||||
PNS_ALGO_BASE( PNS_ROUTER* aRouter ) :
|
||||
m_router( aRouter )
|
||||
{}
|
||||
|
||||
virtual ~PNS_ALGO_BASE() {}
|
||||
virtual ~PNS_ALGO_BASE() {}
|
||||
|
||||
///> Returns the instance of our router
|
||||
PNS_ROUTER* Router() const
|
||||
{
|
||||
return m_router;
|
||||
}
|
||||
///> Returns the instance of our router
|
||||
PNS_ROUTER* Router() const
|
||||
{
|
||||
return m_router;
|
||||
}
|
||||
|
||||
///> Returns current router settings
|
||||
PNS_ROUTING_SETTINGS& Settings() const;
|
||||
///> Returns current router settings
|
||||
PNS_ROUTING_SETTINGS& Settings() const;
|
||||
|
||||
///> Returns the logger object, allowing to dump geometry to a file.
|
||||
virtual PNS_LOGGER* Logger();
|
||||
///> Returns the logger object, allowing to dump geometry to a file.
|
||||
virtual PNS_LOGGER* Logger();
|
||||
|
||||
|
||||
private:
|
||||
PNS_ROUTER* m_router;
|
||||
PNS_ROUTER* m_router;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,23 +43,22 @@ class PNS_DIFF_PAIR;
|
|||
**/
|
||||
class PNS_DP_GATEWAY {
|
||||
public:
|
||||
PNS_DP_GATEWAY ( const VECTOR2I& aAnchorP,
|
||||
const VECTOR2I& aAnchorN,
|
||||
bool aIsDiagonal,
|
||||
int aAllowedEntryAngles = DIRECTION_45::ANG_OBTUSE,
|
||||
int aPriority = 0 )
|
||||
: m_anchorP(aAnchorP),
|
||||
m_anchorN (aAnchorN),
|
||||
m_isDiagonal( aIsDiagonal ),
|
||||
m_allowedEntryAngles (aAllowedEntryAngles),
|
||||
m_priority(aPriority)
|
||||
PNS_DP_GATEWAY( const VECTOR2I& aAnchorP,
|
||||
const VECTOR2I& aAnchorN,
|
||||
bool aIsDiagonal,
|
||||
int aAllowedEntryAngles = DIRECTION_45::ANG_OBTUSE,
|
||||
int aPriority = 0 )
|
||||
: m_anchorP( aAnchorP ),
|
||||
m_anchorN( aAnchorN ),
|
||||
m_isDiagonal( aIsDiagonal ),
|
||||
m_allowedEntryAngles( aAllowedEntryAngles ),
|
||||
m_priority( aPriority )
|
||||
{
|
||||
m_hasEntryLines = false;
|
||||
}
|
||||
|
||||
~PNS_DP_GATEWAY ()
|
||||
~PNS_DP_GATEWAY()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,15 +66,15 @@ public:
|
|||
*
|
||||
* @return true, if the gateway anchors lie on a diagonal line
|
||||
*/
|
||||
|
||||
bool IsDiagonal() const
|
||||
{
|
||||
return m_isDiagonal;
|
||||
return m_isDiagonal;
|
||||
}
|
||||
|
||||
const VECTOR2I& AnchorP () const { return m_anchorP; }
|
||||
const VECTOR2I& AnchorN () const { return m_anchorN; }
|
||||
|
||||
const VECTOR2I& AnchorP() const { return m_anchorP; }
|
||||
|
||||
const VECTOR2I& AnchorN() const { return m_anchorN; }
|
||||
|
||||
/**
|
||||
* Function AllowedAngles()
|
||||
*
|
||||
|
@ -89,36 +88,35 @@ public:
|
|||
*
|
||||
* @return priority/score value for gateway matching
|
||||
*/
|
||||
int Priority() const
|
||||
{
|
||||
int Priority() const
|
||||
{
|
||||
return m_priority;
|
||||
}
|
||||
|
||||
void SetPriority(int aPriority)
|
||||
|
||||
void SetPriority(int 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_entryN = aEntryN;
|
||||
m_hasEntryLines = true;
|
||||
}
|
||||
|
||||
const SHAPE_LINE_CHAIN& EntryP () const { return m_entryP; }
|
||||
const SHAPE_LINE_CHAIN& EntryN () const { return m_entryN; }
|
||||
const SHAPE_LINE_CHAIN& EntryP() const { return m_entryP; }
|
||||
const SHAPE_LINE_CHAIN& EntryN() const { return m_entryN; }
|
||||
const PNS_DIFF_PAIR Entry() const ;
|
||||
|
||||
void Reverse();
|
||||
|
||||
bool HasEntryLines () const
|
||||
{
|
||||
return m_hasEntryLines;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void Reverse();
|
||||
|
||||
bool HasEntryLines () const
|
||||
{
|
||||
return m_hasEntryLines;
|
||||
}
|
||||
|
||||
private:
|
||||
SHAPE_LINE_CHAIN m_entryP, m_entryN;
|
||||
bool m_hasEntryLines;
|
||||
VECTOR2I m_anchorP, m_anchorN;
|
||||
|
@ -134,37 +132,36 @@ private:
|
|||
**/
|
||||
class PNS_DP_PRIMITIVE_PAIR
|
||||
{
|
||||
|
||||
public:
|
||||
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 ( PNS_ITEM *aPrimP, PNS_ITEM *aPrimN );
|
||||
PNS_DP_PRIMITIVE_PAIR ( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
|
||||
PNS_DP_PRIMITIVE_PAIR( const PNS_DP_PRIMITIVE_PAIR& aOther );
|
||||
PNS_DP_PRIMITIVE_PAIR( PNS_ITEM* aPrimP, PNS_ITEM* aPrimN );
|
||||
PNS_DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
|
||||
|
||||
~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& AnchorN () const { return m_anchorN; }
|
||||
const VECTOR2I& AnchorP() const { return m_anchorP; }
|
||||
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* PrimN () const { return m_primN; }
|
||||
PNS_ITEM* PrimP() const { return m_primP; }
|
||||
PNS_ITEM* PrimN() const { return m_primN; }
|
||||
|
||||
bool Directional() const;
|
||||
|
||||
DIRECTION_45 DirP () const;
|
||||
DIRECTION_45 DirN () const;
|
||||
DIRECTION_45 DirP() const;
|
||||
DIRECTION_45 DirN() const;
|
||||
|
||||
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, *m_primN;
|
||||
PNS_ITEM* m_primP;
|
||||
PNS_ITEM* m_primN;
|
||||
VECTOR2I m_anchorP, m_anchorN;
|
||||
};
|
||||
|
||||
|
@ -174,21 +171,21 @@ private:
|
|||
* A set of gateways calculated for the cursor or starting/ending primitive pair.
|
||||
**/
|
||||
|
||||
class PNS_DP_GATEWAYS
|
||||
class PNS_DP_GATEWAYS
|
||||
{
|
||||
|
||||
public:
|
||||
PNS_DP_GATEWAYS ( int aGap ):
|
||||
m_gap(aGap), m_viaGap( aGap ) {};
|
||||
|
||||
void SetGap ( int aGap ) {
|
||||
m_gap = aGap;
|
||||
void SetGap ( int aGap ) {
|
||||
m_gap = aGap;
|
||||
m_viaGap = aGap;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_gateways.clear();
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_gateways.clear();
|
||||
}
|
||||
|
||||
void SetFitVias ( bool aEnable, int aDiameter = 0, int aViaGap = -1 )
|
||||
|
@ -201,12 +198,12 @@ class PNS_DP_GATEWAYS
|
|||
m_viaGap = aViaGap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BuildForCursor ( const VECTOR2I& aCursorPos );
|
||||
void BuildOrthoProjections ( PNS_DP_GATEWAYS &aEntries, const VECTOR2I& aCursorPos, int aOrthoScore );
|
||||
void BuildGeneric ( const VECTOR2I& p0_p, const VECTOR2I& p0_n, bool aBuildEntries = false, bool aViaMode = false );
|
||||
void BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal );
|
||||
|
||||
|
||||
bool FitGateways ( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget, bool aPrefDiagonal, PNS_DIFF_PAIR& aDp );
|
||||
|
||||
std::vector<PNS_DP_GATEWAY>& Gateways()
|
||||
|
@ -216,7 +213,7 @@ class PNS_DP_GATEWAYS
|
|||
|
||||
private:
|
||||
|
||||
struct DP_CANDIDATE
|
||||
struct DP_CANDIDATE
|
||||
{
|
||||
SHAPE_LINE_CHAIN p, n;
|
||||
VECTOR2I gw_p, gw_n;
|
||||
|
@ -246,7 +243,7 @@ class PNS_DIFF_PAIR : public PNS_ITEM {
|
|||
|
||||
public:
|
||||
struct COUPLED_SEGMENTS {
|
||||
COUPLED_SEGMENTS ( const SEG& aCoupledP, const SEG& aParentP, int aIndexP,
|
||||
COUPLED_SEGMENTS ( const SEG& aCoupledP, const SEG& aParentP, int aIndexP,
|
||||
const SEG& aCoupledN, const SEG& aParentN, int aIndexN ) :
|
||||
coupledP ( aCoupledP ),
|
||||
coupledN ( aCoupledN ),
|
||||
|
@ -255,7 +252,7 @@ public:
|
|||
indexP ( aIndexP ),
|
||||
indexN ( aIndexN )
|
||||
{}
|
||||
|
||||
|
||||
SEG coupledP;
|
||||
SEG coupledN;
|
||||
SEG parentP;
|
||||
|
@ -266,17 +263,17 @@ public:
|
|||
|
||||
typedef std::vector<COUPLED_SEGMENTS> COUPLED_SEGMENTS_VEC;
|
||||
|
||||
PNS_DIFF_PAIR ( ) : PNS_ITEM ( DIFF_PAIR ), m_hasVias (false) {}
|
||||
PNS_DIFF_PAIR ( ) : PNS_ITEM ( DIFF_PAIR ), m_hasVias (false) {}
|
||||
|
||||
PNS_DIFF_PAIR ( int aGap ) :
|
||||
PNS_ITEM ( DIFF_PAIR ),
|
||||
PNS_DIFF_PAIR ( int aGap ) :
|
||||
PNS_ITEM ( DIFF_PAIR ),
|
||||
m_hasVias (false)
|
||||
{
|
||||
m_gapConstraint = aGap;
|
||||
}
|
||||
|
||||
PNS_DIFF_PAIR ( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, int aGap = 0 ):
|
||||
PNS_ITEM ( DIFF_PAIR ),
|
||||
PNS_ITEM ( DIFF_PAIR ),
|
||||
m_n (aN),
|
||||
m_p (aP),
|
||||
m_hasVias (false)
|
||||
|
@ -285,7 +282,7 @@ public:
|
|||
}
|
||||
|
||||
PNS_DIFF_PAIR ( const PNS_LINE &aLineP, const PNS_LINE &aLineN, int aGap = 0 ):
|
||||
PNS_ITEM ( DIFF_PAIR ),
|
||||
PNS_ITEM ( DIFF_PAIR ),
|
||||
m_line_p ( aLineP ),
|
||||
m_line_n ( aLineN ),
|
||||
m_hasVias (false)
|
||||
|
@ -301,8 +298,8 @@ public:
|
|||
{
|
||||
return aItem && DIFF_PAIR == aItem->Kind();
|
||||
}
|
||||
|
||||
PNS_DIFF_PAIR * Clone() const { assert(false); return NULL; }
|
||||
|
||||
PNS_DIFF_PAIR * Clone() const { assert(false); return NULL; }
|
||||
|
||||
static PNS_DIFF_PAIR* AssembleDp ( PNS_LINE *aLine );
|
||||
|
||||
|
@ -317,7 +314,7 @@ public:
|
|||
m_n = aN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SetShape ( const PNS_DIFF_PAIR& aPair )
|
||||
{
|
||||
m_p = aPair.m_p;
|
||||
|
@ -326,20 +323,20 @@ public:
|
|||
|
||||
void SetNets ( int aP, int aN )
|
||||
{
|
||||
m_net_p = aP;
|
||||
m_net_n = aN;
|
||||
m_net_p = aP;
|
||||
m_net_n = aN;
|
||||
}
|
||||
|
||||
|
||||
void SetWidth ( int aWidth )
|
||||
{
|
||||
m_width = aWidth;
|
||||
m_width = aWidth;
|
||||
}
|
||||
|
||||
int Width() const { return m_width; }
|
||||
|
||||
|
||||
void SetGap ( int aGap)
|
||||
{
|
||||
m_gap = aGap;
|
||||
m_gap = aGap;
|
||||
m_gapConstraint = RANGED_NUM<int> ( m_gap, 10000, 10000 );
|
||||
}
|
||||
|
||||
|
@ -364,24 +361,24 @@ public:
|
|||
return m_hasVias;
|
||||
}
|
||||
|
||||
int NetP() const
|
||||
int NetP() const
|
||||
{
|
||||
return m_net_p;
|
||||
}
|
||||
|
||||
int NetN() const
|
||||
int NetN() const
|
||||
{
|
||||
return m_net_n;
|
||||
}
|
||||
|
||||
PNS_LINE& PLine()
|
||||
PNS_LINE& PLine()
|
||||
{
|
||||
if ( !m_line_p.IsLinked ( ) )
|
||||
updateLine(m_line_p, m_p, m_net_p, m_via_p );
|
||||
return m_line_p;
|
||||
}
|
||||
}
|
||||
|
||||
PNS_LINE& NLine()
|
||||
PNS_LINE& NLine()
|
||||
{
|
||||
if ( !m_line_n.IsLinked ( ) )
|
||||
updateLine(m_line_n, m_n, m_net_n, m_via_n );
|
||||
|
@ -415,7 +412,7 @@ public:
|
|||
}
|
||||
const SHAPE_LINE_CHAIN& CP() const { return m_p; }
|
||||
const SHAPE_LINE_CHAIN& CN() const { return m_n; }
|
||||
|
||||
|
||||
bool BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal );
|
||||
bool CheckConnectionAngle ( const PNS_DIFF_PAIR &aOther, int allowedAngles ) const;
|
||||
int CoupledLength ( const SEG& aP, const SEG& aN ) const;
|
||||
|
@ -428,7 +425,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void updateLine( PNS_LINE &aLine, const SHAPE_LINE_CHAIN& aShape, int aNet, PNS_VIA& aVia )
|
||||
void updateLine( PNS_LINE &aLine, const SHAPE_LINE_CHAIN& aShape, int aNet, PNS_VIA& aVia )
|
||||
{
|
||||
aLine.SetShape( aShape );
|
||||
aLine.SetWidth( m_width );
|
||||
|
|
|
@ -57,74 +57,82 @@ 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;
|
||||
}
|
||||
|
||||
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() );
|
||||
|
||||
PNS_VIA v( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), -1, m_sizes.ViaType() );
|
||||
v.SetNet (aNet);
|
||||
v.SetNet( aNet );
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
void PNS_DIFF_PAIR_PLACER::SetOrthoMode ( bool 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 )
|
||||
{
|
||||
m_placingVia = aEnabled;
|
||||
if(!m_idle)
|
||||
Move ( m_currentEnd, NULL );
|
||||
|
||||
if( !m_idle )
|
||||
Move( m_currentEnd, NULL );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DIFF_PAIR_PLACER::rhMarkObstacles( const VECTOR2I& aP )
|
||||
{
|
||||
if( !routeHead ( aP ) )
|
||||
if( !routeHead( aP ) )
|
||||
return false;
|
||||
|
||||
bool collP = m_currentNode->CheckColliding( &m_currentTrace.PLine() );
|
||||
bool collN = m_currentNode->CheckColliding( &m_currentTrace.NLine() );
|
||||
|
||||
m_fitOk = !(collP || collN);
|
||||
|
||||
m_fitOk = !( collP || collN ) ;
|
||||
return m_fitOk;
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
virtHead.SetDiameter ( viaGap() + 2 * virtHead.Diameter() );
|
||||
else
|
||||
if( m_placingVia )
|
||||
virtHead.SetDiameter( viaGap() + 2 * virtHead.Diameter() );
|
||||
else
|
||||
{
|
||||
virtHead.SetLayer ( m_currentLayer );
|
||||
virtHead.SetDiameter ( m_sizes.DiffPairGap() + 2 * m_sizes.TrackWidth() );
|
||||
virtHead.SetLayer( m_currentLayer );
|
||||
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;
|
||||
bool solidsOnly = true;
|
||||
|
||||
bool solidsOnly = true;
|
||||
|
||||
if(m_currentMode == RM_MarkObstacles )
|
||||
if( m_currentMode == RM_MarkObstacles )
|
||||
{
|
||||
aNewP = aP;
|
||||
return true;
|
||||
} else if (m_currentMode == RM_Walkaround )
|
||||
return true;
|
||||
}
|
||||
else if( m_currentMode == RM_Walkaround )
|
||||
{
|
||||
solidsOnly = false;
|
||||
}
|
||||
|
||||
|
||||
// fixme: I'm too lazy to do it well. Circular approximaton will do for the moment.
|
||||
if( virtHead.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
|
||||
{
|
||||
|
@ -134,98 +142,96 @@ bool PNS_DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I&
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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_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.SetIterationLimit( Settings().WalkaroundIterationLimit() );
|
||||
|
||||
PNS_SHOVE shove(aNode, Router());
|
||||
PNS_SHOVE shove( aNode, Router() );
|
||||
PNS_LINE walkP, walkN;
|
||||
|
||||
|
||||
aWalk = *aCurrent;
|
||||
|
||||
|
||||
int iter = 0;
|
||||
|
||||
PNS_DIFF_PAIR cur (*aCurrent);
|
||||
|
||||
PNS_DIFF_PAIR cur( *aCurrent );
|
||||
|
||||
bool currentIsP = aPFirst;
|
||||
|
||||
int mask = aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY;
|
||||
|
||||
|
||||
//Router()->DisplayDebugLine( aCurrent->CP(), 4, 10000 );
|
||||
//Router()->DisplayDebugLine( aCurrent->CN(), 5, 10000 );
|
||||
|
||||
do {
|
||||
PNS_LINE preWalk = (currentIsP ? cur.PLine() : cur.NLine() );
|
||||
PNS_LINE preShove = (currentIsP ? cur.NLine() : cur.PLine() );
|
||||
do
|
||||
{
|
||||
PNS_LINE preWalk = ( currentIsP ? cur.PLine() : cur.NLine() );
|
||||
PNS_LINE preShove = ( currentIsP ? cur.NLine() : cur.PLine() );
|
||||
PNS_LINE postWalk;
|
||||
|
||||
if (!aNode->CheckColliding ( &preWalk, mask ) )
|
||||
{
|
||||
|
||||
if( !aNode->CheckColliding ( &preWalk, mask ) )
|
||||
{
|
||||
currentIsP = !currentIsP;
|
||||
|
||||
if (!aNode->CheckColliding ( &preShove, mask ) )
|
||||
|
||||
if( !aNode->CheckColliding( &preShove, mask ) )
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
wf1 = walkaround.Route( preWalk, postWalk, false );
|
||||
|
||||
if(wf1 != PNS_WALKAROUND::DONE)
|
||||
if( wf1 != PNS_WALKAROUND::DONE )
|
||||
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;
|
||||
|
||||
|
||||
sh1 = shove.ProcessSingleLine( &postWalk, &preShove, &postShove );
|
||||
|
||||
if(sh1 != PNS_SHOVE::SH_OK)
|
||||
if( sh1 != PNS_SHOVE::SH_OK )
|
||||
return false;
|
||||
|
||||
postWalk.Line().Simplify();
|
||||
postShove.Line().Simplify();
|
||||
|
||||
cur.SetShape( postWalk.CLine(), postShove.CLine(), !currentIsP );
|
||||
|
||||
cur.SetShape ( postWalk.CLine(), postShove.CLine(), !currentIsP );
|
||||
|
||||
currentIsP = !currentIsP;
|
||||
|
||||
if (!aNode->CheckColliding ( &postShove, mask ) )
|
||||
|
||||
if( !aNode->CheckColliding( &postShove, mask ) )
|
||||
break;
|
||||
|
||||
|
||||
iter++;
|
||||
} while (iter < 3);
|
||||
}
|
||||
while( iter < 3 );
|
||||
|
||||
if(iter == 3)
|
||||
if( iter == 3 )
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
aWalk.SetShape(cur.CP(), cur.CN() );
|
||||
Router()->GetClearanceFunc()->OverrideClearance ( false );
|
||||
aWalk.SetShape( cur.CP(), cur.CN() );
|
||||
Router()->GetClearanceFunc()->OverrideClearance( false );
|
||||
|
||||
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;
|
||||
double bestScore = 100000000000000.0;
|
||||
|
||||
for(int attempt = 0; attempt <= 1; attempt ++)
|
||||
for( int attempt = 0; attempt <= 1; attempt++ )
|
||||
{
|
||||
PNS_DIFF_PAIR p;
|
||||
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 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 cl = p.CoupledLength();
|
||||
|
@ -241,41 +247,42 @@ bool PNS_DIFF_PAIR_PLACER::tryWalkDp ( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bo
|
|||
|
||||
double score = cl + fabs(skew) * 3.0;
|
||||
|
||||
if(score < bestScore)
|
||||
if( score < bestScore )
|
||||
{
|
||||
bestScore = score;
|
||||
best = p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
if(bestScore > 0.0)
|
||||
|
||||
if( bestScore > 0.0 )
|
||||
{
|
||||
PNS_OPTIMIZER optimizer( m_currentNode );
|
||||
|
||||
aPair.SetShape ( best );
|
||||
aPair.SetShape( best );
|
||||
optimizer.Optimize( &aPair );
|
||||
|
||||
optimizer.Optimize ( &aPair );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DIFF_PAIR_PLACER::rhWalkOnly( const VECTOR2I& aP )
|
||||
{
|
||||
if ( !routeHead ( aP ) )
|
||||
if( !routeHead ( aP ) )
|
||||
return false;
|
||||
|
||||
m_fitOk = tryWalkDp ( m_currentNode, m_currentTrace, false );
|
||||
m_fitOk = tryWalkDp( m_currentNode, m_currentTrace, false );
|
||||
|
||||
return m_fitOk;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DIFF_PAIR_PLACER::route ( const VECTOR2I& aP )
|
||||
bool PNS_DIFF_PAIR_PLACER::route( const VECTOR2I& aP )
|
||||
{
|
||||
switch( m_currentMode )
|
||||
{
|
||||
|
@ -292,7 +299,8 @@ bool PNS_DIFF_PAIR_PLACER::route ( const VECTOR2I& aP )
|
|||
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();
|
||||
|
||||
|
@ -300,18 +308,18 @@ bool PNS_DIFF_PAIR_PLACER::rhShoveOnly ( const VECTOR2I& aP )
|
|||
|
||||
m_fitOk = false;
|
||||
|
||||
if(!ok)
|
||||
if( !ok )
|
||||
return false;
|
||||
|
||||
if (!tryWalkDp ( m_currentNode, m_currentTrace, true ) )
|
||||
if( !tryWalkDp( m_currentNode, m_currentTrace, true ) )
|
||||
return false;
|
||||
|
||||
PNS_LINE pLine ( m_currentTrace.PLine() );
|
||||
PNS_LINE nLine ( m_currentTrace.NLine() );
|
||||
|
||||
PNS_LINE pLine( m_currentTrace.PLine() );
|
||||
PNS_LINE nLine( m_currentTrace.NLine() );
|
||||
PNS_ITEMSET head;
|
||||
|
||||
head.Add ( &pLine );
|
||||
head.Add ( &nLine );
|
||||
head.Add( &pLine );
|
||||
head.Add( &nLine );
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveMultiLines( head );
|
||||
|
||||
|
@ -320,9 +328,9 @@ bool PNS_DIFF_PAIR_PLACER::rhShoveOnly ( const VECTOR2I& aP )
|
|||
if( status == PNS_SHOVE::SH_OK )
|
||||
{
|
||||
m_currentNode = m_shove->CurrentNode();
|
||||
|
||||
if( !m_currentNode->CheckColliding ( &m_currentTrace.PLine() ) &&
|
||||
!m_currentNode->CheckColliding ( &m_currentTrace.NLine() ) )
|
||||
|
||||
if( !m_currentNode->CheckColliding( &m_currentTrace.PLine() ) &&
|
||||
!m_currentNode->CheckColliding( &m_currentTrace.NLine() ) )
|
||||
{
|
||||
m_fitOk = true;
|
||||
}
|
||||
|
@ -332,14 +340,13 @@ bool PNS_DIFF_PAIR_PLACER::rhShoveOnly ( const VECTOR2I& aP )
|
|||
}
|
||||
|
||||
|
||||
|
||||
const PNS_ITEMSET PNS_DIFF_PAIR_PLACER::Traces()
|
||||
{
|
||||
PNS_ITEMSET t;
|
||||
|
||||
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.PLine() ) );
|
||||
t.Add( const_cast<PNS_LINE*>( &m_currentTrace.NLine() ) );
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -348,8 +355,8 @@ void PNS_DIFF_PAIR_PLACER::FlipPosture()
|
|||
{
|
||||
m_startDiagonal = !m_startDiagonal;
|
||||
|
||||
if(!m_idle)
|
||||
Move ( m_currentEnd, NULL );
|
||||
if( !m_idle )
|
||||
Move( m_currentEnd, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
@ -368,88 +375,97 @@ bool PNS_DIFF_PAIR_PLACER::SetLayer( int aLayer )
|
|||
{
|
||||
m_currentLayer = aLayer;
|
||||
return true;
|
||||
} else if( m_chainedPlacement )
|
||||
} else if( m_chainedPlacement )
|
||||
return false;
|
||||
else if( !m_prevPair )
|
||||
else if( !m_prevPair )
|
||||
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_start = *m_prevPair;
|
||||
initPlacement ( false );
|
||||
Move ( m_currentEnd, NULL );
|
||||
initPlacement( false );
|
||||
Move( m_currentEnd, NULL );
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
if (aNetName.EndsWith("+"))
|
||||
|
||||
if( aNetName.EndsWith( "+" ) )
|
||||
{
|
||||
aComplementNet = "-";
|
||||
rv = 1;
|
||||
} else if (aNetName.EndsWith("_P"))
|
||||
}
|
||||
else if( aNetName.EndsWith( "_P" ) )
|
||||
{
|
||||
aComplementNet = "_N";
|
||||
rv = 1;
|
||||
} else if (aNetName.EndsWith("-"))
|
||||
}
|
||||
else if( aNetName.EndsWith( "-" ) )
|
||||
{
|
||||
aComplementNet = "+";
|
||||
rv = -1;
|
||||
} else if (aNetName.EndsWith("_N"))
|
||||
}
|
||||
else if( aNetName.EndsWith( "_N" ) )
|
||||
{
|
||||
aComplementNet = "_P";
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
if (rv != 0) {
|
||||
aBaseDpName = aNetName.Left ( aNetName.Length() - aComplementNet.Length() );
|
||||
if( rv != 0 )
|
||||
{
|
||||
aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
|
||||
}
|
||||
|
||||
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::SOLID:
|
||||
return aItem->Anchor(0);
|
||||
return aItem->Anchor( 0 );
|
||||
|
||||
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 *jB = aNode->FindJoint( s->Seg().B, s );
|
||||
PNS_JOINT* jA = aNode->FindJoint( s->Seg().A, s );
|
||||
PNS_JOINT* jB = aNode->FindJoint( s->Seg().B, s );
|
||||
|
||||
if(jA->LinkCount() == 1)
|
||||
if( jA->LinkCount() == 1 )
|
||||
return s->Seg().A;
|
||||
else if (jB->LinkCount() == 1)
|
||||
else if( jB->LinkCount() == 1 )
|
||||
return s->Seg().B;
|
||||
else
|
||||
else
|
||||
return OPT_VECTOR2I();
|
||||
}
|
||||
|
||||
default:
|
||||
return OPT_VECTOR2I();
|
||||
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;
|
||||
|
||||
wxString netNameP = aItem->Parent()->GetNet()->GetNetname();
|
||||
wxString netNameN, netNameBase;
|
||||
|
||||
|
||||
BOARD *brd = Router()->GetBoard();
|
||||
BOARD* brd = Router()->GetBoard();
|
||||
PNS_ITEM *primRef = NULL, *primP = NULL, *primN = NULL;
|
||||
|
||||
// printf("Current %p\n", m_currentNode);
|
||||
|
@ -459,61 +475,65 @@ bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair ( const VECTOR2I& aP, PNS_ITEM *a
|
|||
|
||||
int r = matchDpSuffix ( netNameP, suffix, netNameBase );
|
||||
|
||||
if(r == 0)
|
||||
if( r == 0 )
|
||||
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;
|
||||
} else {
|
||||
primRef = primN = static_cast <PNS_SOLID *> (aItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
primRef = primN = static_cast<PNS_SOLID*>( aItem );
|
||||
netNameN = netNameP;
|
||||
netNameP = netNameBase + suffix;
|
||||
}
|
||||
|
||||
int netP = brd->FindNet ( netNameP )->GetNet();
|
||||
int netN = brd->FindNet ( netNameN )->GetNet();
|
||||
|
||||
if ( primP )
|
||||
int netP = brd->FindNet( netNameP )->GetNet();
|
||||
int netN = brd->FindNet( netNameN )->GetNet();
|
||||
|
||||
if( primP )
|
||||
refNet = netN;
|
||||
else
|
||||
refNet = netP;
|
||||
|
||||
|
||||
// printf("Net: P: %s N: %s\n", (const char *)(netNameP.c_str()), (const char *)(netNameN.c_str()));
|
||||
|
||||
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;
|
||||
|
||||
|
||||
m_currentNode->AllItemsInNet( refNet, items );
|
||||
double bestDist = std::numeric_limits<double>::max();
|
||||
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 );
|
||||
if(!anchor)
|
||||
OPT_VECTOR2I anchor = getDanglingAnchor( m_currentNode, item );
|
||||
if( !anchor )
|
||||
continue;
|
||||
|
||||
double dist = (*anchor - *refAnchor).EuclideanNorm();
|
||||
|
||||
if (dist < bestDist)
|
||||
double dist = ( *anchor - *refAnchor ).EuclideanNorm();
|
||||
|
||||
if( dist < bestDist )
|
||||
{
|
||||
found = true;
|
||||
bestDist = dist;
|
||||
|
||||
if (refNet == netP)
|
||||
|
||||
if( refNet == netP )
|
||||
{
|
||||
aPair = PNS_DP_PRIMITIVE_PAIR ( item, primRef );
|
||||
aPair.SetAnchors ( *anchor, *refAnchor );
|
||||
} else {
|
||||
aPair = PNS_DP_PRIMITIVE_PAIR ( primRef, item );
|
||||
aPair.SetAnchors ( *refAnchor, *anchor );
|
||||
aPair.SetAnchors( *anchor, *refAnchor );
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
int PNS_DIFF_PAIR_PLACER::gap() const
|
||||
{
|
||||
return m_sizes.DiffPairGap() + m_sizes.DiffPairWidth();
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
VECTOR2I p( aP );
|
||||
|
@ -542,7 +564,7 @@ bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
if( Router()->SnappingEnabled() )
|
||||
p = Router()->SnapToItem( aStartItem, aP, split );
|
||||
|
||||
if(!aStartItem)
|
||||
if( !aStartItem )
|
||||
{
|
||||
Router()->SetFailureReason( _( "Can't start a differential pair "
|
||||
" 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();
|
||||
|
||||
if (!findDpPrimitivePair(aP, aStartItem, m_start ) )
|
||||
if( !findDpPrimitivePair( aP, aStartItem, m_start ) )
|
||||
{
|
||||
Router()->SetFailureReason( _( "Unable to find complementary differential pair "
|
||||
"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;
|
||||
}
|
||||
|
||||
|
||||
void PNS_DIFF_PAIR_PLACER::initPlacement( bool aSplitSeg )
|
||||
{
|
||||
m_idle = false;
|
||||
|
@ -598,7 +621,7 @@ void PNS_DIFF_PAIR_PLACER::initPlacement( bool aSplitSeg )
|
|||
delete m_shove;
|
||||
|
||||
m_shove = NULL;
|
||||
|
||||
|
||||
if( m_currentMode == RM_Shove || m_currentMode == RM_Smart )
|
||||
{
|
||||
m_shove = new PNS_SHOVE( m_currentNode, Router() );
|
||||
|
@ -609,57 +632,56 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
|
|||
{
|
||||
m_fitOk = false;
|
||||
|
||||
PNS_DP_GATEWAYS gwsEntry ( gap() );
|
||||
PNS_DP_GATEWAYS gwsTarget ( gap() );
|
||||
PNS_DP_GATEWAYS gwsEntry( gap() );
|
||||
PNS_DP_GATEWAYS gwsTarget( gap() );
|
||||
|
||||
|
||||
if(!m_prevPair)
|
||||
if( !m_prevPair )
|
||||
m_prevPair = m_start;
|
||||
|
||||
gwsEntry.BuildFromPrimitivePair ( *m_prevPair, m_startDiagonal );
|
||||
gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );
|
||||
|
||||
PNS_DP_PRIMITIVE_PAIR target;
|
||||
|
||||
if (findDpPrimitivePair ( aP, m_currentEndItem, target ))
|
||||
|
||||
if( findDpPrimitivePair ( aP, m_currentEndItem, target ) )
|
||||
{
|
||||
gwsTarget.BuildFromPrimitivePair( target, m_startDiagonal );
|
||||
m_snapOnTarget = true;
|
||||
} else {
|
||||
VECTOR2I fp;
|
||||
|
||||
if( !propagateDpHeadForces ( aP, fp ) )
|
||||
if( !propagateDpHeadForces( aP, fp ) )
|
||||
return false;
|
||||
|
||||
gwsTarget.SetFitVias ( m_placingVia, m_sizes.ViaDiameter(), viaGap() );
|
||||
gwsTarget.BuildForCursor ( fp );
|
||||
gwsTarget.BuildOrthoProjections ( gwsEntry, fp, m_orthoMode ? 200 : -200 );
|
||||
gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() );
|
||||
gwsTarget.BuildForCursor( fp );
|
||||
gwsTarget.BuildOrthoProjections( gwsEntry, fp, m_orthoMode ? 200 : -200 );
|
||||
m_snapOnTarget = false;
|
||||
}
|
||||
|
||||
m_currentTrace = PNS_DIFF_PAIR();
|
||||
m_currentTrace.SetGap ( gap() );
|
||||
m_currentTrace.SetGap( gap() );
|
||||
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.SetWidth ( m_sizes.DiffPairWidth() );
|
||||
m_currentTrace.SetGap ( m_sizes.DiffPairGap() );
|
||||
|
||||
if(m_placingVia)
|
||||
m_currentTrace.SetNets( m_netP, m_netN );
|
||||
m_currentTrace.SetWidth( m_sizes.DiffPairWidth() );
|
||||
m_currentTrace.SetGap( m_sizes.DiffPairGap() );
|
||||
|
||||
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 ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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_fitOk = false;
|
||||
|
@ -667,13 +689,13 @@ bool PNS_DIFF_PAIR_PLACER::Move(const VECTOR2I& aP , PNS_ITEM* aEndItem )
|
|||
delete m_lastNode;
|
||||
m_lastNode = NULL;
|
||||
|
||||
if ( !route( aP ) )
|
||||
if( !route( aP ) )
|
||||
return false;
|
||||
|
||||
PNS_NODE* latestNode = m_currentNode;
|
||||
m_lastNode = latestNode->Branch();
|
||||
|
||||
assert (m_lastNode != NULL);
|
||||
assert( m_lastNode != NULL );
|
||||
m_currentEnd = aP;
|
||||
|
||||
updateLeadingRatLine();
|
||||
|
@ -681,42 +703,45 @@ bool PNS_DIFF_PAIR_PLACER::Move(const VECTOR2I& aP , PNS_ITEM* aEndItem )
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PNS_DIFF_PAIR_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
|
||||
{
|
||||
m_sizes = aSizes;
|
||||
|
||||
if( !m_idle )
|
||||
{
|
||||
initPlacement ( );
|
||||
Move ( m_currentEnd, NULL );
|
||||
initPlacement();
|
||||
Move( m_currentEnd, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||
{
|
||||
if (!m_fitOk)
|
||||
if( !m_fitOk )
|
||||
return false;
|
||||
|
||||
if (m_currentTrace.CP().SegmentCount() < 1 ||
|
||||
m_currentTrace.CN().SegmentCount() < 1 )
|
||||
if( m_currentTrace.CP().SegmentCount() < 1 ||
|
||||
m_currentTrace.CN().SegmentCount() < 1 )
|
||||
return false;
|
||||
|
||||
if( m_currentTrace.CP().SegmentCount() > 1)
|
||||
m_initialDiagonal = !DIRECTION_45( m_currentTrace.CP().CSegment(-2) ).IsDiagonal();
|
||||
|
||||
PNS_TOPOLOGY topo ( m_lastNode );
|
||||
|
||||
if( !m_snapOnTarget && !m_currentTrace.EndsWithVias() )
|
||||
if( m_currentTrace.CP().SegmentCount() > 1 )
|
||||
m_initialDiagonal = !DIRECTION_45( m_currentTrace.CP().CSegment( -2 ) ).IsDiagonal();
|
||||
|
||||
PNS_TOPOLOGY topo( m_lastNode );
|
||||
|
||||
if( !m_snapOnTarget && !m_currentTrace.EndsWithVias() )
|
||||
{
|
||||
SHAPE_LINE_CHAIN newP ( m_currentTrace.CP() );
|
||||
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);
|
||||
newN.Remove(-1, -1);
|
||||
newP.Remove( -1, -1 );
|
||||
newN.Remove( -1, -1 );
|
||||
}
|
||||
|
||||
m_currentTrace.SetShape ( newP, newN );
|
||||
m_currentTrace.SetShape( newP, newN );
|
||||
}
|
||||
|
||||
if( m_currentTrace.EndsWithVias() )
|
||||
|
@ -727,11 +752,11 @@ bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
} else
|
||||
m_chainedPlacement = !m_snapOnTarget;
|
||||
|
||||
PNS_LINE lineP ( m_currentTrace.PLine() );
|
||||
PNS_LINE lineN ( m_currentTrace.NLine() );
|
||||
|
||||
m_lastNode->Add ( &lineP );
|
||||
m_lastNode->Add ( &lineN );
|
||||
PNS_LINE lineP( m_currentTrace.PLine() );
|
||||
PNS_LINE lineN( m_currentTrace.NLine() );
|
||||
|
||||
m_lastNode->Add( &lineP );
|
||||
m_lastNode->Add( &lineN );
|
||||
|
||||
topo.SimplifyLine( &lineP );
|
||||
topo.SimplifyLine( &lineN );
|
||||
|
@ -742,12 +767,14 @@ bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
|
||||
m_lastNode = NULL;
|
||||
m_placingVia = false;
|
||||
|
||||
if(m_snapOnTarget)
|
||||
|
||||
if( m_snapOnTarget )
|
||||
{
|
||||
m_idle = true;
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
initPlacement();
|
||||
return false;
|
||||
}
|
||||
|
@ -760,19 +787,19 @@ void PNS_DIFF_PAIR_PLACER::GetModifiedNets( std::vector<int> &aNets ) const
|
|||
aNets.push_back( m_netN );
|
||||
}
|
||||
|
||||
|
||||
void PNS_DIFF_PAIR_PLACER::updateLeadingRatLine()
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
if( topo.LeadingRatLine ( &m_currentTrace.NLine(), ratLineN ))
|
||||
if( topo.LeadingRatLine ( &m_currentTrace.NLine(), ratLineN ) )
|
||||
{
|
||||
Router()->DisplayDebugLine( ratLineN, 3, 10000 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,11 +161,11 @@ public:
|
|||
|
||||
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:
|
||||
|
||||
int viaGap() const;
|
||||
int gap() const;
|
||||
|
||||
|
@ -212,10 +212,10 @@ private:
|
|||
*/
|
||||
void setInitialDirection( const DIRECTION_45& aDirection );
|
||||
|
||||
|
||||
|
||||
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
|
||||
bool rhWalkOnly( const VECTOR2I& aP );
|
||||
|
||||
|
@ -227,10 +227,10 @@ private:
|
|||
|
||||
const PNS_VIA makeVia ( const VECTOR2I& aP, int aNet );
|
||||
|
||||
bool findDpPrimitivePair ( const VECTOR2I& aP, PNS_ITEM *aItem, PNS_DP_PRIMITIVE_PAIR& aPair );
|
||||
OPT_VECTOR2I getDanglingAnchor ( PNS_NODE *aNode, PNS_ITEM *aItem );
|
||||
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 findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair );
|
||||
OPT_VECTOR2I getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem );
|
||||
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 propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP );
|
||||
|
||||
enum State {
|
||||
|
@ -247,11 +247,10 @@ private:
|
|||
bool m_fitOk;
|
||||
|
||||
int m_netP, m_netN;
|
||||
|
||||
|
||||
PNS_DP_PRIMITIVE_PAIR m_start;
|
||||
boost::optional<PNS_DP_PRIMITIVE_PAIR> m_prevPair;
|
||||
|
||||
|
||||
///> current algorithm iteration
|
||||
int m_iteration;
|
||||
|
||||
|
@ -294,9 +293,9 @@ private:
|
|||
VECTOR2I m_currentEnd, m_currentStart;
|
||||
PNS_DIFF_PAIR m_currentTrace;
|
||||
|
||||
PNS_ITEM *m_currentEndItem;
|
||||
PNS_ITEM* m_currentEndItem;
|
||||
PNS_MODE m_currentMode;
|
||||
|
||||
|
||||
bool m_idle;
|
||||
};
|
||||
|
||||
|
|
|
@ -34,13 +34,10 @@
|
|||
#include "pns_router.h"
|
||||
#include "pns_utils.h"
|
||||
|
||||
|
||||
using boost::optional;
|
||||
|
||||
|
||||
|
||||
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_currentNode = NULL;
|
||||
|
@ -49,42 +46,46 @@ PNS_DP_MEANDER_PLACER::PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
|
|||
|
||||
PNS_DP_MEANDER_PLACER::~PNS_DP_MEANDER_PLACER()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
const PNS_LINE PNS_DP_MEANDER_PLACER::Trace() const
|
||||
{
|
||||
return m_currentTraceP;
|
||||
}
|
||||
|
||||
|
||||
PNS_NODE* PNS_DP_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
|
||||
{
|
||||
if(!m_currentNode)
|
||||
if( !m_currentNode )
|
||||
return m_world;
|
||||
|
||||
return m_currentNode;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DP_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
m_initialSegment = static_cast<PNS_SEGMENT *>(aStartItem);
|
||||
m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
|
||||
|
||||
p = m_initialSegment->Seg().NearestPoint( aP );
|
||||
|
||||
m_currentNode=NULL;
|
||||
m_currentStart = p;
|
||||
m_currentStart = p;
|
||||
|
||||
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 "
|
||||
"net for length tuning. Make sure the names of the nets belonging "
|
||||
|
@ -92,21 +93,20 @@ bool PNS_DP_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_originPair.SetGap ( Router()->Sizes().DiffPairGap() );
|
||||
m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
|
||||
|
||||
if( !m_originPair.PLine().SegmentCount() ||
|
||||
!m_originPair.NLine().SegmentCount() )
|
||||
return false;
|
||||
|
||||
m_tunedPathP = topo.AssembleTrivialPath ( m_originPair.PLine().GetLink(0) );
|
||||
m_tunedPathN = topo.AssembleTrivialPath ( m_originPair.NLine().GetLink(0) );
|
||||
|
||||
m_world->Remove ( m_originPair.PLine() );
|
||||
m_world->Remove ( m_originPair.NLine() );
|
||||
m_tunedPathP = topo.AssembleTrivialPath( m_originPair.PLine().GetLink( 0 ) );
|
||||
m_tunedPathN = topo.AssembleTrivialPath( m_originPair.NLine().GetLink( 0 ) );
|
||||
|
||||
m_world->Remove( m_originPair.PLine() );
|
||||
m_world->Remove( m_originPair.NLine() );
|
||||
|
||||
m_currentWidth = m_originPair.Width();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -123,40 +123,42 @@ void PNS_DP_MEANDER_PLACER::release()
|
|||
#endif
|
||||
}
|
||||
|
||||
int PNS_DP_MEANDER_PLACER::origPathLength () const
|
||||
|
||||
int PNS_DP_MEANDER_PLACER::origPathLength() const
|
||||
{
|
||||
int totalP = 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) )
|
||||
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( );
|
||||
|
||||
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||
totalP += 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 b( ( aCoupledSegs.coupledP.B + aCoupledSegs.coupledN.B ) / 2 );
|
||||
|
||||
return SEG (a, b);
|
||||
return SEG( a, b );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
PNS_MEANDER_PLACER_BASE::TUNING_STATUS PNS_DP_MEANDER_PLACER::tuneLineLength ( PNS_MEANDERED_LINE& aTuned, int aElongation )
|
||||
{
|
||||
int remaining = aElongation;
|
||||
int remaining = aElongation;
|
||||
bool finished = false;
|
||||
|
||||
BOOST_FOREACH(PNS_MEANDER_SHAPE *m, aTuned.Meanders())
|
||||
|
@ -181,7 +183,7 @@ PNS_MEANDER_PLACER_BASE::TUNING_STATUS PNS_DP_MEANDER_PLACER::tuneLineLength ( P
|
|||
|
||||
m->SetType ( newType );
|
||||
m->Recalculate( );
|
||||
|
||||
|
||||
finished = true;
|
||||
} else {
|
||||
m->MakeEmpty();
|
||||
|
@ -210,7 +212,7 @@ PNS_MEANDER_PLACER_BASE::TUNING_STATUS PNS_DP_MEANDER_PLACER::tuneLineLength ( P
|
|||
|
||||
if( meanderCount )
|
||||
balance = -remaining / meanderCount;
|
||||
|
||||
|
||||
if (balance >= 0)
|
||||
{
|
||||
BOOST_FOREACH(PNS_MEANDER_SHAPE *m, aTuned.Meanders())
|
||||
|
@ -221,50 +223,47 @@ PNS_MEANDER_PLACER_BASE::TUNING_STATUS PNS_DP_MEANDER_PLACER::tuneLineLength ( P
|
|||
m->Resize ( std::max( m->Amplitude() - balance / 2, m_settings.m_minAmplitude ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return TUNED;
|
||||
}
|
||||
#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;
|
||||
|
||||
//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 )
|
||||
{
|
||||
|
||||
|
||||
|
||||
// return false;
|
||||
|
||||
if(m_currentNode)
|
||||
if( m_currentNode )
|
||||
delete m_currentNode;
|
||||
|
||||
m_currentNode = m_world->Branch();
|
||||
|
||||
|
||||
SHAPE_LINE_CHAIN preP, tunedP, postP;
|
||||
SHAPE_LINE_CHAIN preN, tunedN, postN;
|
||||
|
||||
cutTunedLine ( m_originPair.CP(), m_currentStart, aP, preP, tunedP, postP );
|
||||
cutTunedLine ( m_originPair.CN(), m_currentStart, aP, preN, tunedN, postN );
|
||||
|
||||
cutTunedLine( m_originPair.CP(), m_currentStart, aP, preP, tunedP, postP );
|
||||
cutTunedLine( m_originPair.CN(), m_currentStart, aP, preN, tunedN, postN );
|
||||
|
||||
PNS_DIFF_PAIR tuned ( m_originPair );
|
||||
|
||||
tuned.SetShape ( tunedP, tunedN );
|
||||
tuned.SetShape( tunedP, tunedN );
|
||||
|
||||
m_coupledSegments.clear();
|
||||
|
||||
tuned.CoupledSegmentPairs ( m_coupledSegments );
|
||||
tuned.CoupledSegmentPairs( m_coupledSegments );
|
||||
|
||||
if (m_coupledSegments.size() == 0)
|
||||
if( m_coupledSegments.size() == 0 )
|
||||
return false;
|
||||
|
||||
//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.CN(), 4, 20000 );
|
||||
|
||||
m_result = PNS_MEANDERED_LINE (this, true );
|
||||
m_result.SetWidth ( tuned.Width() );
|
||||
|
||||
int offset = ( tuned.Gap() + tuned.Width() ) / 2;
|
||||
m_result = PNS_MEANDERED_LINE( this, true );
|
||||
m_result.SetWidth( tuned.Width() );
|
||||
|
||||
if ( !pairOrientation ( m_coupledSegments[0] ) )
|
||||
int offset = ( tuned.Gap() + tuned.Width() ) / 2;
|
||||
|
||||
if( !pairOrientation( m_coupledSegments[0] ) )
|
||||
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) )
|
||||
Router()->DisplayDebugLine ( l->CLine(), 5, 10000 );
|
||||
|
||||
}
|
||||
|
||||
BOOST_FOREACH ( const PNS_ITEM *item, m_tunedPathN.CItems() )
|
||||
{
|
||||
if ( const PNS_LINE *l = dyn_cast<const PNS_LINE *> (item) )
|
||||
Router()->DisplayDebugLine ( l->CLine(), 5, 10000 );
|
||||
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||
Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
|
||||
}
|
||||
|
||||
|
||||
BOOST_FOREACH ( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& sp, m_coupledSegments )
|
||||
BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
|
||||
{
|
||||
SEG base = baselineSegment ( sp );
|
||||
|
||||
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||
Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
|
||||
}
|
||||
|
||||
BOOST_FOREACH( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& sp, m_coupledSegments )
|
||||
{
|
||||
SEG base = baselineSegment( sp );
|
||||
|
||||
// DrawDebugSeg ( base, 3 );
|
||||
|
||||
m_result.AddCorner ( sp.parentP.A, sp.parentN.A );
|
||||
m_result.MeanderSegment ( base );
|
||||
m_result.AddCorner ( sp.parentP.B, sp.parentN.B );
|
||||
|
||||
m_result.AddCorner( sp.parentP.A, sp.parentN.A );
|
||||
m_result.MeanderSegment( base );
|
||||
m_result.AddCorner( sp.parentP.B, sp.parentN.B );
|
||||
}
|
||||
|
||||
int dpLen = origPathLength();
|
||||
|
||||
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_lastLength = dpLen;
|
||||
} else {
|
||||
|
||||
m_lastLength = dpLen - std::max ( tunedP.Length(), tunedN.Length() );
|
||||
tuneLineLength(m_result, m_settings.m_targetLength - dpLen );
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
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 )
|
||||
{
|
||||
tunedP.Append ( m->CLine(0) );
|
||||
tunedN.Append ( m->CLine(1) );
|
||||
}
|
||||
tunedP.Append ( m->CLine( 0 ) );
|
||||
tunedN.Append ( m->CLine( 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
m_lastLength += std::max ( tunedP.Length(), tunedN.Length() );
|
||||
|
||||
int comp = compareWithTollerance( m_lastLength - m_settings.m_targetLength, 0, m_settings.m_lengthTollerance );
|
||||
m_lastLength += std::max( tunedP.Length(), tunedN.Length() );
|
||||
|
||||
int comp = compareWithTolerance( m_lastLength - m_settings.m_targetLength, 0, m_settings.m_lengthTolerance );
|
||||
|
||||
if( comp > 0 )
|
||||
m_lastStatus = TOO_LONG;
|
||||
|
@ -348,16 +344,15 @@ bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
m_lastStatus = TOO_SHORT;
|
||||
else
|
||||
m_lastStatus = TUNED;
|
||||
|
||||
}
|
||||
|
||||
m_finalShapeP.Clear( );
|
||||
m_finalShapeP.Clear();
|
||||
m_finalShapeP.Append( preP );
|
||||
m_finalShapeP.Append( tunedP );
|
||||
m_finalShapeP.Append( postP );
|
||||
m_finalShapeP.Simplify();
|
||||
|
||||
m_finalShapeN.Clear( );
|
||||
|
||||
m_finalShapeN.Clear();
|
||||
m_finalShapeN.Append( preN );
|
||||
m_finalShapeN.Append( tunedN );
|
||||
m_finalShapeN.Append( postN );
|
||||
|
@ -369,22 +364,23 @@ bool PNS_DP_MEANDER_PLACER::Move( 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 lN ( m_originPair.NLine(), m_finalShapeN );
|
||||
|
||||
m_currentNode->Add ( &lP );
|
||||
m_currentNode->Add ( &lN );
|
||||
PNS_LINE lP( m_originPair.PLine(), m_finalShapeP );
|
||||
PNS_LINE lN( m_originPair.NLine(), m_finalShapeN );
|
||||
|
||||
m_currentNode->Add( &lP );
|
||||
m_currentNode->Add( &lN );
|
||||
|
||||
Router()->CommitRouting( m_currentNode );
|
||||
|
||||
|
||||
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 l2 ( m_originPair.NLine(), aShape->CLine(1) );
|
||||
|
||||
PNS_LINE l1( m_originPair.PLine(), aShape->CLine( 0 ) );
|
||||
PNS_LINE l2( m_originPair.NLine(), aShape->CLine( 1 ) );
|
||||
|
||||
if( m_currentNode->CheckColliding( &l1 ) )
|
||||
return false;
|
||||
|
||||
|
@ -397,62 +393,66 @@ bool PNS_DP_MEANDER_PLACER::CheckFit ( PNS_MEANDER_SHAPE *aShape )
|
|||
return m_result.CheckSelfIntersections( aShape, clearance );
|
||||
}
|
||||
|
||||
|
||||
|
||||
const PNS_ITEMSET PNS_DP_MEANDER_PLACER::Traces()
|
||||
{
|
||||
|
||||
m_currentTraceP = PNS_LINE ( m_originPair.PLine(), m_finalShapeP );
|
||||
m_currentTraceN = PNS_LINE ( m_originPair.NLine(), m_finalShapeN );
|
||||
m_currentTraceP = PNS_LINE( m_originPair.PLine(), m_finalShapeP );
|
||||
m_currentTraceN = PNS_LINE( m_originPair.NLine(), m_finalShapeN );
|
||||
|
||||
PNS_ITEMSET traces;
|
||||
|
||||
traces.Add (&m_currentTraceP);
|
||||
traces.Add (&m_currentTraceN);
|
||||
|
||||
|
||||
traces.Add( &m_currentTraceP );
|
||||
traces.Add( &m_currentTraceN );
|
||||
|
||||
return traces;
|
||||
}
|
||||
|
||||
|
||||
const VECTOR2I& PNS_DP_MEANDER_PLACER::CurrentEnd() const
|
||||
{
|
||||
return m_currentEnd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int PNS_DP_MEANDER_PLACER::CurrentNet() const
|
||||
{
|
||||
return m_initialSegment->Net();
|
||||
}
|
||||
|
||||
|
||||
int PNS_DP_MEANDER_PLACER::CurrentLayer() const
|
||||
{
|
||||
return m_initialSegment->Layers().Start();
|
||||
}
|
||||
|
||||
|
||||
const wxString PNS_DP_MEANDER_PLACER::TuningInfo() const
|
||||
{
|
||||
wxString status;
|
||||
|
||||
switch (m_lastStatus)
|
||||
switch( m_lastStatus )
|
||||
{
|
||||
case TOO_LONG:
|
||||
status = _("Too long: ");
|
||||
status = _( "Too long: " );
|
||||
break;
|
||||
case TOO_SHORT:
|
||||
status = _("Too short: ");
|
||||
status = _("Too short: " );
|
||||
break;
|
||||
case TUNED:
|
||||
status = _("Tuned: ");
|
||||
status = _( "Tuned: " );
|
||||
break;
|
||||
default:
|
||||
return _("?");
|
||||
return _( "?" );
|
||||
}
|
||||
|
||||
status += LengthDoubleToString( (double) m_lastLength, false );
|
||||
status += "/";
|
||||
status += LengthDoubleToString( (double) m_settings.m_targetLength, false );
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
PNS_DP_MEANDER_PLACER::TUNING_STATUS PNS_DP_MEANDER_PLACER::TuningStatus() const
|
||||
{
|
||||
return m_lastStatus;
|
||||
|
|
|
@ -48,13 +48,12 @@ class PNS_ROUTER_BASE;
|
|||
class PNS_DP_MEANDER_PLACER : public PNS_MEANDER_PLACER_BASE
|
||||
{
|
||||
public:
|
||||
|
||||
PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter );
|
||||
~PNS_DP_MEANDER_PLACER();
|
||||
|
||||
/**
|
||||
* Function Start()
|
||||
*
|
||||
*
|
||||
* Starts routing a single track at point aP, taking item aStartItem as anchor
|
||||
* (unless NULL).
|
||||
*/
|
||||
|
@ -62,8 +61,8 @@ public:
|
|||
|
||||
/**
|
||||
* Function Move()
|
||||
*
|
||||
* Moves the end of the currently routed trace to the point aP, taking
|
||||
*
|
||||
* Moves the end of the currently routed trace to the point aP, taking
|
||||
* aEndItem as anchor (if not NULL).
|
||||
* (unless NULL).
|
||||
*/
|
||||
|
@ -71,7 +70,7 @@ public:
|
|||
|
||||
/**
|
||||
* Function FixRoute()
|
||||
*
|
||||
*
|
||||
* Commits the currently routed track to the parent node, taking
|
||||
* aP as the final end point and aEndItem as the final anchor (if provided).
|
||||
* @return true, if route has been commited. May return false if the routing
|
||||
|
@ -79,7 +78,7 @@ public:
|
|||
* if Settings.CanViolateDRC() is on.
|
||||
*/
|
||||
bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem );
|
||||
|
||||
|
||||
const PNS_LINE Trace() const;
|
||||
|
||||
/**
|
||||
|
@ -88,39 +87,36 @@ public:
|
|||
* Returns the most recent world state.
|
||||
*/
|
||||
PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
|
||||
|
||||
|
||||
const PNS_ITEMSET Traces();
|
||||
|
||||
const VECTOR2I& CurrentEnd() const;
|
||||
|
||||
|
||||
int CurrentNet() const;
|
||||
int CurrentLayer() const;
|
||||
|
||||
|
||||
int totalLength();
|
||||
|
||||
const wxString TuningInfo() const;
|
||||
TUNING_STATUS TuningStatus() const;
|
||||
|
||||
bool CheckFit ( PNS_MEANDER_SHAPE* aShape );
|
||||
bool CheckFit( PNS_MEANDER_SHAPE* aShape );
|
||||
|
||||
|
||||
|
||||
private:
|
||||
friend class PNS_MEANDER_SHAPE;
|
||||
|
||||
|
||||
void meanderSegment ( const SEG& aBase );
|
||||
|
||||
|
||||
|
||||
// void addMeander ( PNS_MEANDER *aM );
|
||||
// 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();
|
||||
|
||||
int origPathLength () const;
|
||||
int origPathLength() const;
|
||||
|
||||
///> pointer to world to search colliding items
|
||||
PNS_NODE* m_world;
|
||||
|
@ -139,7 +135,7 @@ private:
|
|||
|
||||
SHAPE_LINE_CHAIN m_finalShapeP, m_finalShapeN;
|
||||
PNS_MEANDERED_LINE m_result;
|
||||
PNS_SEGMENT *m_initialSegment;
|
||||
PNS_SEGMENT* m_initialSegment;
|
||||
|
||||
int m_lastLength;
|
||||
TUNING_STATUS m_lastStatus;
|
||||
|
|
|
@ -42,7 +42,7 @@ class PNS_ROUTER_BASE;
|
|||
class PNS_DRAGGER : public PNS_ALGO_BASE
|
||||
{
|
||||
public:
|
||||
PNS_DRAGGER( PNS_ROUTER* aRouter );
|
||||
PNS_DRAGGER( PNS_ROUTER* aRouter );
|
||||
~PNS_DRAGGER();
|
||||
|
||||
/**
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
/**
|
||||
* Function Start()
|
||||
*
|
||||
*
|
||||
* Starts routing a single track at point aP, taking item aStartItem as anchor
|
||||
* (unless NULL). Returns true if a dragging operation has started.
|
||||
*/
|
||||
|
@ -67,24 +67,24 @@ public:
|
|||
* @return true, if dragging finished with success.
|
||||
*/
|
||||
bool Drag( const VECTOR2I& aP );
|
||||
|
||||
|
||||
/**
|
||||
* Function FixRoute()
|
||||
*
|
||||
* Checks if the result of current dragging operation is correct
|
||||
* Checks if the result of current dragging operation is correct
|
||||
* and eventually commits it to the world.
|
||||
* @return true, if dragging finished with success.
|
||||
*/
|
||||
bool FixRoute();
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Function CurrentNode()
|
||||
*
|
||||
* Returns the most recent world state, including all
|
||||
* items changed due to dragging operation.
|
||||
*/
|
||||
PNS_NODE* CurrentNode() const;
|
||||
|
||||
|
||||
/**
|
||||
* Function Traces()
|
||||
*
|
||||
|
@ -94,30 +94,30 @@ public:
|
|||
|
||||
/// @copydoc PNS_ALGO_BASE::Logger()
|
||||
virtual PNS_LOGGER* Logger();
|
||||
|
||||
|
||||
private:
|
||||
typedef std::pair<PNS_LINE *, PNS_LINE *> LinePair;
|
||||
typedef std::pair<PNS_LINE*, PNS_LINE*> LinePair;
|
||||
typedef std::vector<LinePair> LinePairVec;
|
||||
|
||||
enum DragMode {
|
||||
CORNER = 0,
|
||||
SEGMENT,
|
||||
VIA
|
||||
};
|
||||
enum DragMode {
|
||||
CORNER = 0,
|
||||
SEGMENT,
|
||||
VIA
|
||||
};
|
||||
|
||||
bool dragMarkObstacles( const VECTOR2I& aP );
|
||||
bool dragShove(const VECTOR2I& aP );
|
||||
bool startDragSegment( const VECTOR2D& aP, PNS_SEGMENT* aSeg );
|
||||
bool startDragVia( const VECTOR2D& aP, PNS_VIA* aVia );
|
||||
void dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP );
|
||||
bool startDragSegment( const VECTOR2D& aP, PNS_SEGMENT* aSeg );
|
||||
bool startDragVia( const VECTOR2D& aP, PNS_VIA* aVia );
|
||||
void dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP );
|
||||
|
||||
PNS_NODE* m_world;
|
||||
PNS_NODE* m_lastNode;
|
||||
DragMode m_mode;
|
||||
PNS_LINE* m_draggedLine;
|
||||
PNS_VIA* m_draggedVia;
|
||||
PNS_LINE m_lastValidDraggedLine;
|
||||
PNS_SHOVE* m_shove;
|
||||
PNS_NODE* m_world;
|
||||
PNS_NODE* m_lastNode;
|
||||
DragMode m_mode;
|
||||
PNS_LINE* m_draggedLine;
|
||||
PNS_VIA* m_draggedVia;
|
||||
PNS_LINE m_lastValidDraggedLine;
|
||||
PNS_SHOVE* m_shove;
|
||||
int m_draggedSegmentIndex;
|
||||
bool m_dragStatus;
|
||||
PNS_MODE m_currentMode;
|
||||
|
|
|
@ -160,7 +160,6 @@ PNS_INDEX::PNS_INDEX()
|
|||
memset( m_subIndices, 0, sizeof( m_subIndices ) );
|
||||
}
|
||||
|
||||
|
||||
PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
void PNS_INDEX::Add( PNS_ITEM* 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 )
|
||||
{
|
||||
ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
|
||||
|
@ -230,14 +227,12 @@ void PNS_INDEX::Remove( PNS_ITEM* aItem )
|
|||
m_netMap[net].remove( aItem );
|
||||
}
|
||||
|
||||
|
||||
void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem )
|
||||
{
|
||||
Remove( aOldItem );
|
||||
Add( aNewItem );
|
||||
}
|
||||
|
||||
|
||||
template<class Visitor>
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
template<class Visitor>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
template<class Visitor>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void PNS_INDEX::Clear()
|
||||
{
|
||||
for( int i = 0; i < MaxSubIndices; ++i )
|
||||
|
@ -307,13 +299,11 @@ void PNS_INDEX::Clear()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
PNS_INDEX::~PNS_INDEX()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
PNS_INDEX::NET_ITEMS_LIST* PNS_INDEX::GetItemsForNet( int aNet )
|
||||
{
|
||||
if( m_netMap.find( aNet ) == m_netMap.end() )
|
||||
|
|
|
@ -23,21 +23,23 @@
|
|||
#include "pns_itemset.h"
|
||||
|
||||
PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem ) :
|
||||
m_owner ( false )
|
||||
m_owner( false )
|
||||
{
|
||||
if( aInitialItem )
|
||||
m_items.push_back( aInitialItem );
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
||||
{
|
||||
ITEMS newItems;
|
||||
|
@ -74,6 +76,7 @@ PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask, bool aInvert )
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, bool aInvert )
|
||||
{
|
||||
ITEMS newItems;
|
||||
|
@ -105,6 +108,7 @@ PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET& PNS_ITEMSET::ExcludeItem( const PNS_ITEM* aItem )
|
||||
{
|
||||
ITEMS newItems;
|
||||
|
|
|
@ -41,14 +41,14 @@ public:
|
|||
PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL );
|
||||
|
||||
PNS_ITEMSET( const PNS_ITEMSET& aOther ):
|
||||
m_owner ( false )
|
||||
m_owner( false )
|
||||
{
|
||||
m_items = aOther.m_items;
|
||||
}
|
||||
|
||||
~PNS_ITEMSET();
|
||||
|
||||
void MakeOwner ( )
|
||||
void MakeOwner()
|
||||
{
|
||||
m_owner = true;
|
||||
}
|
||||
|
@ -105,9 +105,9 @@ public:
|
|||
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
|
||||
|
|
|
@ -95,20 +95,20 @@ public:
|
|||
return seg1->Width() == seg2->Width();
|
||||
}
|
||||
|
||||
bool IsNonFanoutVia () const
|
||||
bool IsNonFanoutVia() const
|
||||
{
|
||||
if ( m_linkedItems.Size() != 3 )
|
||||
if( m_linkedItems.Size() != 3 )
|
||||
return false;
|
||||
|
||||
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;
|
||||
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)
|
||||
|
@ -209,15 +209,11 @@ private:
|
|||
PNS_ITEMSET m_linkedItems;
|
||||
};
|
||||
|
||||
|
||||
// hash function & comparison operator for boost::unordered_map<>
|
||||
inline bool operator==( PNS_JOINT::HASH_TAG const& aP1,
|
||||
PNS_JOINT::HASH_TAG const& aP2 )
|
||||
inline bool operator==( PNS_JOINT::HASH_TAG const& aP1, PNS_JOINT::HASH_TAG const& aP2 )
|
||||
{
|
||||
return aP1.pos == aP2.pos && aP1.net == aP2.net;
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t hash_value( PNS_JOINT::HASH_TAG const& aP )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
|
|
@ -140,7 +140,7 @@ PNS_SEGMENT* PNS_SEGMENT::Clone( ) const
|
|||
{
|
||||
PNS_SEGMENT* s = new PNS_SEGMENT;
|
||||
|
||||
s->m_seg = m_seg;
|
||||
s->m_seg = m_seg;
|
||||
s->m_net = m_net;
|
||||
s->m_layers = m_layers;
|
||||
s->m_marker = m_marker;
|
||||
|
@ -348,7 +348,6 @@ SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECT
|
|||
{
|
||||
optional<SHAPE_LINE_CHAIN> picked;
|
||||
int i;
|
||||
|
||||
int d = 2;
|
||||
|
||||
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 )
|
||||
{
|
||||
if(m_line.PointCount() == 0)
|
||||
if( m_line.PointCount() == 0 )
|
||||
return;
|
||||
|
||||
if( aVia.Pos() == m_line.CPoint( 0 ) )
|
||||
|
@ -785,44 +784,47 @@ void PNS_LINE::ClearSegmentLinks()
|
|||
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 )
|
||||
aBox.Merge ( aP );
|
||||
else {
|
||||
aBox = BOX2I ( aP, VECTOR2I (0, 0 ) );
|
||||
aBox = BOX2I( aP, VECTOR2I( 0, 0 ) );
|
||||
aDefined = true;
|
||||
}
|
||||
}
|
||||
|
||||
OPT_BOX2I PNS_LINE::ChangedArea ( const PNS_LINE *aOther ) const
|
||||
|
||||
OPT_BOX2I PNS_LINE::ChangedArea( const PNS_LINE* aOther ) const
|
||||
{
|
||||
BOX2I area;
|
||||
bool areaDefined = false;
|
||||
|
||||
|
||||
int i_start = -1;
|
||||
int i_end_self = -1, i_end_other = -1;
|
||||
|
||||
SHAPE_LINE_CHAIN self ( m_line );
|
||||
SHAPE_LINE_CHAIN self( m_line );
|
||||
self.Simplify();
|
||||
SHAPE_LINE_CHAIN other ( aOther->m_line );
|
||||
SHAPE_LINE_CHAIN other( aOther->m_line );
|
||||
other.Simplify();
|
||||
|
||||
int np_self = self.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 p2 = other.CPoint(i);
|
||||
if (p1 != p2)
|
||||
const VECTOR2I p1 = self.CPoint( i );
|
||||
const VECTOR2I p2 = other.CPoint( i );
|
||||
|
||||
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 ) )
|
||||
{
|
||||
i_start = i;
|
||||
|
@ -832,16 +834,15 @@ OPT_BOX2I PNS_LINE::ChangedArea ( const PNS_LINE *aOther ) const
|
|||
i_start = i;
|
||||
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 p2 = other.CPoint( np_other - 1 - i );
|
||||
if (p1 != p2)
|
||||
|
||||
if( p1 != p2 )
|
||||
{
|
||||
i_end_self = np_self - 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 )
|
||||
i_end_other = np_other - 1;
|
||||
|
||||
for (int i = i_start; i <= i_end_self; i++ )
|
||||
extendBox ( area, areaDefined, self.CPoint(i) );
|
||||
for( int i = i_start; i <= i_end_self; i++ )
|
||||
extendBox( area, areaDefined, self.CPoint( i ) );
|
||||
|
||||
for (int i = i_start; i <= i_end_other; i++ )
|
||||
extendBox ( area, areaDefined, other.CPoint(i) );
|
||||
for( int i = i_start; i <= i_end_other; i++ )
|
||||
extendBox( area, areaDefined, other.CPoint( i ) );
|
||||
|
||||
if( areaDefined )
|
||||
{
|
||||
area.Inflate ( std::max( Width(), aOther->Width() ) );
|
||||
area.Inflate( std::max( Width(), aOther->Width() ) );
|
||||
return area;
|
||||
}
|
||||
|
||||
return OPT_BOX2I ( );
|
||||
return OPT_BOX2I();
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
}
|
||||
|
||||
PNS_LINE( const PNS_LINE& aOther ) ;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Copies properties (net, layers, etc.) from a base line and replaces the shape
|
||||
|
@ -88,12 +88,12 @@ public:
|
|||
}
|
||||
|
||||
~PNS_LINE();
|
||||
|
||||
|
||||
static inline bool ClassOf( const PNS_ITEM* aItem )
|
||||
{
|
||||
return aItem && LINE == aItem->Kind();
|
||||
}
|
||||
|
||||
|
||||
/// @copydoc PNS_ITEM::Clone()
|
||||
virtual PNS_LINE* Clone() const;
|
||||
|
||||
|
@ -101,62 +101,62 @@ public:
|
|||
|
||||
///> Assigns a shape to the line (a polyline/line chain)
|
||||
void SetShape( const SHAPE_LINE_CHAIN& aLine )
|
||||
{
|
||||
{
|
||||
m_line = aLine;
|
||||
}
|
||||
|
||||
///> Returns the shape of the line
|
||||
const SHAPE* Shape() const
|
||||
{
|
||||
return &m_line;
|
||||
const SHAPE* Shape() const
|
||||
{
|
||||
return &m_line;
|
||||
}
|
||||
|
||||
///> Modifiable accessor to the underlying shape
|
||||
SHAPE_LINE_CHAIN& Line()
|
||||
{
|
||||
return m_line;
|
||||
SHAPE_LINE_CHAIN& Line()
|
||||
{
|
||||
return m_line;
|
||||
}
|
||||
|
||||
///> Const accessor to the underlying shape
|
||||
const SHAPE_LINE_CHAIN& CLine() const
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& CLine() const
|
||||
{
|
||||
return m_line;
|
||||
}
|
||||
|
||||
///> Returns the number of segments in the line
|
||||
int SegmentCount() const
|
||||
int SegmentCount() const
|
||||
{
|
||||
return m_line.SegmentCount();
|
||||
return m_line.SegmentCount();
|
||||
}
|
||||
|
||||
///> Returns the number of points in the line
|
||||
int PointCount() const
|
||||
{
|
||||
return m_line.PointCount();
|
||||
int PointCount() const
|
||||
{
|
||||
return m_line.PointCount();
|
||||
}
|
||||
|
||||
///> Returns the aIdx-th point of the line
|
||||
const VECTOR2I& CPoint( int aIdx ) const
|
||||
{
|
||||
const VECTOR2I& CPoint( int aIdx ) const
|
||||
{
|
||||
return m_line.CPoint( aIdx );
|
||||
}
|
||||
|
||||
///> Returns the aIdx-th segment of the line
|
||||
const SEG CSegment( int aIdx ) const
|
||||
{
|
||||
{
|
||||
return m_line.CSegment( aIdx );
|
||||
}
|
||||
|
||||
///> Sets line width
|
||||
void SetWidth( int aWidth )
|
||||
{
|
||||
m_width = aWidth;
|
||||
void SetWidth( int aWidth )
|
||||
{
|
||||
m_width = aWidth;
|
||||
}
|
||||
|
||||
|
||||
///> Returns line width
|
||||
int Width() const
|
||||
{
|
||||
return m_width;
|
||||
int Width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
///> Returns true if the line is geometrically identical as line aOther
|
||||
|
@ -168,7 +168,7 @@ public:
|
|||
|
||||
/* Linking functions */
|
||||
|
||||
///> Adds a reference to a segment registered in a PNS_NODE that is a part of this line.
|
||||
///> Adds a reference to a segment registered in a PNS_NODE that is a part of this line.
|
||||
void LinkSegment( PNS_SEGMENT* aSeg )
|
||||
{
|
||||
if( !m_segmentRefs )
|
||||
|
@ -184,7 +184,7 @@ public:
|
|||
return m_segmentRefs;
|
||||
}
|
||||
|
||||
bool IsLinked () const
|
||||
bool IsLinked() const
|
||||
{
|
||||
return m_segmentRefs != NULL;
|
||||
}
|
||||
|
@ -199,14 +199,14 @@ public:
|
|||
aSeg ) != m_segmentRefs->end();
|
||||
}
|
||||
|
||||
PNS_SEGMENT* GetLink ( int aIndex ) const
|
||||
PNS_SEGMENT* GetLink( int aIndex ) const
|
||||
{
|
||||
return (*m_segmentRefs) [ aIndex ];
|
||||
}
|
||||
|
||||
///> Erases the linking information. Used to detach the line from the owning node.
|
||||
void ClearSegmentLinks();
|
||||
|
||||
|
||||
///> Returns the number of segments that were assembled together to form this line.
|
||||
int LinkCount() const
|
||||
{
|
||||
|
@ -220,9 +220,9 @@ public:
|
|||
///> Returns the clipped line.
|
||||
const PNS_LINE ClipToNearestObstacle( PNS_NODE* aNode ) const;
|
||||
|
||||
///> Clips the line to a given range of vertices.
|
||||
///> Clips the line to a given range of vertices.
|
||||
void ClipVertexRange ( int aStart, int aEnd );
|
||||
|
||||
|
||||
///> Returns the number of corners of angles specified by mask aAngles.
|
||||
int CountCorners( int aAngles );
|
||||
|
||||
|
@ -253,21 +253,21 @@ public:
|
|||
void RemoveVia() { m_hasVia = false; }
|
||||
|
||||
const PNS_VIA& Via() const { return m_via; }
|
||||
|
||||
|
||||
virtual void Mark( int aMarker );
|
||||
virtual void Unmark ();
|
||||
virtual int Marker() const;
|
||||
|
||||
|
||||
void DragSegment( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0 );
|
||||
void DragCorner( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0 );
|
||||
|
||||
void SetRank( int aRank );
|
||||
int Rank() const;
|
||||
|
||||
|
||||
bool HasLoops() const;
|
||||
|
||||
OPT_BOX2I ChangedArea ( const PNS_LINE *aOther ) const;
|
||||
|
||||
OPT_BOX2I ChangedArea( const PNS_LINE* aOther ) const;
|
||||
|
||||
private:
|
||||
VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
|
||||
int aIndex, int aThreshold) const;
|
||||
|
@ -277,7 +277,7 @@ private:
|
|||
|
||||
///> Copies m_segmentRefs from the line aParent.
|
||||
void copyLinks( const PNS_LINE* aParent ) ;
|
||||
|
||||
|
||||
///> List of segments in the owning PNS_NODE (PNS_ITEM::m_owner) that constitute this line, or NULL
|
||||
///> if the line is not a part of any node.
|
||||
SEGMENT_REFS* m_segmentRefs;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
using boost::optional;
|
||||
|
||||
PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) :
|
||||
PNS_PLACEMENT_ALGO ( aRouter )
|
||||
PNS_PLACEMENT_ALGO( aRouter )
|
||||
{
|
||||
m_initial_direction = DIRECTION_45::N;
|
||||
m_world = NULL;
|
||||
|
@ -71,8 +71,8 @@ const PNS_VIA PNS_LINE_PLACER::makeVia ( const VECTOR2I& aP )
|
|||
bool PNS_LINE_PLACER::ToggleVia( bool aEnabled )
|
||||
{
|
||||
m_placingVia = aEnabled;
|
||||
if(!m_idle)
|
||||
Move ( m_currentEnd, NULL );
|
||||
if( !m_idle )
|
||||
Move( m_currentEnd, NULL );
|
||||
|
||||
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 )
|
||||
{
|
||||
SHAPE_LINE_CHAIN line = buildInitialLine ( aP );
|
||||
SHAPE_LINE_CHAIN line = buildInitialLine( aP );
|
||||
PNS_LINE initTrack( m_head, line ), walkFull;
|
||||
int effort = 0;
|
||||
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 )
|
||||
{
|
||||
m_head.SetShape( buildInitialLine ( aP ) );
|
||||
m_head.SetShape( buildInitialLine( aP ) );
|
||||
|
||||
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 )
|
||||
{
|
||||
SHAPE_LINE_CHAIN line = buildInitialLine ( aP );
|
||||
SHAPE_LINE_CHAIN line = buildInitialLine( aP );
|
||||
PNS_LINE initTrack( m_head, line );
|
||||
PNS_LINE walkSolids, l2;
|
||||
|
||||
|
@ -531,9 +531,9 @@ bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
case RM_MarkObstacles:
|
||||
return rhMarkObstacles( aP, aNewHead );
|
||||
case RM_Walkaround:
|
||||
return rhWalkOnly ( aP, aNewHead );
|
||||
return rhWalkOnly( aP, aNewHead );
|
||||
case RM_Shove:
|
||||
return rhShoveOnly ( aP, aNewHead );
|
||||
return rhShoveOnly( aP, aNewHead );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -732,9 +732,12 @@ bool PNS_LINE_PLACER::SetLayer( int aLayer )
|
|||
{
|
||||
m_currentLayer = aLayer;
|
||||
return true;
|
||||
} else if( m_chainedPlacement ) {
|
||||
}
|
||||
else if( m_chainedPlacement )
|
||||
{
|
||||
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_splitSeg = false;
|
||||
initPlacement ( m_splitSeg );
|
||||
|
@ -745,6 +748,7 @@ bool PNS_LINE_PLACER::SetLayer( int aLayer )
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
VECTOR2I p( aP );
|
||||
|
@ -1013,36 +1017,39 @@ void PNS_LINE_PLACER::updateLeadingRatLine()
|
|||
SHAPE_LINE_CHAIN ratLine;
|
||||
PNS_TOPOLOGY topo ( m_lastNode );
|
||||
|
||||
if( topo.LeadingRatLine ( ¤t, ratLine ))
|
||||
if( topo.LeadingRatLine( ¤t, ratLine ) )
|
||||
Router()->DisplayDebugLine( ratLine, 5, 10000 );
|
||||
}
|
||||
|
||||
void PNS_LINE_PLACER::SetOrthoMode ( bool aOrthoMode )
|
||||
|
||||
void PNS_LINE_PLACER::SetOrthoMode( bool 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 )
|
||||
return l;
|
||||
|
||||
if (m_orthoMode)
|
||||
{
|
||||
VECTOR2I newLast = l.CSegment(0).LineProject ( l.CPoint(-1) );
|
||||
|
||||
l.Remove(-1, -1);
|
||||
l.Point(1) = newLast;
|
||||
if( m_orthoMode )
|
||||
{
|
||||
VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
|
||||
|
||||
l.Remove( -1, -1 );
|
||||
l.Point( 1 ) = newLast;
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ class PNS_VIA;
|
|||
class PNS_SIZES_SETTINGS;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class PNS_LINE_PLACER
|
||||
*
|
||||
|
@ -96,7 +95,6 @@ public:
|
|||
*/
|
||||
bool SetLayer( int aLayer );
|
||||
|
||||
|
||||
/**
|
||||
* Function Head()
|
||||
*
|
||||
|
@ -181,11 +179,11 @@ public:
|
|||
*/
|
||||
void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes );
|
||||
|
||||
void SetOrthoMode ( bool aOrthoMode );
|
||||
void SetOrthoMode( bool aOrthoMode );
|
||||
|
||||
bool IsPlacingVia() const { return m_placingVia; }
|
||||
|
||||
void GetModifiedNets( std::vector<int> &aNets ) const;
|
||||
void GetModifiedNets( std::vector<int>& aNets ) const;
|
||||
private:
|
||||
/**
|
||||
* Function route()
|
||||
|
@ -348,8 +346,9 @@ private:
|
|||
bool rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead );
|
||||
|
||||
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
|
||||
DIRECTION_45 m_direction;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
PNS_LOGGER::PNS_LOGGER( )
|
||||
{
|
||||
m_groupOpened = false;
|
||||
m_groupOpened = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,89 +43,89 @@ PNS_LOGGER::~PNS_LOGGER()
|
|||
|
||||
void PNS_LOGGER::Clear()
|
||||
{
|
||||
m_theLog.str( std::string() );
|
||||
m_groupOpened = false;
|
||||
m_theLog.str( std::string() );
|
||||
m_groupOpened = false;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOGGER::NewGroup( const std::string& aName, int aIter )
|
||||
{
|
||||
if( m_groupOpened )
|
||||
m_theLog << "endgroup" << std::endl;
|
||||
if( m_groupOpened )
|
||||
m_theLog << "endgroup" << std::endl;
|
||||
|
||||
m_theLog << "group " << aName << " " << aIter << std::endl;
|
||||
m_groupOpened = true;
|
||||
m_theLog << "group " << aName << " " << aIter << std::endl;
|
||||
m_groupOpened = true;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOGGER::EndGroup()
|
||||
{
|
||||
if( !m_groupOpened )
|
||||
return;
|
||||
if( !m_groupOpened )
|
||||
return;
|
||||
|
||||
m_groupOpened = false;
|
||||
m_theLog << "endgroup" << std::endl;
|
||||
m_groupOpened = false;
|
||||
m_theLog << "endgroup" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOGGER::Log ( const PNS_ITEM* aItem, int aKind, const std::string aName )
|
||||
{
|
||||
m_theLog << "aItem " << aKind << " " << aName << " ";
|
||||
m_theLog << aItem->Net() << " " << aItem->Layers().Start() << " " <<
|
||||
aItem->Layers().End() << " " << aItem->Marker() << " " << aItem->Rank();
|
||||
m_theLog << "aItem " << aKind << " " << aName << " ";
|
||||
m_theLog << aItem->Net() << " " << aItem->Layers().Start() << " " <<
|
||||
aItem->Layers().End() << " " << aItem->Marker() << " " << aItem->Rank();
|
||||
|
||||
switch( aItem->Kind() )
|
||||
{
|
||||
case PNS_ITEM::LINE:
|
||||
{
|
||||
PNS_LINE* l = (PNS_LINE*) aItem;
|
||||
m_theLog << " line ";
|
||||
m_theLog << l->Width() << " " << ( l->EndsWithVia() ? 1 : 0 ) << " ";
|
||||
dumpShape ( l->Shape() );
|
||||
m_theLog << std::endl;
|
||||
break;
|
||||
}
|
||||
switch( aItem->Kind() )
|
||||
{
|
||||
case PNS_ITEM::LINE:
|
||||
{
|
||||
PNS_LINE* l = (PNS_LINE*) aItem;
|
||||
m_theLog << " line ";
|
||||
m_theLog << l->Width() << " " << ( l->EndsWithVia() ? 1 : 0 ) << " ";
|
||||
dumpShape ( l->Shape() );
|
||||
m_theLog << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNS_ITEM::VIA:
|
||||
{
|
||||
m_theLog << " via 0 0 ";
|
||||
dumpShape ( aItem->Shape() );
|
||||
m_theLog << std::endl;
|
||||
break;
|
||||
}
|
||||
case PNS_ITEM::VIA:
|
||||
{
|
||||
m_theLog << " via 0 0 ";
|
||||
dumpShape ( aItem->Shape() );
|
||||
m_theLog << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNS_ITEM::SEGMENT:
|
||||
{
|
||||
PNS_SEGMENT* s =(PNS_SEGMENT*) aItem;
|
||||
m_theLog << " line ";
|
||||
m_theLog << s->Width() << " 0 linechain 2 0 " << s->Seg().A.x << " " <<
|
||||
s->Seg().A.y << " " << s->Seg().B.x << " " <<s->Seg().B.y << std::endl;
|
||||
break;
|
||||
}
|
||||
case PNS_ITEM::SEGMENT:
|
||||
{
|
||||
PNS_SEGMENT* s =(PNS_SEGMENT*) aItem;
|
||||
m_theLog << " line ";
|
||||
m_theLog << s->Width() << " 0 linechain 2 0 " << s->Seg().A.x << " " <<
|
||||
s->Seg().A.y << " " << s->Seg().B.x << " " <<s->Seg().B.y << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNS_ITEM::SOLID:
|
||||
{
|
||||
PNS_SOLID* s = (PNS_SOLID*) aItem;
|
||||
m_theLog << " solid 0 0 ";
|
||||
dumpShape( s->Shape() );
|
||||
m_theLog << std::endl;
|
||||
break;
|
||||
}
|
||||
case PNS_ITEM::SOLID:
|
||||
{
|
||||
PNS_SOLID* s = (PNS_SOLID*) aItem;
|
||||
m_theLog << " solid 0 0 ";
|
||||
dumpShape( s->Shape() );
|
||||
m_theLog << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOGGER::Log( const SHAPE_LINE_CHAIN *aL, int aKind, const std::string aName )
|
||||
{
|
||||
m_theLog << "item " << aKind << " " << aName << " ";
|
||||
m_theLog << 0 << " " << 0 << " " << 0 << " " << 0 << " " << 0;
|
||||
m_theLog << " line ";
|
||||
m_theLog << 0 << " " << 0 << " ";
|
||||
dumpShape( aL );
|
||||
m_theLog << std::endl;
|
||||
m_theLog << "item " << aKind << " " << aName << " ";
|
||||
m_theLog << 0 << " " << 0 << " " << 0 << " " << 0 << " " << 0;
|
||||
m_theLog << " line ";
|
||||
m_theLog << 0 << " " << 0 << " ";
|
||||
dumpShape( aL );
|
||||
m_theLog << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,54 +137,55 @@ void PNS_LOGGER::Log( const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
|||
|
||||
void PNS_LOGGER::dumpShape( const SHAPE* aSh )
|
||||
{
|
||||
switch( aSh->Type() )
|
||||
{
|
||||
case SH_LINE_CHAIN:
|
||||
{
|
||||
const SHAPE_LINE_CHAIN* lc = (const SHAPE_LINE_CHAIN*) aSh;
|
||||
m_theLog << "linechain " << lc->PointCount() << " " << ( lc->IsClosed() ? 1 : 0 ) << " ";
|
||||
switch( aSh->Type() )
|
||||
{
|
||||
case SH_LINE_CHAIN:
|
||||
{
|
||||
const SHAPE_LINE_CHAIN* lc = (const SHAPE_LINE_CHAIN*) aSh;
|
||||
m_theLog << "linechain " << lc->PointCount() << " " << ( lc->IsClosed() ? 1 : 0 ) << " ";
|
||||
|
||||
for( int i = 0; i < lc->PointCount(); i++ )
|
||||
m_theLog << lc->CPoint( i ).x << " " << lc->CPoint( i ).y << " ";
|
||||
for( int i = 0; i < lc->PointCount(); i++ )
|
||||
m_theLog << lc->CPoint( i ).x << " " << lc->CPoint( i ).y << " ";
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_CIRCLE:
|
||||
{
|
||||
const SHAPE_CIRCLE *c = (const SHAPE_CIRCLE*) aSh;
|
||||
m_theLog << "circle " << c->GetCenter().x << " " << c->GetCenter().y << " " << c->GetRadius();
|
||||
break;
|
||||
}
|
||||
case SH_CIRCLE:
|
||||
{
|
||||
const SHAPE_CIRCLE *c = (const SHAPE_CIRCLE*) aSh;
|
||||
m_theLog << "circle " << c->GetCenter().x << " " << c->GetCenter().y << " " << c->GetRadius();
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_RECT:
|
||||
{
|
||||
const SHAPE_RECT* r = (const SHAPE_RECT*) aSh;
|
||||
m_theLog << "rect " << r->GetPosition().x << " " << r->GetPosition().y << " " <<
|
||||
r->GetSize().x << " " <<r->GetSize().y;
|
||||
break;
|
||||
}
|
||||
case SH_RECT:
|
||||
{
|
||||
const SHAPE_RECT* r = (const SHAPE_RECT*) aSh;
|
||||
m_theLog << "rect " << r->GetPosition().x << " " << r->GetPosition().y << " " <<
|
||||
r->GetSize().x << " " <<r->GetSize().y;
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_SEGMENT:
|
||||
{
|
||||
const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) aSh;
|
||||
m_theLog << "linechain 2 0 " << s->GetSeg().A.x << " " << s->GetSeg().A.y << " " <<
|
||||
s->GetSeg().B.x << " " << s->GetSeg().B.y;
|
||||
break;
|
||||
}
|
||||
case SH_SEGMENT:
|
||||
{
|
||||
const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) aSh;
|
||||
m_theLog << "linechain 2 0 " << s->GetSeg().A.x << " " << s->GetSeg().A.y << " " <<
|
||||
s->GetSeg().B.x << " " << s->GetSeg().B.y;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOGGER::Save( const std::string& aFilename )
|
||||
{
|
||||
EndGroup();
|
||||
EndGroup();
|
||||
|
||||
FILE* f = fopen( aFilename.c_str(), "wb" );
|
||||
printf( "Saving to '%s' [%p]\n", aFilename.c_str(), f );
|
||||
const std::string s = m_theLog.str();
|
||||
fwrite( s.c_str(), 1, s.length(), f );
|
||||
fclose( f );
|
||||
FILE* f = fopen( aFilename.c_str(), "wb" );
|
||||
printf( "Saving to '%s' [%p]\n", aFilename.c_str(), f );
|
||||
const std::string s = m_theLog.str();
|
||||
fwrite( s.c_str(), 1, s.length(), f );
|
||||
fclose( f );
|
||||
}
|
||||
|
|
|
@ -35,25 +35,25 @@ class SHAPE;
|
|||
class PNS_LOGGER
|
||||
{
|
||||
public:
|
||||
PNS_LOGGER();
|
||||
~PNS_LOGGER();
|
||||
PNS_LOGGER();
|
||||
~PNS_LOGGER();
|
||||
|
||||
void Save( const std::string& aFilename );
|
||||
void Clear();
|
||||
void Save( const std::string& aFilename );
|
||||
void Clear();
|
||||
|
||||
void NewGroup( const std::string& aName, int aIter = 0 );
|
||||
void EndGroup();
|
||||
void NewGroup( const std::string& aName, int aIter = 0 );
|
||||
void EndGroup();
|
||||
|
||||
void Log( const PNS_ITEM* aItem, int aKind = 0, const std::string aName = std::string() );
|
||||
void Log( const SHAPE_LINE_CHAIN *aL, int aKind = 0, const std::string aName = std::string() );
|
||||
void Log( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aKind = 0,
|
||||
const std::string aName = std::string() );
|
||||
void Log( const PNS_ITEM* aItem, int aKind = 0, const std::string aName = std::string() );
|
||||
void Log( const SHAPE_LINE_CHAIN *aL, int aKind = 0, const std::string aName = std::string() );
|
||||
void Log( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aKind = 0,
|
||||
const std::string aName = std::string() );
|
||||
|
||||
private:
|
||||
void dumpShape ( const SHAPE* aSh );
|
||||
void dumpShape( const SHAPE* aSh );
|
||||
|
||||
bool m_groupOpened;
|
||||
std::stringstream m_theLog;
|
||||
bool m_groupOpened;
|
||||
std::stringstream m_theLog;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,50 +32,49 @@
|
|||
#include "pns_meander_placer_base.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;
|
||||
|
||||
|
||||
bool side = true;
|
||||
VECTOR2D dir( aBase.B - aBase.A );
|
||||
|
||||
if(!m_dual)
|
||||
if( !m_dual )
|
||||
AddCorner( aBase.A );
|
||||
|
||||
bool turning = false;
|
||||
bool started = false;
|
||||
|
||||
|
||||
m_last = aBase.A;
|
||||
|
||||
|
||||
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->SetBaseIndex( aBaseIndex );
|
||||
|
||||
double thr = (double) m->spacing( );
|
||||
double thr = (double) m->spacing();
|
||||
|
||||
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 )
|
||||
break;
|
||||
|
||||
if( remaining > 3.0 * thr )
|
||||
{
|
||||
|
||||
if( !turning )
|
||||
{
|
||||
for( int i = 0; i < 2; i++ )
|
||||
|
@ -106,11 +105,10 @@ void PNS_MEANDERED_LINE::MeanderSegment( const SEG &aBase, int aBaseIndex )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
bool rv = m->Fit( MT_CHECK_FINISH, aBase, m_last, side );
|
||||
|
||||
if( rv )
|
||||
if( rv )
|
||||
{
|
||||
m->Fit( MT_TURN, aBase, m_last, side );
|
||||
AddMeander( m );
|
||||
|
@ -124,37 +122,35 @@ void PNS_MEANDERED_LINE::MeanderSegment( const SEG &aBase, int aBaseIndex )
|
|||
|
||||
side = !side;
|
||||
}
|
||||
|
||||
} else if( started )
|
||||
{
|
||||
bool rv = m->Fit( MT_FINISH, aBase, m_last, side );
|
||||
if( rv )
|
||||
AddMeander(m);
|
||||
|
||||
if( rv )
|
||||
AddMeander( m );
|
||||
|
||||
break;
|
||||
|
||||
} else {
|
||||
fail = true;
|
||||
}
|
||||
|
||||
|
||||
remaining = base_len - ( m_last - aBase.A ).EuclideanNorm( );
|
||||
|
||||
if( remaining < Settings( ).m_step )
|
||||
break;
|
||||
|
||||
|
||||
if( fail )
|
||||
{
|
||||
PNS_MEANDER_SHAPE tmp( m_placer, m_width, m_dual );
|
||||
tmp.SetBaselineOffset( m_baselineOffset );
|
||||
tmp.SetBaseIndex( aBaseIndex );
|
||||
|
||||
int nextP = tmp.spacing( ) - 2 * tmp.cornerRadius( ) + Settings( ).m_step;
|
||||
VECTOR2I pn = m_last + dir.Resize ( nextP );
|
||||
|
||||
if (aBase.Contains( pn ) && !m_dual)
|
||||
int nextP = tmp.spacing() - 2 * tmp.cornerRadius() + Settings().m_step;
|
||||
VECTOR2I pn = m_last + dir.Resize( nextP );
|
||||
|
||||
if( aBase.Contains( pn ) && !m_dual )
|
||||
{
|
||||
AddCorner ( pn );
|
||||
AddCorner( pn );
|
||||
} else
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
int PNS_MEANDER_SHAPE::spacing( ) const
|
||||
{
|
||||
if ( !m_dual )
|
||||
return std::max ( 2 * m_width, Settings( ).m_spacing );
|
||||
return std::max( 2 * m_width, Settings().m_spacing );
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -195,22 +192,24 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::circleQuad( VECTOR2D aP, VECTOR2D aDir, bool
|
|||
lc.Append( aP );
|
||||
return lc;
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D dir_u( aDir );
|
||||
VECTOR2D dir_v( aDir.Perpendicular( ) );
|
||||
|
||||
const int ArcSegments = Settings( ).m_cornerArcSegments;
|
||||
|
||||
for(int i = ArcSegments - 1; i >= 0; i--)
|
||||
const int ArcSegments = Settings().m_cornerArcSegments;
|
||||
|
||||
for( int i = ArcSegments - 1; i >= 0; i-- )
|
||||
{
|
||||
VECTOR2D p;
|
||||
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 ) );
|
||||
double alpha = (double) i / (double) ( ArcSegments - 1 ) * M_PI / 2.0;
|
||||
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 );
|
||||
}
|
||||
|
||||
return lc;
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I PNS_MEANDER_SHAPE::reflect( VECTOR2I p, const SEG& line )
|
||||
{
|
||||
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 );
|
||||
VECTOR2I c, rv;
|
||||
|
||||
if(!l_squared)
|
||||
if( !l_squared )
|
||||
c = p;
|
||||
else {
|
||||
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.x = line.A.x + rescale( t, (ecoord) d.x, l_squared );
|
||||
c.y = line.A.y + rescale( t, (ecoord) d.y, l_squared );
|
||||
}
|
||||
|
||||
|
||||
return 2 * c - p;
|
||||
}
|
||||
|
||||
|
||||
void PNS_MEANDER_SHAPE::start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir )
|
||||
{
|
||||
m_currentTarget = aTarget;
|
||||
m_currentTarget->Clear( );
|
||||
m_currentTarget->Clear();
|
||||
m_currentTarget->Append( aWhere );
|
||||
m_currentDir = aDir;
|
||||
m_currentPos = aWhere;
|
||||
}
|
||||
|
||||
|
||||
void PNS_MEANDER_SHAPE::forward( int aLength )
|
||||
{
|
||||
m_currentPos += m_currentDir.Resize( aLength );
|
||||
m_currentTarget->Append( m_currentPos );
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
if( aRadius <= 0 )
|
||||
{
|
||||
turn ( aSide ? -90 : 90 );
|
||||
turn( aSide ? -90 : 90 );
|
||||
return;
|
||||
}
|
||||
|
||||
VECTOR2D dir = m_currentDir.Resize( (double) aRadius );
|
||||
SHAPE_LINE_CHAIN arc = circleQuad( m_currentPos, dir, aSide );
|
||||
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 );
|
||||
}
|
||||
|
||||
void PNS_MEANDER_SHAPE::uShape ( int aSides, int aCorner, int aTop )
|
||||
|
||||
void PNS_MEANDER_SHAPE::uShape( int aSides, int aCorner, int aTop )
|
||||
{
|
||||
forward( aSides );
|
||||
arc( aCorner, true );
|
||||
|
@ -274,35 +278,36 @@ void PNS_MEANDER_SHAPE::uShape ( int aSides, int aCorner, int aTop )
|
|||
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();
|
||||
int cr = cornerRadius();
|
||||
int offset = aBaselineOffset;
|
||||
int spc = spacing();
|
||||
|
||||
if (aSide)
|
||||
|
||||
if( aSide )
|
||||
offset *= -1;
|
||||
|
||||
VECTOR2D dir_u_b ( aDir.Resize( offset ) );
|
||||
VECTOR2D dir_v_b (dir_u_b.Perpendicular());
|
||||
VECTOR2D dir_u_b( aDir.Resize( offset ) );
|
||||
VECTOR2D dir_v_b( dir_u_b.Perpendicular() );
|
||||
|
||||
if (2 * cr > aAmpl)
|
||||
if( 2 * cr > aAmpl )
|
||||
{
|
||||
cr = aAmpl / 2;
|
||||
}
|
||||
|
||||
if (2 * cr > spc)
|
||||
if( 2 * cr > spc )
|
||||
{
|
||||
cr = spc / 2;
|
||||
}
|
||||
|
||||
|
||||
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:
|
||||
{
|
||||
|
@ -313,7 +318,7 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
|
|||
{
|
||||
arc( cr - offset, false );
|
||||
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 ) );
|
||||
|
||||
break;
|
||||
|
@ -323,8 +328,8 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
|
|||
{
|
||||
start( &lc, aP - dir_u_b, aDir );
|
||||
turn ( 90 );
|
||||
forward( std::min(cr - offset, cr + offset) );
|
||||
forward( std::abs( offset ) );
|
||||
forward( std::min( cr - offset, cr + offset ) );
|
||||
forward( std::abs( offset ) );
|
||||
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
||||
arc( cr - offset, false );
|
||||
break;
|
||||
|
@ -332,13 +337,11 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
|
|||
|
||||
case MT_TURN:
|
||||
{
|
||||
|
||||
start( &lc, aP - dir_u_b, aDir );
|
||||
turn( 90 );
|
||||
forward( std::abs( offset ) );
|
||||
uShape ( aAmpl - cr, cr + offset, spc - 2 * cr );
|
||||
forward( std::abs( offset ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -347,7 +350,7 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
|
|||
arc( cr - offset, false );
|
||||
uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -358,71 +361,76 @@ SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape ( VECTOR2D aP, VECTOR2D aDir
|
|||
if( aSide )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
const SEG& b1 = aShape->BaseSegment();
|
||||
const SEG& b2 = m->BaseSegment();
|
||||
|
||||
if (b1.ApproxParallel(b2))
|
||||
if( b1.ApproxParallel( b2 ) )
|
||||
continue;
|
||||
|
||||
int n = m->CLine(0).SegmentCount();
|
||||
|
||||
for (int j = n - 1; j >= 0; j--)
|
||||
if ( aShape->CLine(0).Collide ( m->CLine(0).CSegment(j), aClearance ) )
|
||||
int n = m->CLine( 0 ).SegmentCount();
|
||||
|
||||
for( int j = n - 1; j >= 0; j-- )
|
||||
if( aShape->CLine( 0 ).Collide ( m->CLine( 0 ) .CSegment( j ), aClearance ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
||||
bool checkMode = false;
|
||||
PNS_MEANDER_TYPE prim1, prim2;
|
||||
|
||||
if(aType == MT_CHECK_START)
|
||||
if( aType == MT_CHECK_START )
|
||||
{
|
||||
prim1 = MT_START;
|
||||
prim2 = MT_TURN;
|
||||
checkMode = true;
|
||||
} else if (aType == MT_CHECK_FINISH ) {
|
||||
}
|
||||
else if( aType == MT_CHECK_FINISH )
|
||||
{
|
||||
prim1 = MT_TURN;
|
||||
prim2 = MT_FINISH;
|
||||
checkMode = true;
|
||||
}
|
||||
|
||||
if(checkMode)
|
||||
|
||||
if( checkMode )
|
||||
{
|
||||
PNS_MEANDER_SHAPE m1 ( m_placer, m_width, m_dual );
|
||||
PNS_MEANDER_SHAPE m2 ( 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 );
|
||||
|
||||
m1.SetBaselineOffset ( m_baselineOffset );
|
||||
m2.SetBaselineOffset ( m_baselineOffset );
|
||||
m1.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;
|
||||
|
||||
if(c1)
|
||||
c2 = m2.Fit ( prim2, aSeg, m1.End(), !aSide );
|
||||
if( c1 )
|
||||
c2 = m2.Fit( prim2, aSeg, m1.End(), !aSide );
|
||||
|
||||
if(c1 && c2)
|
||||
if( c1 && c2 )
|
||||
{
|
||||
m_type = prim1;
|
||||
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_baseSeg = m1.m_baseSeg;
|
||||
m_baseIndex = m1.m_baseIndex;
|
||||
updateBaseSegment ();
|
||||
updateBaseSegment();
|
||||
m_baselineOffset = m1.m_baselineOffset;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int minAmpl = st.m_minAmplitude;
|
||||
int maxAmpl = st.m_maxAmplitude;
|
||||
|
||||
if (m_dual)
|
||||
if( m_dual )
|
||||
{
|
||||
minAmpl = std::max( minAmpl, 2 * std::abs(m_baselineOffset) );
|
||||
maxAmpl = std::max( maxAmpl, 2 * std::abs(m_baselineOffset) );
|
||||
minAmpl = std::max( minAmpl, 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[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);
|
||||
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 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_shapes[0] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, 0 );
|
||||
}
|
||||
|
||||
m_type = aType;
|
||||
m_baseSeg =aSeg;
|
||||
m_baseSeg = aSeg;
|
||||
m_p0 = aP;
|
||||
m_side = aSide;
|
||||
m_amplitude = ampl;
|
||||
|
||||
|
||||
updateBaseSegment();
|
||||
|
||||
if( m_placer->CheckFit ( this ) )
|
||||
|
||||
if( m_placer->CheckFit( this ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (m_dual)
|
||||
m_shapes[1] = genMeanderShape ( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, -m_baselineOffset );
|
||||
|
||||
updateBaseSegment();
|
||||
|
||||
}
|
||||
|
||||
void PNS_MEANDER_SHAPE::Resize ( int aAmpl )
|
||||
void PNS_MEANDER_SHAPE::Recalculate()
|
||||
{
|
||||
if(aAmpl < 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 );
|
||||
|
||||
updateBaseSegment();
|
||||
}
|
||||
|
||||
|
||||
void PNS_MEANDER_SHAPE::Resize( int aAmpl )
|
||||
{
|
||||
if( aAmpl < 0 )
|
||||
return;
|
||||
|
||||
m_amplitude = aAmpl;
|
||||
|
@ -498,6 +507,7 @@ void PNS_MEANDER_SHAPE::Resize ( int aAmpl )
|
|||
Recalculate();
|
||||
}
|
||||
|
||||
|
||||
void PNS_MEANDER_SHAPE::MakeEmpty()
|
||||
{
|
||||
updateBaseSegment();
|
||||
|
@ -506,47 +516,46 @@ void PNS_MEANDER_SHAPE::MakeEmpty()
|
|||
|
||||
m_type = MT_EMPTY;
|
||||
|
||||
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 );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
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_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 );
|
||||
m_shapes[ 0 ].Clear( );
|
||||
m_shapes[ 1 ].Clear( );
|
||||
m_shapes[ 0 ].Append( aP1 );
|
||||
m_shapes[ 1 ].Append( aP2 );
|
||||
m_shapes[0].Clear();
|
||||
m_shapes[1].Clear();
|
||||
m_shapes[0].Append( aP1 );
|
||||
m_shapes[1].Append( aP2 );
|
||||
m_clippedBaseSeg.A = 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 );
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -554,26 +563,31 @@ void PNS_MEANDERED_LINE::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( )
|
||||
{
|
||||
if( m_dual )
|
||||
{
|
||||
VECTOR2I midpA = ( CLine( 0 ).CPoint( 0 ) + CLine( 1 ).CPoint( 0 ) ) / 2;
|
||||
VECTOR2I midpB = ( CLine( 0 ).CPoint( -1 ) + CLine( 1 ).CPoint( -1 ) ) / 2;
|
||||
|
||||
|
||||
m_clippedBaseSeg.A = m_baseSeg.LineProject( midpA );
|
||||
m_clippedBaseSeg.B = m_baseSeg.LineProject( midpB );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clippedBaseSeg.A = m_baseSeg.LineProject( CLine( 0 ).CPoint( 0 ) );
|
||||
m_clippedBaseSeg.B = m_baseSeg.LineProject( CLine( 0 ).CPoint( -1 ) );
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
CHAMFER // chamfered (45 degree segment)
|
||||
};
|
||||
|
||||
PNS_MEANDER_SETTINGS ()
|
||||
PNS_MEANDER_SETTINGS()
|
||||
{
|
||||
m_minAmplitude = 100000;
|
||||
m_maxAmplitude = 1000000;
|
||||
|
@ -65,26 +65,26 @@ public:
|
|||
m_targetSkew = 0;
|
||||
m_cornerType = ROUND;
|
||||
m_cornerRadiusPercentage = 100;
|
||||
m_lengthTollerance = 100000;
|
||||
m_lengthTolerance = 100000;
|
||||
m_cornerArcSegments = 8;
|
||||
}
|
||||
|
||||
|
||||
///> minimum meandering amplitude
|
||||
int m_minAmplitude;
|
||||
///> maximum meandering amplitude
|
||||
int m_maxAmplitude;
|
||||
///> meandering period/spacing (see dialog picture for explanation)
|
||||
///> meandering period/spacing (see dialog picture for explanation)
|
||||
int m_spacing;
|
||||
///> amplitude/spacing adjustment step
|
||||
int m_step;
|
||||
///> desired length of the tuned line/diff pair
|
||||
int m_targetLength;
|
||||
///> type of corners for the meandered line
|
||||
///> type of corners for the meandered line
|
||||
CornerType m_cornerType;
|
||||
///> rounding percentage (0 - 100)
|
||||
int m_cornerRadiusPercentage;
|
||||
///> allowable tuning error
|
||||
int m_lengthTollerance;
|
||||
int m_lengthTolerance;
|
||||
///> number of line segments for arc approximation
|
||||
int m_cornerArcSegments;
|
||||
///> target skew value for diff pair de-skewing
|
||||
|
@ -100,280 +100,278 @@ class PNS_MEANDERED_LINE;
|
|||
*/
|
||||
class PNS_MEANDER_SHAPE
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param aPlacer the meander placer instance
|
||||
* @param aWidth width of the meandered line
|
||||
* @param aIsDual when true, the shape contains two meandered
|
||||
* lines at a given offset (diff pairs)
|
||||
*/
|
||||
PNS_MEANDER_SHAPE( PNS_MEANDER_PLACER_BASE *aPlacer, int aWidth, bool aIsDual = false ) :
|
||||
m_placer( aPlacer ),
|
||||
m_dual( aIsDual ),
|
||||
m_width( aWidth ),
|
||||
m_baselineOffset( 0 )
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param aPlacer the meander placer instance
|
||||
* @param aWidth width of the meandered line
|
||||
* @param aIsDual when true, the shape contains two meandered
|
||||
* lines at a given offset (diff pairs)
|
||||
*/
|
||||
PNS_MEANDER_SHAPE( PNS_MEANDER_PLACER_BASE *aPlacer, int aWidth, bool aIsDual = false ) :
|
||||
m_placer( aPlacer ),
|
||||
m_dual( aIsDual ),
|
||||
m_width( aWidth ),
|
||||
m_baselineOffset( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Function SetType()
|
||||
*
|
||||
* Sets the type of the meander.
|
||||
*/
|
||||
void SetType( PNS_MEANDER_TYPE aType )
|
||||
{
|
||||
m_type = aType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetType()
|
||||
*
|
||||
* Sets the type of the meander.
|
||||
*/
|
||||
void SetType( PNS_MEANDER_TYPE aType )
|
||||
{
|
||||
m_type = aType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Type()
|
||||
*
|
||||
* @return the type of the meander.
|
||||
*/
|
||||
PNS_MEANDER_TYPE Type( ) const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
/**
|
||||
* Function Type()
|
||||
*
|
||||
* @return the type of the meander.
|
||||
*/
|
||||
PNS_MEANDER_TYPE Type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetBaseIndex()
|
||||
*
|
||||
* Sets an auxillary index of the segment being meandered in its original PNS_LINE.
|
||||
*/
|
||||
void SetBaseIndex( int aIndex )
|
||||
{
|
||||
m_baseIndex = aIndex;
|
||||
}
|
||||
/**
|
||||
* Function SetBaseIndex()
|
||||
*
|
||||
* Sets an auxillary index of the segment being meandered in its original PNS_LINE.
|
||||
*/
|
||||
void SetBaseIndex( int aIndex )
|
||||
{
|
||||
m_baseIndex = aIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function BaseIndex()
|
||||
*
|
||||
* @return auxillary index of the segment being meandered in its original PNS_LINE.
|
||||
*/
|
||||
int BaseIndex( ) const
|
||||
{
|
||||
return m_baseIndex;
|
||||
}
|
||||
/**
|
||||
* Function BaseIndex()
|
||||
*
|
||||
* @return auxillary index of the segment being meandered in its original PNS_LINE.
|
||||
*/
|
||||
int BaseIndex() const
|
||||
{
|
||||
return m_baseIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Amplitude()
|
||||
*
|
||||
* @return the amplitude of the meander shape.
|
||||
*/
|
||||
int Amplitude( ) const
|
||||
{
|
||||
return m_amplitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function MakeCorner()
|
||||
*
|
||||
* Creates a dummy meander shape representing a line corner. Used to define
|
||||
* the starts/ends of meandered segments.
|
||||
* @param aP1 corner point of the 1st line
|
||||
* @param aP2 corner point of the 2nd line (if m_dual == true)
|
||||
*/
|
||||
void MakeCorner( VECTOR2I aP1, VECTOR2I aP2 = VECTOR2I ( 0, 0 ) );
|
||||
/**
|
||||
* Function Amplitude()
|
||||
*
|
||||
* @return the amplitude of the meander shape.
|
||||
*/
|
||||
int Amplitude() const
|
||||
{
|
||||
return m_amplitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Resize()
|
||||
*
|
||||
* Changes the amplitude of the meander shape to aAmpl and recalculates
|
||||
* the resulting line chain.
|
||||
* @param aAmpl new amplitude.
|
||||
*/
|
||||
void Resize( int aAmpl );
|
||||
/**
|
||||
* Function MakeCorner()
|
||||
*
|
||||
* Creates a dummy meander shape representing a line corner. Used to define
|
||||
* the starts/ends of meandered segments.
|
||||
* @param aP1 corner point of the 1st line
|
||||
* @param aP2 corner point of the 2nd line (if m_dual == true)
|
||||
*/
|
||||
void MakeCorner( VECTOR2I aP1, VECTOR2I aP2 = VECTOR2I( 0, 0 ) );
|
||||
|
||||
/**
|
||||
* Function Recalculate()
|
||||
*
|
||||
* Recalculates the line chain representing the meanders's shape.
|
||||
*/
|
||||
void Recalculate ( );
|
||||
|
||||
/**
|
||||
* Function IsDual()
|
||||
*
|
||||
* @return true if the shape represents 2 parallel lines (diff pair).
|
||||
*/
|
||||
bool IsDual( ) const
|
||||
{
|
||||
return m_dual;
|
||||
}
|
||||
/**
|
||||
* Function Resize()
|
||||
*
|
||||
* Changes the amplitude of the meander shape to aAmpl and recalculates
|
||||
* the resulting line chain.
|
||||
* @param aAmpl new amplitude.
|
||||
*/
|
||||
void Resize( int aAmpl );
|
||||
|
||||
/**
|
||||
* Function Side()
|
||||
*
|
||||
* @return true if the meander is to the right of its base segment.
|
||||
*/
|
||||
bool Side( ) const
|
||||
{
|
||||
return m_side;
|
||||
}
|
||||
/**
|
||||
* Function Recalculate()
|
||||
*
|
||||
* Recalculates the line chain representing the meanders's shape.
|
||||
*/
|
||||
void Recalculate();
|
||||
|
||||
/**
|
||||
* Function End()
|
||||
*
|
||||
* @return end vertex of the base segment of the meander shape.
|
||||
*/
|
||||
VECTOR2I End( ) const
|
||||
{
|
||||
return m_clippedBaseSeg.B;
|
||||
}
|
||||
/**
|
||||
* Function IsDual()
|
||||
*
|
||||
* @return true if the shape represents 2 parallel lines (diff pair).
|
||||
*/
|
||||
bool IsDual() const
|
||||
{
|
||||
return m_dual;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function CLine()
|
||||
*
|
||||
* @return the line chain representing the shape of the meander.
|
||||
*/
|
||||
const SHAPE_LINE_CHAIN& CLine( int aShape ) const
|
||||
{
|
||||
return m_shapes[ aShape ];
|
||||
}
|
||||
/**
|
||||
* Function Side()
|
||||
*
|
||||
* @return true if the meander is to the right of its base segment.
|
||||
*/
|
||||
bool Side() const
|
||||
{
|
||||
return m_side;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function MakeEmpty()
|
||||
*
|
||||
* Replaces the meander with straight bypass line(s), effectively
|
||||
* clearing it.
|
||||
*/
|
||||
void MakeEmpty( );
|
||||
/**
|
||||
* Function End()
|
||||
*
|
||||
* @return end vertex of the base segment of the meander shape.
|
||||
*/
|
||||
VECTOR2I End() const
|
||||
{
|
||||
return m_clippedBaseSeg.B;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Fit()
|
||||
*
|
||||
* Attempts to fit a meander of a given type onto a segment, avoiding
|
||||
* collisions with other board features.
|
||||
* @param aType type of meander shape
|
||||
* @param aSeg base segment for meandering
|
||||
* @param aP start point of the meander
|
||||
* @param aSide side of aSeg to put the meander on (true = right)
|
||||
* @return true on success.
|
||||
*/
|
||||
bool Fit( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide );
|
||||
/**
|
||||
* Function CLine()
|
||||
*
|
||||
* @return the line chain representing the shape of the meander.
|
||||
*/
|
||||
const SHAPE_LINE_CHAIN& CLine( int aShape ) const
|
||||
{
|
||||
return m_shapes[aShape];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function BaseSegment()
|
||||
*
|
||||
* Returns the base segment the meadner was fitted to.
|
||||
* @return the base segment.
|
||||
*/
|
||||
const SEG& BaseSegment( ) const
|
||||
{
|
||||
return m_clippedBaseSeg;
|
||||
}
|
||||
/**
|
||||
* Function MakeEmpty()
|
||||
*
|
||||
* Replaces the meander with straight bypass line(s), effectively
|
||||
* clearing it.
|
||||
*/
|
||||
void MakeEmpty();
|
||||
|
||||
/**
|
||||
* Function BaselineLength()
|
||||
*
|
||||
* @return length of the base segment for the meander (i.e.
|
||||
* the minimim tuned length.
|
||||
*/
|
||||
int BaselineLength( ) const;
|
||||
|
||||
/**
|
||||
* Function MaxTunableLength()
|
||||
*
|
||||
* @return the length of the fitted line chain.
|
||||
*/
|
||||
int MaxTunableLength( ) const;
|
||||
/**
|
||||
* Function Fit()
|
||||
*
|
||||
* Attempts to fit a meander of a given type onto a segment, avoiding
|
||||
* collisions with other board features.
|
||||
* @param aType type of meander shape
|
||||
* @param aSeg base segment for meandering
|
||||
* @param aP start point of the meander
|
||||
* @param aSide side of aSeg to put the meander on (true = right)
|
||||
* @return true on success.
|
||||
*/
|
||||
bool Fit( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide );
|
||||
|
||||
/**
|
||||
* Function Settings()
|
||||
*
|
||||
* @return the current meandering settings.
|
||||
*/
|
||||
const PNS_MEANDER_SETTINGS& Settings( ) const;
|
||||
/**
|
||||
* Function BaseSegment()
|
||||
*
|
||||
* Returns the base segment the meadner was fitted to.
|
||||
* @return the base segment.
|
||||
*/
|
||||
const SEG& BaseSegment() const
|
||||
{
|
||||
return m_clippedBaseSeg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Width()
|
||||
*
|
||||
* @return width of the meandered line.
|
||||
*/
|
||||
int Width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
/**
|
||||
* Function BaselineLength()
|
||||
*
|
||||
* @return length of the base segment for the meander (i.e.
|
||||
* the minimum tuned length.
|
||||
*/
|
||||
int BaselineLength() const;
|
||||
|
||||
/**
|
||||
* Function SetBaselineOffset()
|
||||
*
|
||||
* Sets the parallel offset between the base segment and the meandered
|
||||
* line. Used for dual menaders (diff pair) only.
|
||||
* @param aOffset the offset
|
||||
*/
|
||||
void SetBaselineOffset ( int aOffset )
|
||||
{
|
||||
m_baselineOffset = aOffset;
|
||||
}
|
||||
/**
|
||||
* Function MaxTunableLength()
|
||||
*
|
||||
* @return the length of the fitted line chain.
|
||||
*/
|
||||
int MaxTunableLength() const;
|
||||
|
||||
private:
|
||||
friend class PNS_MEANDERED_LINE;
|
||||
/**
|
||||
* Function Settings()
|
||||
*
|
||||
* @return the current meandering settings.
|
||||
*/
|
||||
const PNS_MEANDER_SETTINGS& Settings() const;
|
||||
|
||||
///> starts turtle drawing
|
||||
void start ( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir );
|
||||
///> moves turtle forward by aLength
|
||||
void forward ( int aLength );
|
||||
///> turns the turtle by aAngle
|
||||
void turn ( int aAngle );
|
||||
///> tells the turtle to draw an arc of given radius and turn direction
|
||||
void arc ( int aRadius, bool aSide );
|
||||
///> tells the turtle to draw an U-like shape
|
||||
void uShape ( int aSides, int aCorner, int aTop );
|
||||
/**
|
||||
* Function Width()
|
||||
*
|
||||
* @return width of the meandered line.
|
||||
*/
|
||||
int Width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
///> generates a 90-degree circular arc
|
||||
SHAPE_LINE_CHAIN circleQuad ( VECTOR2D aP, VECTOR2D aDir, bool side );
|
||||
/**
|
||||
* Function SetBaselineOffset()
|
||||
*
|
||||
* Sets the parallel offset between the base segment and the meandered
|
||||
* line. Used for dual menaders (diff pair) only.
|
||||
* @param aOffset the offset
|
||||
*/
|
||||
void SetBaselineOffset( int aOffset )
|
||||
{
|
||||
m_baselineOffset = aOffset;
|
||||
}
|
||||
|
||||
///> reflects a point onto other side of a given segment
|
||||
VECTOR2I reflect ( VECTOR2I p, const SEG& line );
|
||||
private:
|
||||
friend class PNS_MEANDERED_LINE;
|
||||
|
||||
///> 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);
|
||||
|
||||
///> recalculates the clipped baseline after the parameters of
|
||||
///> the meander have been changed.
|
||||
void updateBaseSegment();
|
||||
|
||||
///> returns sanitized corner radius value
|
||||
int cornerRadius ( ) const;
|
||||
|
||||
///> returns sanitized spacing value
|
||||
int spacing ( ) const;
|
||||
|
||||
///> the type
|
||||
PNS_MEANDER_TYPE m_type;
|
||||
///> the placer that placed this meander
|
||||
PNS_MEANDER_PLACER_BASE *m_placer;
|
||||
///> dual or single line
|
||||
bool m_dual;
|
||||
///> width of the line
|
||||
int m_width;
|
||||
///> amplitude of the meander
|
||||
int m_amplitude;
|
||||
///> offset wrs the base segment (dual only)
|
||||
int m_baselineOffset;
|
||||
///> first point of the meandered line
|
||||
VECTOR2I m_p0;
|
||||
///> base segment (unclipped)
|
||||
SEG m_baseSeg;
|
||||
///> base segment (clipped)
|
||||
SEG m_clippedBaseSeg;
|
||||
///> side (true = right)
|
||||
bool m_side;
|
||||
///> the actual shapes (0 used for single, both for dual)
|
||||
SHAPE_LINE_CHAIN m_shapes[2];
|
||||
///> index of the meandered segment in the base line
|
||||
int m_baseIndex;
|
||||
///> current turtle direction
|
||||
VECTOR2D m_currentDir;
|
||||
///> current turtle position
|
||||
VECTOR2D m_currentPos;
|
||||
///> the line the turtle is drawing on
|
||||
SHAPE_LINE_CHAIN* m_currentTarget;
|
||||
///> starts turtle drawing
|
||||
void start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir );
|
||||
///> moves turtle forward by aLength
|
||||
void forward( int aLength );
|
||||
///> turns the turtle by aAngle
|
||||
void turn( int aAngle );
|
||||
///> tells the turtle to draw an arc of given radius and turn direction
|
||||
void arc( int aRadius, bool aSide );
|
||||
///> tells the turtle to draw an U-like shape
|
||||
void uShape( int aSides, int aCorner, int aTop );
|
||||
|
||||
///> generates a 90-degree circular arc
|
||||
SHAPE_LINE_CHAIN circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide );
|
||||
|
||||
///> reflects a point onto other side of a given segment
|
||||
VECTOR2I reflect( VECTOR2I aP, const SEG& aLine );
|
||||
|
||||
///> 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 );
|
||||
|
||||
///> recalculates the clipped baseline after the parameters of
|
||||
///> the meander have been changed.
|
||||
void updateBaseSegment();
|
||||
|
||||
///> returns sanitized corner radius value
|
||||
int cornerRadius() const;
|
||||
|
||||
///> returns sanitized spacing value
|
||||
int spacing() const;
|
||||
|
||||
///> the type
|
||||
PNS_MEANDER_TYPE m_type;
|
||||
///> the placer that placed this meander
|
||||
PNS_MEANDER_PLACER_BASE* m_placer;
|
||||
///> dual or single line
|
||||
bool m_dual;
|
||||
///> width of the line
|
||||
int m_width;
|
||||
///> amplitude of the meander
|
||||
int m_amplitude;
|
||||
///> offset wrs the base segment (dual only)
|
||||
int m_baselineOffset;
|
||||
///> first point of the meandered line
|
||||
VECTOR2I m_p0;
|
||||
///> base segment (unclipped)
|
||||
SEG m_baseSeg;
|
||||
///> base segment (clipped)
|
||||
SEG m_clippedBaseSeg;
|
||||
///> side (true = right)
|
||||
bool m_side;
|
||||
///> the actual shapes (0 used for single, both for dual)
|
||||
SHAPE_LINE_CHAIN m_shapes[2];
|
||||
///> index of the meandered segment in the base line
|
||||
int m_baseIndex;
|
||||
///> current turtle direction
|
||||
VECTOR2D m_currentDir;
|
||||
///> current turtle position
|
||||
VECTOR2D m_currentPos;
|
||||
///> the line the turtle is drawing on
|
||||
SHAPE_LINE_CHAIN* m_currentTarget;
|
||||
};
|
||||
|
||||
|
||||
|
@ -384,115 +382,111 @@ class PNS_MEANDER_SHAPE
|
|||
*/
|
||||
class PNS_MEANDERED_LINE
|
||||
{
|
||||
public:
|
||||
PNS_MEANDERED_LINE( )
|
||||
{
|
||||
public:
|
||||
PNS_MEANDERED_LINE()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param aPlacer the meander placer instance
|
||||
* @param aIsDual when true, the meanders are generated for two coupled lines
|
||||
*/
|
||||
PNS_MEANDERED_LINE( PNS_MEANDER_PLACER_BASE* aPlacer, bool aIsDual = false ) :
|
||||
m_placer( aPlacer ),
|
||||
m_dual( aIsDual )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param aPlacer the meander placer instance
|
||||
* @param aIsDual when true, the meanders are generated for two coupled lines
|
||||
*/
|
||||
PNS_MEANDERED_LINE( PNS_MEANDER_PLACER_BASE *aPlacer, bool aIsDual = false ) :
|
||||
m_placer( aPlacer ),
|
||||
m_dual( aIsDual )
|
||||
{
|
||||
/**
|
||||
* Function AddCorner()
|
||||
*
|
||||
* Creates a dummy meander shape representing a line corner. Used to define
|
||||
* the starts/ends of meandered segments.
|
||||
* @param aA corner point of the 1st line
|
||||
* @param aB corner point of the 2nd line (if m_dual == true)
|
||||
*/
|
||||
void AddCorner( const VECTOR2I& aA, const VECTOR2I& aB = VECTOR2I( 0, 0 ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function AddCorner()
|
||||
*
|
||||
* Creates a dummy meander shape representing a line corner. Used to define
|
||||
* the starts/ends of meandered segments.
|
||||
* @param aA corner point of the 1st line
|
||||
* @param aB corner point of the 2nd line (if m_dual == true)
|
||||
*/
|
||||
void AddCorner( const VECTOR2I& aA, const VECTOR2I& aB = VECTOR2I( 0, 0 ) );
|
||||
|
||||
/**
|
||||
* Function AddMeander()
|
||||
*
|
||||
* Adds a new meander shape the the meandered line.
|
||||
* @param aShape the meander shape to add
|
||||
*/
|
||||
void AddMeander( PNS_MEANDER_SHAPE *aShape );
|
||||
|
||||
/**
|
||||
* Function Clear()
|
||||
*
|
||||
* Clears the line geometry, removing all corners and meanders.
|
||||
*/
|
||||
void Clear( );
|
||||
/**
|
||||
* Function AddMeander()
|
||||
*
|
||||
* Adds a new meander shape the the meandered line.
|
||||
* @param aShape the meander shape to add
|
||||
*/
|
||||
void AddMeander( PNS_MEANDER_SHAPE* aShape );
|
||||
|
||||
/**
|
||||
* Function SetWidth()
|
||||
*
|
||||
* Sets the line width.
|
||||
*/
|
||||
void SetWidth( int aWidth )
|
||||
{
|
||||
m_width = aWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function MeanderSegment()
|
||||
*
|
||||
* Fits maximum amplitude meanders on a given segment and adds to the
|
||||
* current line.
|
||||
* @param aSeg the base segment to meander
|
||||
* @param aBaseIndex index of the base segment in the original line
|
||||
*/
|
||||
void MeanderSegment( const SEG& aSeg, int aBaseIndex = 0 );
|
||||
/**
|
||||
* Function Clear()
|
||||
*
|
||||
* Clears the line geometry, removing all corners and meanders.
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
/// @copydoc PNS_MEANDER_SHAPE::SetBaselineOffset()
|
||||
void SetBaselineOffset( int aOffset )
|
||||
{
|
||||
m_baselineOffset = aOffset;
|
||||
}
|
||||
/**
|
||||
* Function SetWidth()
|
||||
*
|
||||
* Sets the line width.
|
||||
*/
|
||||
void SetWidth( int aWidth )
|
||||
{
|
||||
m_width = aWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Meanders()
|
||||
*
|
||||
* @return set of meander shapes for this line
|
||||
*/
|
||||
std::vector<PNS_MEANDER_SHAPE*> & Meanders()
|
||||
{
|
||||
return m_meanders;
|
||||
}
|
||||
/**
|
||||
* Function MeanderSegment()
|
||||
*
|
||||
* Fits maximum amplitude meanders on a given segment and adds to the
|
||||
* current line.
|
||||
* @param aSeg the base segment to meander
|
||||
* @param aBaseIndex index of the base segment in the original line
|
||||
*/
|
||||
void MeanderSegment( const SEG& aSeg, int aBaseIndex = 0 );
|
||||
|
||||
/// @copydoc PNS_MEANDER_SHAPE::SetBaselineOffset()
|
||||
void SetBaselineOffset( int aOffset )
|
||||
{
|
||||
m_baselineOffset = aOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function CheckSelfIntersections()
|
||||
*
|
||||
* Checks if the given shape is intersecting with any other meander in
|
||||
* the current line.
|
||||
* @param aShape the shape to check
|
||||
* @param aClearance clearance value
|
||||
* @return true, if the meander shape is not colliding
|
||||
*/
|
||||
bool CheckSelfIntersections ( PNS_MEANDER_SHAPE *aShape, int aClearance );
|
||||
|
||||
/**
|
||||
* Function Settings()
|
||||
*
|
||||
* @return the current meandering settings.
|
||||
*/
|
||||
const PNS_MEANDER_SETTINGS& Settings() const;
|
||||
/**
|
||||
* Function Meanders()
|
||||
*
|
||||
* @return set of meander shapes for this line
|
||||
*/
|
||||
std::vector<PNS_MEANDER_SHAPE*>& Meanders()
|
||||
{
|
||||
return m_meanders;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Function CheckSelfIntersections()
|
||||
*
|
||||
* Checks if the given shape is intersecting with any other meander in
|
||||
* the current line.
|
||||
* @param aShape the shape to check
|
||||
* @param aClearance clearance value
|
||||
* @return true, if the meander shape is not colliding
|
||||
*/
|
||||
bool CheckSelfIntersections ( PNS_MEANDER_SHAPE* aShape, int aClearance );
|
||||
|
||||
VECTOR2I m_last;
|
||||
|
||||
PNS_MEANDER_PLACER_BASE *m_placer;
|
||||
std::vector<PNS_MEANDER_SHAPE *> m_meanders;
|
||||
|
||||
bool m_dual;
|
||||
int m_width;
|
||||
int m_baselineOffset;
|
||||
/**
|
||||
* Function Settings()
|
||||
*
|
||||
* @return the current meandering settings.
|
||||
*/
|
||||
const PNS_MEANDER_SETTINGS& Settings() const;
|
||||
|
||||
private:
|
||||
VECTOR2I m_last;
|
||||
|
||||
PNS_MEANDER_PLACER_BASE* m_placer;
|
||||
std::vector<PNS_MEANDER_SHAPE*> m_meanders;
|
||||
|
||||
bool m_dual;
|
||||
int m_width;
|
||||
int m_baselineOffset;
|
||||
};
|
||||
|
||||
#endif // __PNS_MEANDER_H
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
|
||||
PNS_MEANDER_PLACER::PNS_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
|
||||
PNS_MEANDER_PLACER_BASE ( aRouter )
|
||||
PNS_MEANDER_PLACER_BASE( aRouter )
|
||||
{
|
||||
m_world = 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
|
||||
{
|
||||
if( !m_currentNode )
|
||||
|
@ -54,73 +54,76 @@ PNS_NODE* PNS_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
|
|||
return m_currentNode;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
VECTOR2I p;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_currentNode = NULL;
|
||||
m_currentStart = p;
|
||||
|
||||
m_world = Router( )->GetWorld( )->Branch( );
|
||||
m_world = Router()->GetWorld()->Branch();
|
||||
m_originLine = m_world->AssembleLine( m_initialSegment );
|
||||
|
||||
PNS_TOPOLOGY topo( m_world );
|
||||
m_tunedPath = topo.AssembleTrivialPath( m_initialSegment );
|
||||
|
||||
m_world->Remove( m_originLine );
|
||||
|
||||
m_currentWidth = m_originLine->Width( );
|
||||
|
||||
m_currentWidth = m_originLine->Width();
|
||||
m_currentEnd = VECTOR2I( 0, 0 );
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int PNS_MEANDER_PLACER::origPathLength( ) const
|
||||
int PNS_MEANDER_PLACER::origPathLength() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
SHAPE_LINE_CHAIN pre, tuned, post;
|
||||
|
||||
if(m_currentNode)
|
||||
if( 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.SetWidth( m_originLine->Width() );
|
||||
m_result.SetBaselineOffset( 0 );
|
||||
|
||||
|
||||
for( int i = 0; i < tuned.SegmentCount(); i++ )
|
||||
{
|
||||
const SEG s = tuned.CSegment( i );
|
||||
|
@ -128,43 +131,43 @@ bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTa
|
|||
m_result.MeanderSegment( s );
|
||||
m_result.AddCorner( s.B );
|
||||
}
|
||||
|
||||
int lineLen = origPathLength( );
|
||||
|
||||
int lineLen = origPathLength();
|
||||
|
||||
m_lastLength = lineLen;
|
||||
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;
|
||||
} else {
|
||||
m_lastLength = lineLen - tuned.Length( );
|
||||
tuneLineLength( m_result, aTargetLength - lineLen );
|
||||
m_lastLength = lineLen - tuned.Length();
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
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;
|
||||
else
|
||||
m_lastStatus = TUNED;
|
||||
|
||||
}
|
||||
|
||||
m_finalShape.Clear( );
|
||||
m_finalShape.Clear();
|
||||
m_finalShape.Append( pre );
|
||||
m_finalShape.Append( tuned );
|
||||
m_finalShape.Append( post );
|
||||
m_finalShape.Simplify( );
|
||||
m_finalShape.Simplify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -187,50 +189,54 @@ bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTa
|
|||
|
||||
bool PNS_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||
{
|
||||
m_currentTrace = PNS_LINE( *m_originLine, m_finalShape );
|
||||
m_currentNode->Add ( &m_currentTrace );
|
||||
m_currentTrace = PNS_LINE( *m_originLine, m_finalShape );
|
||||
m_currentNode->Add( &m_currentTrace );
|
||||
|
||||
Router( )->CommitRouting( m_currentNode );
|
||||
Router()->CommitRouting( m_currentNode );
|
||||
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 ) );
|
||||
|
||||
|
||||
if( m_currentNode->CheckColliding( &l ) )
|
||||
return false;
|
||||
|
||||
int w = aShape->Width( );
|
||||
int w = aShape->Width();
|
||||
int clearance = w + m_settings.m_spacing;
|
||||
|
||||
return m_result.CheckSelfIntersections( aShape, clearance );
|
||||
}
|
||||
|
||||
|
||||
|
||||
const PNS_ITEMSET PNS_MEANDER_PLACER::Traces()
|
||||
{
|
||||
m_currentTrace = PNS_LINE( *m_originLine, m_finalShape );
|
||||
return PNS_ITEMSET( &m_currentTrace );
|
||||
}
|
||||
|
||||
|
||||
const VECTOR2I& PNS_MEANDER_PLACER::CurrentEnd() const
|
||||
{
|
||||
return m_currentEnd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int PNS_MEANDER_PLACER::CurrentNet() const
|
||||
{
|
||||
return m_initialSegment->Net( );
|
||||
return m_initialSegment->Net();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
@ -240,10 +246,10 @@ const wxString PNS_MEANDER_PLACER::TuningInfo( ) const
|
|||
status = _( "Too long: " );
|
||||
break;
|
||||
case TOO_SHORT:
|
||||
status = _(" Too short: " );
|
||||
status = _( "Too short: " );
|
||||
break;
|
||||
case TUNED:
|
||||
status = _(" Tuned: " );
|
||||
status = _( "Tuned: " );
|
||||
break;
|
||||
default:
|
||||
return _( "?" );
|
||||
|
@ -252,11 +258,12 @@ const wxString PNS_MEANDER_PLACER::TuningInfo( ) const
|
|||
status += LengthDoubleToString( (double) m_lastLength, false );
|
||||
status += "/";
|
||||
status += LengthDoubleToString( (double) m_settings.m_targetLength, false );
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -61,16 +61,16 @@ public:
|
|||
|
||||
/// @copydoc PNS_PLACEMENT_ALGO::CurrentNode()
|
||||
PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
|
||||
|
||||
|
||||
/// @copydoc PNS_PLACEMENT_ALGO::Traces()
|
||||
const PNS_ITEMSET Traces();
|
||||
|
||||
/// @copydoc PNS_PLACEMENT_ALGO::CurrentEnd()
|
||||
const VECTOR2I& CurrentEnd() const;
|
||||
|
||||
|
||||
/// @copydoc PNS_PLACEMENT_ALGO::CurrentNet()
|
||||
int CurrentNet() const;
|
||||
|
||||
|
||||
/// @copydoc PNS_PLACEMENT_ALGO::CurrentLayer()
|
||||
int CurrentLayer() const;
|
||||
|
||||
|
@ -84,12 +84,12 @@ public:
|
|||
bool CheckFit ( PNS_MEANDER_SHAPE* aShape );
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
bool doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength );
|
||||
|
||||
void setWorld ( PNS_NODE* aWorld );
|
||||
|
||||
virtual int origPathLength () const;
|
||||
void setWorld( PNS_NODE* aWorld );
|
||||
|
||||
virtual int origPathLength() const;
|
||||
|
||||
///> pointer to world to search colliding items
|
||||
PNS_NODE* m_world;
|
||||
|
@ -106,7 +106,7 @@ protected:
|
|||
|
||||
SHAPE_LINE_CHAIN m_finalShape;
|
||||
PNS_MEANDERED_LINE m_result;
|
||||
PNS_SEGMENT *m_initialSegment;
|
||||
PNS_SEGMENT* m_initialSegment;
|
||||
|
||||
int m_lastLength;
|
||||
TUNING_STATUS m_lastStatus;
|
||||
|
|
|
@ -25,35 +25,38 @@
|
|||
PNS_MEANDER_PLACER_BASE::PNS_MEANDER_PLACER_BASE( PNS_ROUTER* 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 )
|
||||
{
|
||||
int a = m_settings.m_maxAmplitude + aSign * m_settings.m_step;
|
||||
a = std::max( a, m_settings.m_minAmplitude );
|
||||
|
||||
|
||||
m_settings.m_maxAmplitude = a;
|
||||
}
|
||||
|
||||
|
||||
void PNS_MEANDER_PLACER_BASE::SpacingStep( int aSign )
|
||||
{
|
||||
int s = m_settings.m_spacing + aSign * m_settings.m_step;
|
||||
s = std::max( s, 2 * m_currentWidth );
|
||||
|
||||
|
||||
m_settings.m_spacing = s;
|
||||
}
|
||||
|
||||
|
||||
void PNS_MEANDER_PLACER_BASE::UpdateSettings( const PNS_MEANDER_SETTINGS& aSettings )
|
||||
{
|
||||
m_settings = aSettings;
|
||||
}
|
||||
|
||||
|
||||
void PNS_MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
|
||||
const VECTOR2I& aTuneStart,
|
||||
const VECTOR2I& aCursorPos,
|
||||
|
@ -73,47 +76,48 @@ void PNS_MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
|
|||
|
||||
if( i_start > i_end )
|
||||
{
|
||||
l = l.Reverse( );
|
||||
l = l.Reverse();
|
||||
i_start = l.Find( m );
|
||||
i_end = l.Find( n );
|
||||
}
|
||||
|
||||
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.Simplify( );
|
||||
aTuned.Simplify();
|
||||
}
|
||||
|
||||
|
||||
void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation )
|
||||
{
|
||||
int remaining = aElongation;
|
||||
int remaining = aElongation;
|
||||
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();
|
||||
|
||||
if(remaining < 0)
|
||||
if( remaining < 0 )
|
||||
{
|
||||
if(!finished)
|
||||
{
|
||||
PNS_MEANDER_TYPE newType;
|
||||
if( !finished )
|
||||
{
|
||||
PNS_MEANDER_TYPE newType;
|
||||
|
||||
if ( m->Type() == MT_START || m->Type() == MT_SINGLE)
|
||||
newType = MT_SINGLE;
|
||||
else
|
||||
newType = MT_FINISH;
|
||||
if( m->Type() == MT_START || m->Type() == MT_SINGLE )
|
||||
newType = MT_SINGLE;
|
||||
else
|
||||
newType = MT_FINISH;
|
||||
|
||||
m->SetType ( newType );
|
||||
m->Recalculate( );
|
||||
|
||||
finished = true;
|
||||
} else {
|
||||
m->MakeEmpty();
|
||||
}
|
||||
m->SetType( newType );
|
||||
m->Recalculate();
|
||||
|
||||
finished = true;
|
||||
} else {
|
||||
m->MakeEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +125,7 @@ void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aE
|
|||
remaining = aElongation;
|
||||
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 )
|
||||
{
|
||||
|
@ -137,31 +141,32 @@ void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aE
|
|||
|
||||
if( 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;
|
||||
}
|
||||
|
||||
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;
|
||||
else if( aValue > aExpected + aTollerance )
|
||||
else if( aValue > aExpected + aTolerance )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
};
|
||||
|
||||
PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter );
|
||||
virtual ~PNS_MEANDER_PLACER_BASE( );
|
||||
virtual ~PNS_MEANDER_PLACER_BASE();
|
||||
|
||||
/**
|
||||
* Function TuningInfo()
|
||||
|
@ -62,15 +62,15 @@ public:
|
|||
* Returns a string describing the status and length of the
|
||||
* tuned traces.
|
||||
*/
|
||||
virtual const wxString TuningInfo( ) const = 0;
|
||||
|
||||
virtual const wxString TuningInfo() const = 0;
|
||||
|
||||
/**
|
||||
* Function TuningStatus()
|
||||
*
|
||||
* Returns the tuning status (too short, too long, etc.)
|
||||
* of the trace(s) being tuned.
|
||||
*/
|
||||
virtual TUNING_STATUS TuningStatus( ) const = 0;
|
||||
virtual TUNING_STATUS TuningStatus() const = 0;
|
||||
|
||||
/**
|
||||
* Function AmplitudeStep()
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
* @param aSign direction (negative = decrease, positive = increase).
|
||||
*/
|
||||
virtual void AmplitudeStep( int aSign );
|
||||
|
||||
|
||||
/**
|
||||
* Function SpacingStep()
|
||||
*
|
||||
|
@ -95,7 +95,7 @@ public:
|
|||
* @return the settings
|
||||
*/
|
||||
virtual const PNS_MEANDER_SETTINGS& MeanderSettings() const;
|
||||
|
||||
|
||||
/*
|
||||
* Function UpdateSettings()
|
||||
*
|
||||
|
@ -103,7 +103,7 @@ public:
|
|||
* @param aSettings the settings
|
||||
*/
|
||||
virtual void UpdateSettings( const PNS_MEANDER_SETTINGS& aSettings);
|
||||
|
||||
|
||||
/**
|
||||
* Function CheckFit()
|
||||
*
|
||||
|
@ -113,18 +113,16 @@ public:
|
|||
* @param aShape the shape to check
|
||||
* @return true if the shape fits
|
||||
*/
|
||||
virtual bool CheckFit ( PNS_MEANDER_SHAPE* aShape )
|
||||
{
|
||||
virtual bool CheckFit( PNS_MEANDER_SHAPE* aShape )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/**
|
||||
* Function cutTunedLine()
|
||||
*
|
||||
*
|
||||
* Extracts the part of a track to be meandered, depending on the
|
||||
* starting point and the cursor position.
|
||||
* @param aOrigin the original line
|
||||
|
@ -144,22 +142,22 @@ protected:
|
|||
/**
|
||||
* Function tuneLineLength()
|
||||
*
|
||||
* Takes a set of meanders in aTuned and tunes their length to
|
||||
* Takes a set of meanders in aTuned and tunes their length to
|
||||
* extend the original line length by 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)
|
||||
int m_currentWidth;
|
||||
///> meandering settings
|
||||
PNS_MEANDER_SETTINGS m_settings;
|
||||
PNS_MEANDER_SETTINGS m_settings;
|
||||
///> current end point
|
||||
VECTOR2I m_currentEnd;
|
||||
};
|
||||
|
|
|
@ -38,30 +38,31 @@ PNS_MEANDER_SKEW_PLACER::PNS_MEANDER_SKEW_PLACER ( PNS_ROUTER* aRouter ) :
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
PNS_MEANDER_SKEW_PLACER::~PNS_MEANDER_SKEW_PLACER( )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
VECTOR2I p;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_currentNode = NULL;
|
||||
m_currentStart = p;
|
||||
|
||||
m_world = Router( )->GetWorld( )->Branch( );
|
||||
m_world = Router()->GetWorld( )->Branch();
|
||||
m_originLine = m_world->AssembleLine( m_initialSegment );
|
||||
|
||||
PNS_TOPOLOGY topo( m_world );
|
||||
|
@ -75,18 +76,17 @@ bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_originPair.SetGap ( Router()->Sizes().DiffPairGap() );
|
||||
|
||||
if( !m_originPair.PLine().SegmentCount() ||
|
||||
!m_originPair.NLine().SegmentCount() )
|
||||
return false;
|
||||
|
||||
m_tunedPathP = topo.AssembleTrivialPath ( m_originPair.PLine().GetLink(0) );
|
||||
m_tunedPathN = topo.AssembleTrivialPath ( m_originPair.NLine().GetLink(0) );
|
||||
|
||||
m_tunedPathP = topo.AssembleTrivialPath ( m_originPair.PLine().GetLink( 0 ) );
|
||||
m_tunedPathN = topo.AssembleTrivialPath ( m_originPair.NLine().GetLink( 0 ) );
|
||||
|
||||
m_world->Remove( m_originLine );
|
||||
|
||||
|
||||
m_currentWidth = m_originLine->Width( );
|
||||
m_currentEnd = VECTOR2I( 0, 0 );
|
||||
|
||||
|
@ -94,55 +94,58 @@ bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
m_coupledLength = itemsetLength ( m_tunedPathN );
|
||||
else
|
||||
m_coupledLength = itemsetLength ( m_tunedPathP );
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int PNS_MEANDER_SKEW_PLACER::origPathLength( ) const
|
||||
int PNS_MEANDER_SKEW_PLACER::origPathLength( ) const
|
||||
{
|
||||
return itemsetLength ( m_tunedPath );
|
||||
}
|
||||
|
||||
|
||||
int PNS_MEANDER_SKEW_PLACER::itemsetLength( const PNS_ITEMSET& aSet ) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
int PNS_MEANDER_SKEW_PLACER::currentSkew () const
|
||||
|
||||
int PNS_MEANDER_SKEW_PLACER::currentSkew() const
|
||||
{
|
||||
return m_lastLength - m_coupledLength;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
switch ( m_lastStatus )
|
||||
switch( m_lastStatus )
|
||||
{
|
||||
case TOO_LONG:
|
||||
status = _( "Too long: skew " );
|
||||
break;
|
||||
case TOO_SHORT:
|
||||
status = _(" Too short: skew " );
|
||||
status = _( "Too short: skew " );
|
||||
break;
|
||||
case TUNED:
|
||||
status = _(" Tuned: skew " );
|
||||
status = _( "Tuned: skew " );
|
||||
break;
|
||||
default:
|
||||
return _( "?" );
|
||||
|
@ -151,7 +154,7 @@ const wxString PNS_MEANDER_SKEW_PLACER::TuningInfo( ) const
|
|||
status += LengthDoubleToString( (double) m_lastLength - m_coupledLength, false );
|
||||
status += "/";
|
||||
status += LengthDoubleToString( (double) m_settings.m_targetSkew, false );
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ class PNS_ROUTER_BASE;
|
|||
class PNS_MEANDER_SKEW_PLACER : public PNS_MEANDER_PLACER
|
||||
{
|
||||
public:
|
||||
|
||||
PNS_MEANDER_SKEW_PLACER( PNS_ROUTER* aRouter );
|
||||
~PNS_MEANDER_SKEW_PLACER();
|
||||
|
||||
|
@ -51,13 +50,13 @@ public:
|
|||
const wxString TuningInfo() const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
int currentSkew( ) const;
|
||||
int itemsetLength( const PNS_ITEMSET& aSet ) const;
|
||||
|
||||
int origPathLength () const;
|
||||
|
||||
PNS_DIFF_PAIR m_originPair;
|
||||
PNS_DIFF_PAIR m_originPair;
|
||||
PNS_ITEMSET m_tunedPath, m_tunedPathP, m_tunedPathN;
|
||||
|
||||
int m_coupledLength;
|
||||
|
|
|
@ -64,7 +64,7 @@ PNS_NODE::PNS_NODE()
|
|||
PNS_NODE::~PNS_NODE()
|
||||
{
|
||||
TRACE( 0, "PNS_NODE::delete %p", this );
|
||||
|
||||
|
||||
if( !m_children.empty() )
|
||||
{
|
||||
TRACEn( 0, "attempting to free a node that has kids.\n" );
|
||||
|
@ -103,7 +103,7 @@ PNS_NODE* PNS_NODE::Branch()
|
|||
PNS_NODE* child = new PNS_NODE;
|
||||
|
||||
TRACE( 0, "PNS_NODE::branch %p (parent %p)", child % this );
|
||||
|
||||
|
||||
m_children.push_back( child );
|
||||
|
||||
child->m_depth = m_depth + 1;
|
||||
|
@ -175,8 +175,8 @@ struct PNS_NODE::OBSTACLE_VISITOR
|
|||
///> number of items found so far
|
||||
int m_matchCount;
|
||||
|
||||
///> additional clearance
|
||||
int m_extraClearance;
|
||||
///> additional clearance
|
||||
int m_extraClearance;
|
||||
|
||||
OBSTACLE_VISITOR( PNS_NODE::OBSTACLES& aTab, const PNS_ITEM* aItem, int aKindMask ) :
|
||||
m_tab( aTab ),
|
||||
|
@ -184,11 +184,11 @@ struct PNS_NODE::OBSTACLE_VISITOR
|
|||
m_kindMask( aKindMask ),
|
||||
m_limitCount( -1 ),
|
||||
m_matchCount( 0 ),
|
||||
m_extraClearance( 0 )
|
||||
m_extraClearance( 0 )
|
||||
{
|
||||
if( aItem->Kind() == PNS_ITEM::LINE )
|
||||
if( aItem->Kind() == PNS_ITEM::LINE )
|
||||
m_extraClearance += static_cast<const PNS_LINE*>( aItem )->Width() / 2;
|
||||
}
|
||||
}
|
||||
|
||||
void SetCountLimit( int aLimit )
|
||||
{
|
||||
|
@ -429,7 +429,7 @@ bool PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB, i
|
|||
else
|
||||
clearance = GetClearance( aItemA, aItemB );
|
||||
|
||||
// fixme: refactor
|
||||
// fixme: refactor
|
||||
if( aItemA->Kind() == PNS_ITEM::LINE )
|
||||
clearance += static_cast<const PNS_LINE*>( aItemA )->Width() / 2;
|
||||
if( aItemB->Kind() == PNS_ITEM::LINE )
|
||||
|
@ -533,7 +533,7 @@ void PNS_NODE::addLine( PNS_LINE* aLine, bool aAllowRedundant )
|
|||
|
||||
m_index->Add( pseg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,7 +548,7 @@ void PNS_NODE::addSegment( PNS_SEGMENT* aSeg, bool aAllowRedundant )
|
|||
|
||||
if( !aAllowRedundant && findRedundantSegment ( aSeg ) )
|
||||
return;
|
||||
|
||||
|
||||
aSeg->SetOwner( this );
|
||||
|
||||
linkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg );
|
||||
|
@ -619,13 +619,13 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
|
|||
{
|
||||
std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments();
|
||||
|
||||
if(! aLine->SegmentCount() )
|
||||
if( !aLine->SegmentCount() )
|
||||
return;
|
||||
|
||||
assert (segRefs != NULL);
|
||||
assert (aLine->Owner());
|
||||
|
||||
if ( (int) segRefs->size() != aLine->SegmentCount() )
|
||||
assert( segRefs != NULL );
|
||||
assert( aLine->Owner() );
|
||||
|
||||
if( (int) segRefs->size() != aLine->SegmentCount() )
|
||||
{
|
||||
//printf("******weird deletion: segrefs %d segcount %d hasloops %d\n", segRefs->size(), aLine->SegmentCount(), aLine->HasLoops());
|
||||
}
|
||||
|
@ -657,7 +657,7 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
|
|||
tag.net = net;
|
||||
tag.pos = p;
|
||||
|
||||
bool split;
|
||||
bool split;
|
||||
do
|
||||
{
|
||||
split = false;
|
||||
|
@ -678,7 +678,7 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
|
|||
}
|
||||
}
|
||||
} while( split );
|
||||
|
||||
|
||||
// and re-link them, using the former via's link list
|
||||
BOOST_FOREACH(PNS_ITEM* item, links)
|
||||
{
|
||||
|
@ -686,7 +686,7 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
|
|||
linkJoint ( p, item->Layers(), net, item );
|
||||
}
|
||||
|
||||
doRemove( aVia );
|
||||
doRemove( aVia );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -754,7 +755,7 @@ void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos
|
|||
}
|
||||
|
||||
aSegments[aPos] = aCurrent;
|
||||
|
||||
|
||||
aPos += ( aScanDirection ? 1 : -1 );
|
||||
|
||||
if( !jt->IsLineCorner() || aPos < 0 || aPos == aLimit )
|
||||
|
@ -763,7 +764,7 @@ void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos
|
|||
aCurrent = jt->NextSegment( aCurrent );
|
||||
|
||||
prevReversed =
|
||||
( jt->Pos() == (aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) );
|
||||
( jt->Pos() == ( aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -786,10 +787,10 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
|
|||
pl->SetOwner( this );
|
||||
|
||||
followLine( aSeg, false, i_start, MaxVerts, corners, segs, guardHit );
|
||||
|
||||
|
||||
if( !guardHit )
|
||||
followLine( aSeg, true, i_end, MaxVerts, corners, segs, guardHit );
|
||||
|
||||
|
||||
int n = 0;
|
||||
|
||||
PNS_SEGMENT* prev_seg = NULL;
|
||||
|
@ -799,7 +800,7 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
|
|||
const VECTOR2I& p = corners[i];
|
||||
|
||||
pl->Line().Append( p );
|
||||
|
||||
|
||||
if( segs[i] && prev_seg != segs[i] )
|
||||
{
|
||||
pl->LinkSegment( segs[i] );
|
||||
|
@ -815,7 +816,7 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
|
|||
|
||||
assert( pl->SegmentCount() != 0 );
|
||||
assert( pl->SegmentCount() == (int) pl->LinkedSegments()->size() );
|
||||
|
||||
|
||||
return pl;
|
||||
}
|
||||
|
||||
|
@ -855,7 +856,7 @@ void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFo
|
|||
processed.insert( next );
|
||||
searchQueue.push_back( next );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -865,8 +866,6 @@ void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFo
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<PNS_LINE*>& aLines )
|
||||
{
|
||||
BOOST_FOREACH( PNS_ITEM* item, aA.LinkList() )
|
||||
|
@ -877,7 +876,7 @@ int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<
|
|||
PNS_LINE* line = AssembleLine( seg );
|
||||
|
||||
PNS_JOINT j_start, j_end;
|
||||
|
||||
|
||||
FindLineEnds( line, j_start, j_end );
|
||||
|
||||
int id_start = line->CLine().Find( aA.Pos() );
|
||||
|
@ -1020,13 +1019,13 @@ void PNS_NODE::Dump( bool aLong )
|
|||
}
|
||||
|
||||
if( !isRoot() )
|
||||
{
|
||||
{
|
||||
for( i = m_root->m_items.begin(); i != m_root->m_items.end(); i++ )
|
||||
{
|
||||
if( (*i)->GetKind() == PNS_ITEM::SEGMENT && !overrides( *i ) )
|
||||
all_segs.insert( static_cast<PNS_SEGMENT*>(*i) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JOINT_MAP::iterator j;
|
||||
|
||||
|
@ -1153,7 +1152,7 @@ void PNS_NODE::AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems )
|
|||
BOOST_FOREACH( PNS_ITEM*item, *l_cur )
|
||||
aItems.insert( item );
|
||||
}
|
||||
|
||||
|
||||
if( !isRoot() )
|
||||
{
|
||||
PNS_INDEX::NET_ITEMS_LIST* l_root = m_root->m_index->GetItemsForNet( aNet );
|
||||
|
@ -1201,7 +1200,7 @@ int PNS_NODE::RemoveByMarker( int aMarker )
|
|||
}
|
||||
|
||||
for( std::list<PNS_ITEM*>::const_iterator i = garbage.begin(), end = garbage.end(); i != end; ++i )
|
||||
{
|
||||
{
|
||||
Remove( *i );
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -1221,23 +1220,23 @@ PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg )
|
|||
if( item->OfKind( PNS_ITEM::SEGMENT ) )
|
||||
{
|
||||
PNS_SEGMENT* seg2 = (PNS_SEGMENT*) item;
|
||||
|
||||
|
||||
const VECTOR2I a1( aSeg->Seg().A );
|
||||
const VECTOR2I b1( aSeg->Seg().B );
|
||||
|
||||
|
||||
const VECTOR2I a2( seg2->Seg().A );
|
||||
const VECTOR2I b2( seg2->Seg().B );
|
||||
|
||||
if( seg2->Layers().Start() == aSeg->Layers().Start() &&
|
||||
|
||||
if( seg2->Layers().Start() == aSeg->Layers().Start() &&
|
||||
( ( a1 == a2 && b1 == b2 ) || ( a1 == b2 && a2 == b1 ) ) )
|
||||
return seg2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PNS_NODE::SetCollisionFilter ( PNS_COLLISION_FILTER *aFilter )
|
||||
void PNS_NODE::SetCollisionFilter( PNS_COLLISION_FILTER* aFilter )
|
||||
{
|
||||
m_collisionFilter = aFilter;
|
||||
}
|
||||
|
|
|
@ -55,10 +55,9 @@ public:
|
|||
virtual ~PNS_CLEARANCE_FUNC() {}
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
class PNS_PCBNEW_CLEARANCE_FUNC : public PNS_CLEARANCE_FUNC
|
||||
class PNS_PCBNEW_CLEARANCE_FUNC : public PNS_CLEARANCE_FUNC
|
||||
{
|
||||
public:
|
||||
PNS_PCBNEW_CLEARANCE_FUNC( BOARD *aBoard );
|
||||
|
@ -297,7 +296,7 @@ public:
|
|||
* @param aOriginSegmentIndex index of aSeg in the resulting 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
|
||||
void Dump( bool aLong = false );
|
||||
|
@ -365,7 +364,7 @@ public:
|
|||
|
||||
int FindByMarker( int aMarker, PNS_ITEMSET& aItems );
|
||||
int RemoveByMarker( int aMarker );
|
||||
void SetCollisionFilter ( PNS_COLLISION_FILTER *aFilter );
|
||||
void SetCollisionFilter( PNS_COLLISION_FILTER* aFilter );
|
||||
|
||||
private:
|
||||
struct OBSTACLE_VISITOR;
|
||||
|
|
|
@ -101,14 +101,14 @@ void PNS_COST_ESTIMATOR::Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine )
|
|||
|
||||
|
||||
bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
|
||||
double aLengthTollerance,
|
||||
double aCornerTollerance ) const
|
||||
double aLengthTolerance,
|
||||
double aCornerTolerance ) const
|
||||
{
|
||||
if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost )
|
||||
return true;
|
||||
|
||||
else if( aOther.m_cornerCost < m_cornerCost * aCornerTollerance &&
|
||||
aOther.m_lengthCost < m_lengthCost * aLengthTollerance )
|
||||
else if( aOther.m_cornerCost < m_cornerCost * aCornerTolerance &&
|
||||
aOther.m_lengthCost < m_lengthCost * aLengthTolerance )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -224,27 +224,26 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
|
|||
}
|
||||
}
|
||||
|
||||
class LINE_RESTRICTIONS
|
||||
|
||||
class LINE_RESTRICTIONS
|
||||
{
|
||||
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 );
|
||||
void Dump();
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
RVERTEX ( bool aRestricted, int aAllowedAngles ) :
|
||||
restricted ( aRestricted ),
|
||||
allowedAngles ( aAllowedAngles )
|
||||
RVERTEX ( bool aRestricted, int aAllowedAngles ) :
|
||||
restricted( aRestricted ),
|
||||
allowedAngles( aAllowedAngles )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool restricted;
|
||||
|
@ -254,55 +253,54 @@ class LINE_RESTRICTIONS
|
|||
std::vector<RVERTEX> m_rs;
|
||||
};
|
||||
|
||||
|
||||
// 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 );
|
||||
|
||||
if( !jt )
|
||||
return 0xff;
|
||||
|
||||
|
||||
DIRECTION_45 dirs [8];
|
||||
|
||||
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;
|
||||
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();
|
||||
if (s.A != aP)
|
||||
if( s.A != aP )
|
||||
s.Reverse();
|
||||
|
||||
if (n_dirs < 8)
|
||||
dirs [ n_dirs++ ] = aFirst ? DIRECTION_45 ( s ) : DIRECTION_45 ( s ).Opposite();
|
||||
if( n_dirs < 8 )
|
||||
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;
|
||||
int outputMask = 0xff;
|
||||
|
||||
for (int d = 0; d < 8; d ++)
|
||||
|
||||
for( int d = 0; d < 8; d++ )
|
||||
{
|
||||
DIRECTION_45 refDir( (DIRECTION_45::Directions) d );
|
||||
for (int i = 0; i < n_dirs; i++ )
|
||||
DIRECTION_45 refDir( ( DIRECTION_45::Directions ) d );
|
||||
|
||||
for( int i = 0; i < n_dirs; i++ )
|
||||
{
|
||||
if (! (refDir.Angle(dirs [ i ] ) & angleMask) )
|
||||
if( !(refDir.Angle( dirs[i] ) & angleMask ) )
|
||||
outputMask &= ~refDir.Mask();
|
||||
}
|
||||
}
|
||||
|
||||
DrawDebugDirs ( aP, outputMask, 3 );
|
||||
DrawDebugDirs( aP, outputMask, 3 );
|
||||
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;
|
||||
VECTOR2I v_prev;
|
||||
|
@ -310,49 +308,56 @@ void LINE_RESTRICTIONS::Build( PNS_NODE *aWorld, PNS_LINE *aOriginLine, const SH
|
|||
|
||||
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;
|
||||
RVERTEX r ( false, 0xff );
|
||||
const VECTOR2I &v = l.CPoint( i ), v_next;
|
||||
RVERTEX r( false, 0xff );
|
||||
|
||||
if ( aRestrictedAreaEnable )
|
||||
if( aRestrictedAreaEnable )
|
||||
{
|
||||
bool exiting = ( i > 0 && aRestrictedArea.Contains( v_prev ) && !aRestrictedArea.Contains(v) );
|
||||
bool entering = false;
|
||||
bool exiting = ( i > 0 && aRestrictedArea.Contains( v_prev ) && !aRestrictedArea.Contains( v ) );
|
||||
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 ) );
|
||||
}
|
||||
|
||||
if(entering)
|
||||
if( entering )
|
||||
{
|
||||
const SEG& sp = l.CSegment(i);
|
||||
r.allowedAngles = DIRECTION_45(sp).Mask();
|
||||
} else if (exiting) {
|
||||
const SEG& sp = l.CSegment(i - 1);
|
||||
r.allowedAngles = DIRECTION_45(sp).Mask();
|
||||
} else {
|
||||
r.allowedAngles = (! aRestrictedArea.Contains ( v ) ) ? 0 : 0xff;
|
||||
const SEG& sp = l.CSegment( i );
|
||||
r.allowedAngles = DIRECTION_45( sp ).Mask();
|
||||
}
|
||||
else if( exiting )
|
||||
{
|
||||
const SEG& sp = l.CSegment( i - 1 );
|
||||
r.allowedAngles = DIRECTION_45( sp ).Mask();
|
||||
}
|
||||
else
|
||||
{
|
||||
r.allowedAngles = ( !aRestrictedArea.Contains( v ) ) ? 0 : 0xff;
|
||||
r.restricted = r.allowedAngles ? false : true;
|
||||
}
|
||||
}
|
||||
|
||||
v_prev = v;
|
||||
m_rs.push_back(r);
|
||||
m_rs.push_back( r );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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( ) )
|
||||
return true;
|
||||
|
||||
for(int i = aVertex1; i <= aVertex2; i++)
|
||||
|
||||
for( int i = aVertex1; i <= aVertex2; i++ )
|
||||
if ( m_rs[i].restricted )
|
||||
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 m2;
|
||||
if (aReplacement.SegmentCount() == 1)
|
||||
|
||||
if( aReplacement.SegmentCount() == 1 )
|
||||
m2 = m1;
|
||||
else
|
||||
m2 = DIRECTION_45 ( aReplacement.CSegment( 1 ) ).Mask();
|
||||
m2 = DIRECTION_45( aReplacement.CSegment( 1 ) ).Mask();
|
||||
|
||||
|
||||
return ((v1.allowedAngles & m1) != 0) &&
|
||||
((v2.allowedAngles & m2) != 0);
|
||||
return ( ( v1.allowedAngles & m1 ) != 0 ) &&
|
||||
( ( v2.allowedAngles & m2 ) != 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
|
||||
{
|
||||
CACHE_VISITOR v( aItem, m_world, m_collisionKindMask );
|
||||
|
@ -464,7 +468,6 @@ bool PNS_OPTIMIZER::mergeObtuse( PNS_LINE* aLine )
|
|||
s2opt = SEG( ip, s2.B );
|
||||
}
|
||||
|
||||
|
||||
if( DIRECTION_45( s1opt ).IsObtuse( DIRECTION_45( s2opt ) ) )
|
||||
{
|
||||
SHAPE_LINE_CHAIN opt_path;
|
||||
|
@ -802,7 +805,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
|
|||
|
||||
if(!connect.SegmentCount())
|
||||
continue;
|
||||
|
||||
|
||||
int ang1 = dir_bkout.Angle( DIRECTION_45( connect.CSegment( 0 ) ) );
|
||||
int ang2 = 0;
|
||||
|
||||
|
@ -872,7 +875,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
|
|||
bool PNS_OPTIMIZER::runSmartPads( PNS_LINE* aLine )
|
||||
{
|
||||
SHAPE_LINE_CHAIN& line = aLine->Line();
|
||||
|
||||
|
||||
if( line.PointCount() < 3 )
|
||||
return false;
|
||||
|
||||
|
@ -916,25 +919,27 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE* aLine )
|
|||
PNS_ITEM* startPad = findPadOrVia( aLine->Layer(), aLine->Net(), p_start );
|
||||
PNS_ITEM* endPad = findPadOrVia( aLine->Layer(), aLine->Net(), p_end );
|
||||
|
||||
int thr = aLine->Width() * 10;
|
||||
int thr = aLine->Width() * 10;
|
||||
int len = aLine->CLine().Length();
|
||||
|
||||
if( !startPad )
|
||||
return false;
|
||||
|
||||
bool startMatch = startPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
|
||||
bool endMatch = false;
|
||||
bool endMatch = false;
|
||||
|
||||
if(endPad)
|
||||
{
|
||||
endMatch = endPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
endMatch = aLine->EndsWithVia();
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
PNS_LINE repl;
|
||||
|
@ -951,97 +956,103 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE* aLine )
|
|||
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++ )
|
||||
{
|
||||
SEG s = aCoupled.CSegment(i);
|
||||
SEG s = aCoupled.CSegment( i );
|
||||
VECTOR2I projOverCoupled = s.LineProject ( aVertex );
|
||||
|
||||
|
||||
if( s.ApproxParallel ( aOrigSeg ) )
|
||||
{
|
||||
int64_t dist = ( projOverCoupled - aVertex ).EuclideanNorm() - aPair->Width();
|
||||
|
||||
if( aPair->GapConstraint().Matches(dist) )
|
||||
|
||||
if( aPair->GapConstraint().Matches( dist ) )
|
||||
{
|
||||
*aIndices++ = i;
|
||||
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 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;
|
||||
|
||||
if ( aNode->CheckColliding ( &refLine ) )
|
||||
if( aNode->CheckColliding ( &refLine ) )
|
||||
return false;
|
||||
|
||||
if ( aNode->CheckColliding ( &coupledLine ) )
|
||||
if( aNode->CheckColliding ( &coupledLine ) )
|
||||
return false;
|
||||
|
||||
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 nStarts = findCoupledVertices ( aRefBypass.CPoint(0), aRefBypass.CSegment(0), aCoupled, aPair, vStartIdx );
|
||||
DIRECTION_45 dir( aRefBypass.CSegment(0) );
|
||||
|
||||
int nStarts = findCoupledVertices( aRefBypass.CPoint( 0 ), aRefBypass.CSegment( 0 ), aCoupled, aPair, vStartIdx );
|
||||
DIRECTION_45 dir( aRefBypass.CSegment( 0 ) );
|
||||
|
||||
int64_t bestLength = -1;
|
||||
bool found = false;
|
||||
SHAPE_LINE_CHAIN bestBypass;
|
||||
int si, ei;
|
||||
|
||||
for(int i=0; i< nStarts ;i++)
|
||||
for ( int j = 1; j < aCoupled.PointCount() - 1; j++)
|
||||
for( int i=0; i< nStarts; i++ )
|
||||
{
|
||||
for( int j = 1; j < aCoupled.PointCount() - 1; j++ )
|
||||
{
|
||||
int delta = std::abs ( vStartIdx[i] - j );
|
||||
if(delta > 1)
|
||||
|
||||
if( delta > 1 )
|
||||
{
|
||||
const VECTOR2I& vs = aCoupled.CPoint( vStartIdx[i] );
|
||||
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;
|
||||
|
||||
si = vStartIdx[i];
|
||||
ei = j;
|
||||
|
||||
|
||||
if(si < ei)
|
||||
newCoupled.Replace( si, ei, bypass );
|
||||
else
|
||||
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;
|
||||
bestLength = coupledLength;
|
||||
bestLength = coupledLength;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(found)
|
||||
if( found )
|
||||
aNewCoupled = bestBypass;
|
||||
|
||||
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 );
|
||||
|
||||
|
@ -1049,16 +1060,16 @@ 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;
|
||||
|
||||
SHAPE_LINE_CHAIN currentPath = aTryP ? aPair->CP() : aPair->CN();
|
||||
SHAPE_LINE_CHAIN coupledPath = aTryP ? aPair->CN() : aPair->CP();
|
||||
|
||||
SHAPE_LINE_CHAIN currentPath = aTryP ? aPair->CP() : aPair->CN();
|
||||
SHAPE_LINE_CHAIN coupledPath = aTryP ? aPair->CN() : aPair->CP();
|
||||
|
||||
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...
|
||||
|
||||
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 s2 = currentPath.CSegment( n + step );
|
||||
|
||||
DIRECTION_45 dir1 (s1);
|
||||
DIRECTION_45 dir2 (s2);
|
||||
DIRECTION_45 dir1( s1 );
|
||||
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 newRef;
|
||||
SHAPE_LINE_CHAIN newCoup;
|
||||
int64_t deltaCoupled = -1, deltaUni = -1;
|
||||
|
||||
|
||||
newRef = currentPath;
|
||||
newRef.Replace( s1.Index(), s2.Index(), bypass );
|
||||
|
||||
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();
|
||||
newCoup.Simplify();
|
||||
|
||||
aPair->SetShape ( newRef, newCoup, !aTryP );
|
||||
aPair->SetShape( newRef, newCoup, !aTryP );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1100,18 +1110,19 @@ bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR *aPair, bool aTryP, int step )
|
|||
newRef.Simplify();
|
||||
coupledPath.Simplify();
|
||||
|
||||
aPair->SetShape ( newRef, coupledPath, !aTryP );
|
||||
aPair->SetShape( newRef, coupledPath, !aTryP );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
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_n = aPair->CN().SegmentCount() - 2;
|
||||
|
@ -1120,7 +1131,7 @@ bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR *aPair )
|
|||
{
|
||||
int n_segs_p = aPair->CP().SegmentCount();
|
||||
int n_segs_n = aPair->CN().SegmentCount();
|
||||
|
||||
|
||||
int max_step_p = n_segs_p - 2;
|
||||
int max_step_n = n_segs_n - 2;
|
||||
|
||||
|
@ -1136,12 +1147,12 @@ bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR *aPair )
|
|||
bool found_anything_p = false;
|
||||
bool found_anything_n = false;
|
||||
|
||||
if(step_p > 1)
|
||||
if( step_p > 1 )
|
||||
found_anything_p = mergeDpStep( aPair, true, step_p );
|
||||
|
||||
if(step_n > 1)
|
||||
if( step_n > 1 )
|
||||
found_anything_n = mergeDpStep( aPair, false, step_n );
|
||||
|
||||
|
||||
if( !found_anything_n && !found_anything_p )
|
||||
{
|
||||
step_n--;
|
||||
|
@ -1151,9 +1162,8 @@ bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR *aPair )
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_OPTIMIZER::Optimize( PNS_DIFF_PAIR* aPair )
|
||||
{
|
||||
|
||||
|
||||
return mergeDpSegments ( aPair );
|
||||
}
|
||||
return mergeDpSegments( aPair );
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public:
|
|||
void Remove( PNS_LINE& aLine );
|
||||
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 GetLengthCost() const { return m_lengthCost; }
|
||||
|
|
|
@ -34,7 +34,7 @@ class PNS_NODE;
|
|||
/**
|
||||
* Class PNS_PLACEMENT_ALGO
|
||||
*
|
||||
* Abstract class for a P&S placement/dragging algorithm.
|
||||
* Abstract class for a P&S placement/dragging algorithm.
|
||||
* All subtools (drag, single/diff pair routing and meandering)
|
||||
* are derived from it.
|
||||
*/
|
||||
|
@ -44,7 +44,7 @@ class PNS_PLACEMENT_ALGO : public PNS_ALGO_BASE
|
|||
public:
|
||||
PNS_PLACEMENT_ALGO( PNS_ROUTER* aRouter ) :
|
||||
PNS_ALGO_BASE( aRouter ) {};
|
||||
|
||||
|
||||
virtual ~PNS_PLACEMENT_ALGO () {};
|
||||
|
||||
/**
|
||||
|
@ -90,8 +90,8 @@ public:
|
|||
*
|
||||
* Returns true if the placer is placing a via (or more vias).
|
||||
*/
|
||||
virtual bool IsPlacingVia() const
|
||||
{
|
||||
virtual bool IsPlacingVia() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -119,14 +119,14 @@ public:
|
|||
* to the cursor position due to collisions.
|
||||
*/
|
||||
virtual const VECTOR2I& CurrentEnd() const = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Function CurrentNet()
|
||||
*
|
||||
* Returns the net code of currently routed track.
|
||||
*/
|
||||
virtual int CurrentNet() const = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Function CurrentLayer()
|
||||
*
|
||||
|
@ -146,9 +146,8 @@ public:
|
|||
*
|
||||
* Toggles the current posture (straight/diagonal) of the trace head.
|
||||
*/
|
||||
virtual void FlipPosture()
|
||||
virtual void FlipPosture()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,19 +159,17 @@ public:
|
|||
*/
|
||||
virtual void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetOrthoMode()
|
||||
*
|
||||
*
|
||||
* Forces the router to place a straight 90/45 degree trace (with the end
|
||||
* as near to the cursor as possible) instead of a standard 135 degree
|
||||
* two-segment bend.
|
||||
*/
|
||||
virtual void SetOrthoMode ( bool aOrthoMode )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,9 +177,8 @@ public:
|
|||
*
|
||||
* Returns the net codes of all currently routed trace(s)
|
||||
*/
|
||||
virtual void GetModifiedNets( std::vector<int> &aNets ) const
|
||||
virtual void GetModifiedNets( std::vector<int> &aNets ) const
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -49,8 +49,6 @@
|
|||
#include "pns_meander_skew_placer.h"
|
||||
#include "pns_dp_meander_placer.h"
|
||||
|
||||
|
||||
|
||||
#include <router/router_preview_item.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();
|
||||
}
|
||||
|
||||
|
||||
PNS_PCBNEW_CLEARANCE_FUNC::~PNS_PCBNEW_CLEARANCE_FUNC()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int PNS_PCBNEW_CLEARANCE_FUNC::localPadClearance( const PNS_ITEM* aItem ) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
int PNS_PCBNEW_CLEARANCE_FUNC::operator()( const PNS_ITEM* aA, const PNS_ITEM* aB )
|
||||
{
|
||||
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 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 )
|
||||
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 );
|
||||
|
||||
return std::max( cl_a, cl_b );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// 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_overrideNetA = aNetA;
|
||||
|
@ -249,6 +250,7 @@ PNS_ITEM* PNS_ROUTER::syncTrack( TRACK* aTrack )
|
|||
|
||||
if( aTrack->GetFlags( ) & DP_COUPLED )
|
||||
s->Mark ( MK_DP_COUPLED );
|
||||
|
||||
s->SetWidth( aTrack->GetWidth() );
|
||||
s->SetLayers( PNS_LAYERSET( aTrack->GetLayer() ) );
|
||||
s->SetParent( aTrack );
|
||||
|
@ -280,6 +282,7 @@ void PNS_ROUTER::SetBoard( BOARD* aBoard )
|
|||
TRACE( 1, "m_board = %p\n", m_board );
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::SyncWorld()
|
||||
{
|
||||
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 )
|
||||
{
|
||||
switch (m_mode)
|
||||
switch( m_mode )
|
||||
{
|
||||
case PNS_MODE_ROUTE_SINGLE:
|
||||
m_placer = new PNS_LINE_PLACER( this );
|
||||
|
@ -505,7 +508,7 @@ bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLa
|
|||
case PNS_MODE_TUNE_DIFF_PAIR_SKEW:
|
||||
m_placer = new PNS_MEANDER_SKEW_PLACER( this );
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -513,9 +516,9 @@ bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLa
|
|||
m_placer->UpdateSizes ( m_sizes );
|
||||
m_placer->SetLayer( aLayer );
|
||||
|
||||
bool rv = m_placer->Start( aP, aStartItem );
|
||||
bool rv = m_placer->Start( aP, aStartItem );
|
||||
|
||||
if(!rv)
|
||||
if( !rv )
|
||||
return false;
|
||||
|
||||
m_currentEnd = aP;
|
||||
|
@ -524,11 +527,13 @@ bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLa
|
|||
return rv;
|
||||
}
|
||||
|
||||
BOARD *PNS_ROUTER::GetBoard()
|
||||
|
||||
BOARD* PNS_ROUTER::GetBoard()
|
||||
{
|
||||
return m_board;
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::eraseView()
|
||||
{
|
||||
BOOST_FOREACH( BOARD_ITEM* item, m_hiddenItems )
|
||||
|
@ -710,22 +715,20 @@ void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
m_placer->Move( aP, aEndItem );
|
||||
PNS_ITEMSET current = m_placer->Traces();
|
||||
|
||||
|
||||
BOOST_FOREACH( const PNS_ITEM* item, current.CItems() )
|
||||
{
|
||||
if( !item->OfKind ( PNS_ITEM::LINE ) )
|
||||
if( !item->OfKind( PNS_ITEM::LINE ) )
|
||||
continue;
|
||||
|
||||
const PNS_LINE *l = static_cast <const PNS_LINE *> (item);
|
||||
DisplayItem(l);
|
||||
|
||||
const PNS_LINE* l = static_cast <const PNS_LINE*> (item);
|
||||
DisplayItem( l );
|
||||
|
||||
if( l->EndsWithVia() )
|
||||
DisplayItem( &l->Via() );
|
||||
}
|
||||
|
||||
|
||||
//PNS_ITEMSET tmp( ¤t );
|
||||
|
||||
|
||||
updateView( m_placer->CurrentNode( true ), current );
|
||||
}
|
||||
|
||||
|
@ -844,7 +847,6 @@ void PNS_ROUTER::StopRouting()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if( !RoutingInProgress() )
|
||||
return;
|
||||
|
||||
|
@ -890,9 +892,9 @@ void PNS_ROUTER::SwitchLayer( int aLayer )
|
|||
|
||||
void PNS_ROUTER::ToggleViaPlacement()
|
||||
{
|
||||
if( m_state == ROUTE_TRACK )
|
||||
if( m_state == ROUTE_TRACK )
|
||||
{
|
||||
bool toggle = !m_placer->IsPlacingVia();
|
||||
bool toggle = !m_placer->IsPlacingVia();
|
||||
m_placer->ToggleVia( toggle );
|
||||
}
|
||||
}
|
||||
|
@ -932,24 +934,26 @@ void PNS_ROUTER::DumpLog()
|
|||
logger->Save( "/tmp/shove.log" );
|
||||
}
|
||||
|
||||
|
||||
bool PNS_ROUTER::IsPlacingVia() const
|
||||
{
|
||||
if(!m_placer)
|
||||
if( !m_placer )
|
||||
return NULL;
|
||||
|
||||
return m_placer->IsPlacingVia();
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::SetOrthoMode( bool aEnable )
|
||||
{
|
||||
if(!m_placer)
|
||||
if( !m_placer )
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -277,7 +277,6 @@ private:
|
|||
|
||||
wxString m_toolStatusbarName;
|
||||
wxString m_failureReason;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -137,7 +137,6 @@ private:
|
|||
PNS_MODE m_routingMode;
|
||||
PNS_OPTIMIZATION_EFFORT m_optimizerEffort;
|
||||
|
||||
|
||||
int m_walkaroundIterationLimit;
|
||||
int m_shoveIterationLimit;
|
||||
TIME_LIMIT m_shoveTimeLimit;
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
}
|
||||
|
||||
PNS_SEGMENT( const PNS_LINE& aParentLine, const SEG& aSeg ) :
|
||||
PNS_ITEM( SEGMENT ),
|
||||
PNS_ITEM( SEGMENT ),
|
||||
m_seg( aSeg, aParentLine.Width() )
|
||||
{
|
||||
m_net = aParentLine.Net();
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
{
|
||||
return aItem && SEGMENT == aItem->Kind();
|
||||
}
|
||||
|
||||
|
||||
PNS_SEGMENT* Clone( ) const;
|
||||
|
||||
const SHAPE* Shape() const
|
||||
|
@ -100,7 +100,7 @@ public:
|
|||
void SetEnds( const VECTOR2I& a, const VECTOR2I& b )
|
||||
{
|
||||
m_seg.SetSeg( SEG ( a, b ) );
|
||||
}
|
||||
}
|
||||
|
||||
void SwapEnds()
|
||||
{
|
||||
|
@ -110,7 +110,7 @@ public:
|
|||
|
||||
const SHAPE_LINE_CHAIN Hull( int aClearance, int aWalkaroundThickness ) const;
|
||||
|
||||
virtual VECTOR2I Anchor(int n) const
|
||||
virtual VECTOR2I Anchor(int n) const
|
||||
{
|
||||
if( n == 0 )
|
||||
return m_seg.GetSeg().A;
|
||||
|
@ -118,9 +118,9 @@ public:
|
|||
return m_seg.GetSeg().B;
|
||||
}
|
||||
|
||||
virtual int AnchorCount() const
|
||||
virtual int AnchorCount() const
|
||||
{
|
||||
return 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -42,14 +42,13 @@
|
|||
|
||||
#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 );
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
if(m_forceClearance >= 0)
|
||||
if( m_forceClearance >= 0 )
|
||||
return m_forceClearance;
|
||||
|
||||
return m_currentNode->GetClearance( aA, aB );
|
||||
}
|
||||
|
||||
|
||||
static void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew )
|
||||
{
|
||||
assert( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) );
|
||||
|
@ -99,6 +99,7 @@ PNS_LINE* PNS_SHOVE::assembleLine( const PNS_SEGMENT* aSeg, int* aIndex )
|
|||
return l;
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
// 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 );
|
||||
|
||||
assert ( obstacleLine->LayersOverlap( shovedLine ) );
|
||||
assert( obstacleLine->LayersOverlap( shovedLine ) );
|
||||
|
||||
if( rv == SH_OK )
|
||||
{
|
||||
|
@ -319,7 +320,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSegment( PNS_LINE* aCurrent, PNS_S
|
|||
{
|
||||
if( m_multiLineMode )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
|
||||
m_newHead = *shovedLine;
|
||||
}
|
||||
|
||||
|
@ -351,13 +352,11 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE* aCurrent, PNS_LINE
|
|||
|
||||
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine );
|
||||
|
||||
|
||||
|
||||
if( rv == SH_OK )
|
||||
{
|
||||
if( shovedLine->Marker() & MK_HEAD )
|
||||
{
|
||||
if (m_multiLineMode)
|
||||
if( m_multiLineMode )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
m_newHead = *shovedLine;
|
||||
|
@ -444,7 +443,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE* aCurrent, PNS_SOL
|
|||
{
|
||||
walkaroundLine->Mark( MK_HEAD );
|
||||
|
||||
if(m_multiLineMode)
|
||||
if(m_multiLineMode)
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
m_newHead = *walkaroundLine;
|
||||
|
@ -481,7 +480,7 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
|
|||
|
||||
delete spTag.m_node;
|
||||
m_nodeStack.pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
@ -496,10 +495,9 @@ bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
|
|||
SPRINGBACK_TAG st;
|
||||
OPT_BOX2I prev_area;
|
||||
|
||||
if(!m_nodeStack.empty())
|
||||
if( !m_nodeStack.empty() )
|
||||
prev_area = m_nodeStack.back().m_affectedArea;
|
||||
|
||||
|
||||
st.m_node = aNode;
|
||||
st.m_cost = aCost;
|
||||
st.m_headItems = aHeadItems;
|
||||
|
@ -522,20 +520,20 @@ 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 )
|
||||
{
|
||||
LINE_PAIR_VEC draggedLines;
|
||||
VECTOR2I p0 ( aVia->Pos() );
|
||||
VECTOR2I p0( aVia->Pos() );
|
||||
PNS_JOINT* jt = m_currentNode->FindJoint( p0, aVia );
|
||||
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;
|
||||
|
||||
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();
|
||||
pushedVia->SetPos( p0_pushed );
|
||||
pushedVia->Mark( aVia->Marker() );
|
||||
|
@ -554,7 +552,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
|
||||
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;
|
||||
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->ClearSegmentLinks();
|
||||
lp.second->DragCorner( p0_pushed, lp.second->CLine().Find( p0 ) );
|
||||
lp.second->AppendVia ( *pushedVia );
|
||||
lp.second->AppendVia( *pushedVia );
|
||||
draggedLines.push_back( lp );
|
||||
|
||||
if (aVia->Marker() & MK_HEAD )
|
||||
m_draggedViaHeadSet.Add ( clone ( lp.second ) );
|
||||
|
||||
if( aVia->Marker() & MK_HEAD )
|
||||
m_draggedViaHeadSet.Add( clone ( lp.second ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -584,9 +581,9 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
return SH_OK;
|
||||
|
||||
replaceItems ( aVia, pushedVia );
|
||||
|
||||
|
||||
if( aVia->BelongsTo( m_currentNode ) )
|
||||
delete aVia;
|
||||
delete aVia;
|
||||
|
||||
pushedVia->SetRank( aCurrentRank - 1 );
|
||||
|
||||
|
@ -600,7 +597,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
if( lp.first->Marker() & MK_HEAD )
|
||||
{
|
||||
lp.second->Mark( MK_HEAD );
|
||||
|
||||
|
||||
if ( m_multiLineMode )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
|
@ -955,11 +952,12 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveMainLoop()
|
|||
return st;
|
||||
}
|
||||
|
||||
OPT_BOX2I PNS_SHOVE::totalAffectedArea ( ) const
|
||||
|
||||
OPT_BOX2I PNS_SHOVE::totalAffectedArea() const
|
||||
{
|
||||
OPT_BOX2I area;
|
||||
if(!m_nodeStack.empty())
|
||||
area = m_nodeStack.back().m_affectedArea;
|
||||
if( !m_nodeStack.empty() )
|
||||
area = m_nodeStack.back().m_affectedArea;
|
||||
|
||||
if( area )
|
||||
{
|
||||
|
@ -977,7 +975,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
|||
SHOVE_STATUS st = SH_OK;
|
||||
|
||||
m_multiLineMode = false;
|
||||
|
||||
|
||||
// empty head? nothing to shove...
|
||||
if( !aCurrentHead.SegmentCount() )
|
||||
return SH_INCOMPLETE;
|
||||
|
@ -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 )
|
||||
{
|
||||
SHOVE_STATUS st = SH_OK;
|
||||
|
@ -1056,22 +1053,21 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
|
|||
|
||||
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...
|
||||
if( !headOrig->SegmentCount() )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
headSet.Add ( clone ( headOrig ) );
|
||||
}
|
||||
|
||||
headSet.Add( clone( headOrig ) );
|
||||
}
|
||||
|
||||
m_lineStack.clear();
|
||||
m_optimizerQueue.clear();
|
||||
m_logger.Clear();
|
||||
|
||||
|
||||
reduceSpringback( headSet );
|
||||
|
||||
PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||
|
@ -1079,12 +1075,12 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
|
|||
m_currentNode = parent->Branch();
|
||||
m_currentNode->ClearRanks();
|
||||
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);
|
||||
PNS_LINE *head = clone ( headOrig );
|
||||
const PNS_LINE* headOrig = static_cast<const PNS_LINE*>( item );
|
||||
PNS_LINE* head = clone( headOrig );
|
||||
head->ClearSegmentLinks();
|
||||
|
||||
|
||||
m_currentNode->Add( head );
|
||||
|
||||
head->Mark( MK_HEAD );
|
||||
|
@ -1128,12 +1124,12 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
|
|||
return st;
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere,
|
||||
PNS_VIA** aNewVia )
|
||||
{
|
||||
SHOVE_STATUS st = SH_OK;
|
||||
|
||||
|
||||
m_lineStack.clear();
|
||||
m_optimizerQueue.clear();
|
||||
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 )
|
||||
{
|
||||
pushSpringback( m_currentNode, m_draggedViaHeadSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum);
|
||||
pushSpringback( m_currentNode, m_draggedViaHeadSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1193,9 +1189,9 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
|||
maxWidth = std::max ( (*i)->Width(), maxWidth );
|
||||
}
|
||||
|
||||
if(area)
|
||||
if( area )
|
||||
{
|
||||
area->Inflate ( 10 * maxWidth );
|
||||
area->Inflate( 10 * maxWidth );
|
||||
}
|
||||
|
||||
switch( effort )
|
||||
|
@ -1207,9 +1203,9 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
|||
|
||||
case OE_MEDIUM:
|
||||
optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS;
|
||||
|
||||
|
||||
if( area )
|
||||
optimizer.SetRestrictArea ( *area );
|
||||
optimizer.SetRestrictArea( *area );
|
||||
|
||||
n_passes = 2;
|
||||
break;
|
||||
|
@ -1223,7 +1219,6 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
if( Settings().SmartPads() )
|
||||
optFlags |= PNS_OPTIMIZER::SMART_PADS ;
|
||||
|
||||
|
@ -1254,6 +1249,7 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
PNS_NODE* PNS_SHOVE::CurrentNode()
|
||||
{
|
||||
return m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
SHOVE_STATUS ShoveMultiLines( const PNS_ITEMSET& aHeadSet );
|
||||
|
||||
SHOVE_STATUS ShoveDraggingVia( PNS_VIA*aVia, const VECTOR2I& aWhere, PNS_VIA** aNewVia );
|
||||
SHOVE_STATUS ProcessSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||
SHOVE_STATUS ProcessSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||
PNS_LINE* aShoved );
|
||||
|
||||
void ForceClearance ( bool aEnabled, int aClearance )
|
||||
|
@ -115,9 +115,8 @@ private:
|
|||
SHOVE_STATUS onReverseCollidingVia( PNS_LINE* aCurrent, PNS_VIA* aObstacleVia );
|
||||
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_ITEM* aItem );
|
||||
|
||||
|
@ -128,8 +127,8 @@ private:
|
|||
|
||||
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 )
|
||||
{
|
||||
T *cloned = aItem->Clone();
|
||||
|
@ -140,7 +139,6 @@ private:
|
|||
|
||||
OPT_BOX2I m_affectedAreaSum;
|
||||
|
||||
|
||||
SHOVE_STATUS shoveIteration( int aIter );
|
||||
SHOVE_STATUS shoveMainLoop();
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ int PNS_SIZES_SETTINGS::inheritTrackWidth( PNS_ITEM* aItem )
|
|||
return ( mval == INT_MAX ? 0 : mval );
|
||||
}
|
||||
|
||||
|
||||
void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet )
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
void PNS_SIZES_SETTINGS::ClearLayerPairs()
|
||||
{
|
||||
m_layerPairs.clear();
|
||||
}
|
||||
|
||||
|
||||
void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 )
|
||||
{
|
||||
int top = std::min( aL1, aL2 );
|
||||
|
@ -135,6 +138,7 @@ void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 )
|
|||
m_layerPairs[top] = bottom;
|
||||
}
|
||||
|
||||
|
||||
void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings )
|
||||
{
|
||||
m_trackWidth = aSettings.GetCurrentTrackWidth();
|
||||
|
@ -142,6 +146,7 @@ void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings )
|
|||
m_viaDrill = aSettings.GetCurrentViaDrill();
|
||||
}
|
||||
|
||||
|
||||
int PNS_SIZES_SETTINGS::GetLayerTop() const
|
||||
{
|
||||
if( m_layerPairs.empty() )
|
||||
|
@ -150,6 +155,7 @@ int PNS_SIZES_SETTINGS::GetLayerTop() const
|
|||
return m_layerPairs.begin()->first;
|
||||
}
|
||||
|
||||
|
||||
int PNS_SIZES_SETTINGS::GetLayerBottom() const
|
||||
{
|
||||
if( m_layerPairs.empty() )
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
~PNS_SIZES_SETTINGS() {};
|
||||
|
||||
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 AddLayerPair( int aL1, int aL2 );
|
||||
|
@ -57,12 +57,12 @@ public:
|
|||
|
||||
int DiffPairWidth() const { return m_diffPairWidth; }
|
||||
int DiffPairGap() const { return m_diffPairGap; }
|
||||
|
||||
int DiffPairViaGap() const {
|
||||
|
||||
int DiffPairViaGap() const {
|
||||
if(m_diffPairViaGapSameAsTraceGap)
|
||||
return m_diffPairGap;
|
||||
else
|
||||
return m_diffPairViaGap;
|
||||
return m_diffPairViaGap;
|
||||
}
|
||||
|
||||
bool DiffPairViaGapSameAsTraceGap() const { return m_diffPairViaGapSameAsTraceGap; }
|
||||
|
@ -83,7 +83,7 @@ public:
|
|||
if( m_layerPairs.find(aLayerId) == m_layerPairs.end() )
|
||||
return boost::optional<int>();
|
||||
|
||||
return m_layerPairs [ aLayerId ];
|
||||
return m_layerPairs[aLayerId];
|
||||
}
|
||||
|
||||
int GetLayerTop() const;
|
||||
|
|
|
@ -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 );
|
||||
return solid;
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
}
|
||||
|
||||
PNS_SOLID( const PNS_SOLID& aSolid ) :
|
||||
PNS_ITEM ( aSolid )
|
||||
PNS_ITEM( aSolid )
|
||||
{
|
||||
m_shape = aSolid.m_shape->Clone();
|
||||
m_pos = aSolid.m_pos;
|
||||
|
@ -53,7 +53,7 @@ public:
|
|||
{
|
||||
return aItem && SOLID == aItem->Kind();
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEM* Clone() const;
|
||||
|
||||
const SHAPE* Shape() const { return m_shape; }
|
||||
|
@ -83,7 +83,7 @@ public:
|
|||
return m_pos;
|
||||
}
|
||||
|
||||
virtual int AnchorCount() const
|
||||
virtual int AnchorCount() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ void PNS_TOOL_BASE::Reset( RESET_REASON aReason )
|
|||
m_router->SetView( getView() );
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEM* PNS_TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer )
|
||||
{
|
||||
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;
|
||||
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME> ();
|
||||
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
|
||||
DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)frame->GetDisplayOptions();
|
||||
|
||||
for( int i = 0; i < 4; i++ )
|
||||
|
@ -178,6 +179,7 @@ void PNS_TOOL_BASE::highlightNet( bool aEnabled, int aNetcode )
|
|||
getView()->UpdateAllLayersColor();
|
||||
}
|
||||
|
||||
|
||||
void PNS_TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent )
|
||||
{
|
||||
int tl = getView()->GetTopLayer();
|
||||
|
@ -187,7 +189,7 @@ void PNS_TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent )
|
|||
if( aEvent.IsMotion() || aEvent.IsClick() )
|
||||
{
|
||||
bool snapEnabled = !aEvent.Modifier( MD_SHIFT );
|
||||
|
||||
|
||||
VECTOR2I p( aEvent.Position() );
|
||||
startItem = pickSingleItem( p );
|
||||
m_router->EnableSnapping ( snapEnabled );
|
||||
|
@ -227,6 +229,7 @@ void PNS_TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_TOOL_BASE::updateEndItem( TOOL_EVENT& aEvent )
|
||||
{
|
||||
VECTOR2I mp = m_ctls->GetMousePosition();
|
||||
|
|
|
@ -49,7 +49,7 @@ protected:
|
|||
virtual void highlightNet( bool aEnabled, int aNetcode = -1 );
|
||||
virtual void updateStartItem( TOOL_EVENT& aEvent );
|
||||
virtual void updateEndItem( TOOL_EVENT& aEvent );
|
||||
|
||||
|
||||
MSG_PANEL_ITEMS m_panelItems;
|
||||
|
||||
PNS_ROUTER* m_router;
|
||||
|
@ -64,10 +64,10 @@ protected:
|
|||
|
||||
///> Flag marking that the router's world needs syncing.
|
||||
bool m_needsSync;
|
||||
|
||||
PCB_EDIT_FRAME *m_frame;
|
||||
KIGFX::VIEW_CONTROLS *m_ctls;
|
||||
BOARD *m_board;
|
||||
|
||||
PCB_EDIT_FRAME* m_frame;
|
||||
KIGFX::VIEW_CONTROLS* m_ctls;
|
||||
BOARD* m_board;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -30,31 +30,31 @@
|
|||
|
||||
#include <class_board.h>
|
||||
|
||||
bool PNS_TOPOLOGY::SimplifyLine ( PNS_LINE *aLine )
|
||||
bool PNS_TOPOLOGY::SimplifyLine( PNS_LINE* aLine )
|
||||
{
|
||||
|
||||
if( !aLine->LinkedSegments() || !aLine->SegmentCount() )
|
||||
return false;
|
||||
if( !aLine->LinkedSegments() || !aLine->SegmentCount() )
|
||||
return false;
|
||||
|
||||
PNS_SEGMENT *root = (*aLine->LinkedSegments())[0];
|
||||
std::auto_ptr<PNS_LINE> l ( m_world->AssembleLine( root ) );
|
||||
SHAPE_LINE_CHAIN simplified ( l->CLine() );
|
||||
PNS_SEGMENT* root = ( *aLine->LinkedSegments() )[0];
|
||||
std::auto_ptr<PNS_LINE> l( m_world->AssembleLine( root ) );
|
||||
SHAPE_LINE_CHAIN simplified( l->CLine() );
|
||||
|
||||
simplified.Simplify();
|
||||
|
||||
if( simplified.PointCount() != l->PointCount() )
|
||||
{
|
||||
std::auto_ptr<PNS_LINE> lnew ( l->Clone() );
|
||||
m_world -> Remove( l.get() );
|
||||
std::auto_ptr<PNS_LINE> lnew( l->Clone() );
|
||||
m_world->Remove( l.get() );
|
||||
lnew->SetShape( simplified );
|
||||
m_world -> Add( lnew.get() );
|
||||
m_world->Add( lnew.get() );
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
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() )
|
||||
{
|
||||
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* b = m_world->FindJoint( seg->Seg().B, seg );
|
||||
PNS_JOINT* next = ( *a == *current ) ? b : a;
|
||||
|
@ -81,7 +81,7 @@ const PNS_TOPOLOGY::JOINT_SET PNS_TOPOLOGY::ConnectedJoints ( PNS_JOINT* aStart
|
|||
processed.insert( next );
|
||||
searchQueue.push_back( next );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
if( !track.PointCount() )
|
||||
return false;
|
||||
|
||||
std::auto_ptr<PNS_NODE> tmpNode ( m_world->Branch() );
|
||||
std::auto_ptr<PNS_NODE> tmpNode( m_world->Branch() );
|
||||
tmpNode->Add( &track );
|
||||
|
||||
PNS_JOINT* jt = tmpNode->FindJoint( track.CPoint( -1 ), &track );
|
||||
|
||||
if ( !jt )
|
||||
if( !jt )
|
||||
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();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
int anchor;
|
||||
|
||||
PNS_TOPOLOGY topo ( tmpNode.get() );
|
||||
|
||||
PNS_TOPOLOGY topo( tmpNode.get() );
|
||||
PNS_ITEM* it = topo.NearestUnconnectedItem( jt, &anchor );
|
||||
|
||||
if( !it )
|
||||
|
@ -121,24 +123,24 @@ bool PNS_TOPOLOGY::LeadingRatLine( const PNS_LINE *aTrack, SHAPE_LINE_CHAIN& aRa
|
|||
}
|
||||
|
||||
aRatLine.Clear();
|
||||
aRatLine.Append ( track.CPoint( -1 ) );
|
||||
aRatLine.Append ( end );
|
||||
aRatLine.Append( track.CPoint( -1 ) );
|
||||
aRatLine.Append( end );
|
||||
return true;
|
||||
}
|
||||
|
||||
PNS_ITEM* PNS_TOPOLOGY::NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor, int aKindMask )
|
||||
{
|
||||
std::set<PNS_ITEM*> 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() )
|
||||
{
|
||||
if( disconnected.find( link ) != disconnected.end() )
|
||||
disconnected.erase( link );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int best_dist = INT_MAX;
|
||||
|
@ -148,7 +150,7 @@ PNS_ITEM* PNS_TOPOLOGY::NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor,
|
|||
{
|
||||
if( item->OfKind( aKindMask ) )
|
||||
{
|
||||
for(int i = 0; i < item->AnchorCount(); i++)
|
||||
for(int i = 0; i < item->AnchorCount(); i++)
|
||||
{
|
||||
VECTOR2I p = item->Anchor( i );
|
||||
int d = ( p - aStart->Pos() ).EuclideanNorm();
|
||||
|
@ -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);
|
||||
PNS_SEGMENT *last = aLeft ? aLine->LinkedSegments()->front() : aLine->LinkedSegments()->back();
|
||||
PNS_JOINT *jt = m_world->FindJoint ( anchor, aLine );
|
||||
VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
|
||||
PNS_SEGMENT* last = aLeft ? aLine->LinkedSegments()->front() : aLine->LinkedSegments()->back();
|
||||
PNS_JOINT* jt = m_world->FindJoint( anchor, aLine );
|
||||
|
||||
assert (jt != NULL);
|
||||
assert( jt != NULL );
|
||||
|
||||
aVisited.insert( last );
|
||||
|
||||
if( jt->IsNonFanoutVia() )
|
||||
{
|
||||
PNS_ITEM *via = NULL;
|
||||
PNS_SEGMENT *next_seg = NULL;
|
||||
|
||||
BOOST_FOREACH ( PNS_ITEM *link, jt->Links().Items() )
|
||||
PNS_ITEM* via = NULL;
|
||||
PNS_SEGMENT* next_seg = NULL;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* link, jt->Links().Items() )
|
||||
{
|
||||
if( link->OfKind ( PNS_ITEM::VIA ) )
|
||||
if( link->OfKind( PNS_ITEM::VIA ) )
|
||||
via = link;
|
||||
else if( aVisited.find(link) == aVisited.end() )
|
||||
next_seg = static_cast <PNS_SEGMENT *> (link);
|
||||
else if( aVisited.find( link ) == aVisited.end() )
|
||||
next_seg = static_cast<PNS_SEGMENT*>( link );
|
||||
}
|
||||
|
||||
if(!next_seg)
|
||||
|
||||
if( !next_seg )
|
||||
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) );
|
||||
|
||||
if (nextAnchor != anchor)
|
||||
VECTOR2I nextAnchor = ( aLeft ? l->CLine().CPoint( -1 ) : l->CLine().CPoint( 0 ) );
|
||||
|
||||
if( nextAnchor != anchor )
|
||||
{
|
||||
l->Reverse();
|
||||
}
|
||||
|
||||
if (aLeft)
|
||||
if( aLeft )
|
||||
{
|
||||
aSet.Prepend ( via );
|
||||
aSet.Prepend ( l );
|
||||
} else {
|
||||
aSet.Add ( via );
|
||||
aSet.Add ( l );
|
||||
aSet.Prepend( via );
|
||||
aSet.Prepend( l );
|
||||
}
|
||||
else
|
||||
{
|
||||
aSet.Add( via );
|
||||
aSet.Add( l );
|
||||
}
|
||||
|
||||
return followTrivialPath ( l, aLeft, aSet, aVisited );
|
||||
return followTrivialPath( l, aLeft, aSet, aVisited );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath ( PNS_SEGMENT *aStart )
|
||||
|
||||
const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath( PNS_SEGMENT* aStart )
|
||||
{
|
||||
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, true, path, visited );
|
||||
|
@ -233,39 +239,47 @@ const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath ( PNS_SEGMENT *aStart )
|
|||
return path;
|
||||
}
|
||||
|
||||
|
||||
const PNS_ITEMSET PNS_TOPOLOGY::ConnectedItems( PNS_JOINT* aStart, int aKindMask )
|
||||
{
|
||||
return PNS_ITEMSET();
|
||||
}
|
||||
|
||||
|
||||
const PNS_ITEMSET PNS_TOPOLOGY::ConnectedItems( PNS_ITEM* aStart, int aKindMask )
|
||||
{
|
||||
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;
|
||||
if (aNetName.EndsWith("+"))
|
||||
|
||||
if( aNetName.EndsWith( "+" ) )
|
||||
{
|
||||
aComplementNet = "-";
|
||||
rv = 1;
|
||||
} else if (aNetName.EndsWith("_P"))
|
||||
}
|
||||
else if( aNetName.EndsWith( "_P" ) )
|
||||
{
|
||||
aComplementNet = "_N";
|
||||
rv = 1;
|
||||
} else if (aNetName.EndsWith("-"))
|
||||
}
|
||||
else if( aNetName.EndsWith( "-" ) )
|
||||
{
|
||||
aComplementNet = "+";
|
||||
rv = -1;
|
||||
} else if (aNetName.EndsWith("_N"))
|
||||
}
|
||||
else if( aNetName.EndsWith( "_N" ) )
|
||||
{
|
||||
aComplementNet = "_P";
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
if (rv != 0) {
|
||||
aBaseDpName = aNetName.Left ( aNetName.Length() - aComplementNet.Length() );
|
||||
if( rv != 0 )
|
||||
{
|
||||
aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
|
||||
aComplementNet = aBaseDpName + aComplementNet;
|
||||
}
|
||||
|
||||
|
@ -275,16 +289,16 @@ int PNS_TOPOLOGY::MatchDpSuffix ( wxString aNetName, wxString& aComplementNet, w
|
|||
|
||||
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;
|
||||
|
||||
if ( MatchDpSuffix ( refName, coupledNetName, dummy ) )
|
||||
{
|
||||
NETINFO_ITEM *net = brd->FindNet ( coupledNetName );
|
||||
|
||||
if(!net)
|
||||
if( MatchDpSuffix( refName, coupledNetName, dummy ) )
|
||||
{
|
||||
NETINFO_ITEM* net = brd->FindNet( coupledNetName );
|
||||
|
||||
if( !net )
|
||||
return -1;
|
||||
|
||||
return net->GetNet();
|
||||
|
@ -297,24 +311,24 @@ int PNS_TOPOLOGY::DpCoupledNet( 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;
|
||||
|
||||
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 coupledNet = DpCoupledNet ( refNet );
|
||||
|
||||
if(coupledNet < 0)
|
||||
int coupledNet = DpCoupledNet( refNet );
|
||||
|
||||
if( coupledNet < 0 )
|
||||
return false;
|
||||
|
||||
std::set<PNS_ITEM *> coupledItems;
|
||||
std::set<PNS_ITEM*> 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 )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
int dist = s->Seg().Distance( refSeg->Seg() );
|
||||
|
||||
if(dist < minDist)
|
||||
if( dist < minDist )
|
||||
{
|
||||
minDist = dist;
|
||||
coupledSeg = s;
|
||||
|
@ -339,22 +353,23 @@ bool PNS_TOPOLOGY::AssembleDiffPair ( PNS_ITEM *aStart, PNS_DIFF_PAIR& aPair )
|
|||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else
|
||||
return false;
|
||||
|
||||
if(!coupledSeg)
|
||||
if( !coupledSeg )
|
||||
return false;
|
||||
|
||||
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> lp ( m_world->AssembleLine( refSeg ) );
|
||||
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.SetWidth ( lp->Width() );
|
||||
aPair.SetLayers ( lp->Layers() );
|
||||
|
||||
aPair = PNS_DIFF_PAIR( *lp, *ln );
|
||||
aPair.SetWidth( lp->Width() );
|
||||
aPair.SetLayers( lp->Layers() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -35,41 +35,36 @@ class PNS_DIFF_PAIR;
|
|||
|
||||
class PNS_TOPOLOGY
|
||||
{
|
||||
public:
|
||||
typedef std::set<PNS_JOINT *> JOINT_SET;
|
||||
public:
|
||||
typedef std::set<PNS_JOINT*> JOINT_SET;
|
||||
|
||||
PNS_TOPOLOGY ( PNS_NODE *aNode ):
|
||||
m_world ( aNode ) {};
|
||||
PNS_TOPOLOGY( PNS_NODE* aNode ):
|
||||
m_world( aNode ) {};
|
||||
|
||||
~PNS_TOPOLOGY ( ) {};
|
||||
~PNS_TOPOLOGY() {};
|
||||
|
||||
bool SimplifyLine ( PNS_LINE *aLine );
|
||||
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 SimplifyLine( PNS_LINE *aLine );
|
||||
PNS_ITEM* NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor = NULL, int aKindMask = PNS_ITEM::ANY );
|
||||
bool LeadingRatLine( const PNS_LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine );
|
||||
|
||||
const JOINT_SET ConnectedJoints ( PNS_JOINT* aStart );
|
||||
const PNS_ITEMSET ConnectedItems ( PNS_JOINT* 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 );
|
||||
|
||||
const JOINT_SET ConnectedJoints( PNS_JOINT* aStart );
|
||||
const PNS_ITEMSET ConnectedItems( PNS_JOINT* 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 );
|
||||
|
||||
const PNS_ITEMSET AssembleTrivialPath( PNS_SEGMENT* aStart );
|
||||
const PNS_DIFF_PAIR AssembleDiffPair( PNS_SEGMENT* aStart );
|
||||
|
||||
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 DpNetPolarity( int aNet );
|
||||
const PNS_LINE DpCoupledLine( PNS_LINE* aLine );
|
||||
bool AssembleDiffPair( PNS_ITEM* aStart, PNS_DIFF_PAIR& aPair );
|
||||
|
||||
int MatchDpSuffix ( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
|
||||
int DpCoupledNet( int aNet );
|
||||
int DpNetPolarity( int aNet );
|
||||
const PNS_LINE DpCoupledLine( PNS_LINE *aLine );
|
||||
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;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,48 +22,48 @@
|
|||
#include "pns_router.h"
|
||||
#include "pns_meander_placer.h"
|
||||
|
||||
PNS_TUNE_STATUS_POPUP::PNS_TUNE_STATUS_POPUP ( PCB_EDIT_FRAME *parent ) :
|
||||
WX_STATUS_POPUP ( parent )
|
||||
PNS_TUNE_STATUS_POPUP::PNS_TUNE_STATUS_POPUP( PCB_EDIT_FRAME* aParent ) :
|
||||
WX_STATUS_POPUP( aParent )
|
||||
{
|
||||
m_panel->SetBackgroundColour( wxColour(64,64,64) );
|
||||
m_statusLine = new wxStaticText( m_panel, wxID_ANY,
|
||||
wxT("Status text 1\n") ) ;
|
||||
m_panel->SetBackgroundColour( wxColour( 64, 64, 64 ) );
|
||||
m_statusLine = new wxStaticText( m_panel, wxID_ANY, wxT( "Status text 1\n" ) ) ;
|
||||
m_topSizer->Add( m_statusLine, 1, wxALL | wxEXPAND, 5 );
|
||||
|
||||
|
||||
updateSize();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
m_statusLine->SetLabel ( placer->TuningInfo() );
|
||||
m_statusLine->SetLabel( placer->TuningInfo() );
|
||||
|
||||
wxColour color;
|
||||
|
||||
switch ( placer->TuningStatus() )
|
||||
switch( placer->TuningStatus() )
|
||||
{
|
||||
case PNS_MEANDER_PLACER::TUNED:
|
||||
color = wxColour ( 0, 255, 0 );
|
||||
break;
|
||||
case PNS_MEANDER_PLACER::TOO_SHORT:
|
||||
color = wxColour ( 255, 128, 128 );
|
||||
break;
|
||||
case PNS_MEANDER_PLACER::TOO_LONG:
|
||||
color = wxColour ( 128, 128, 255 );
|
||||
break;
|
||||
case PNS_MEANDER_PLACER::TUNED:
|
||||
color = wxColour( 0, 255, 0 );
|
||||
break;
|
||||
case PNS_MEANDER_PLACER::TOO_SHORT:
|
||||
color = wxColour( 255, 128, 128 );
|
||||
break;
|
||||
case PNS_MEANDER_PLACER::TOO_LONG:
|
||||
color = wxColour( 128, 128, 255 );
|
||||
break;
|
||||
}
|
||||
|
||||
m_statusLine->SetForegroundColour (color);
|
||||
m_statusLine->SetForegroundColour( color );
|
||||
|
||||
updateSize();
|
||||
updateSize();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,14 +32,13 @@ class PNS_ROUTER;
|
|||
class PNS_TUNE_STATUS_POPUP : public WX_STATUS_POPUP
|
||||
{
|
||||
public:
|
||||
PNS_TUNE_STATUS_POPUP ( PCB_EDIT_FRAME *parent );
|
||||
PNS_TUNE_STATUS_POPUP( PCB_EDIT_FRAME* aParent );
|
||||
~PNS_TUNE_STATUS_POPUP();
|
||||
|
||||
|
||||
void Update( PNS_ROUTER *aRouter );
|
||||
void Update( PNS_ROUTER* aRouter );
|
||||
|
||||
private:
|
||||
wxStaticText *m_statusLine;
|
||||
wxStaticText* m_statusLine;
|
||||
};
|
||||
|
||||
#endif /* __PNS_TUNE_STATUS_POPUP_H_*/
|
||||
|
|
|
@ -93,82 +93,86 @@ SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg )
|
|||
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;
|
||||
|
||||
l.Append ( p - VECTOR2I(-50000, -50000) );
|
||||
l.Append ( p + VECTOR2I(-50000, -50000) );
|
||||
|
||||
l.Append( aP - VECTOR2I( -50000, -50000 ) );
|
||||
l.Append( aP + VECTOR2I( -50000, -50000 ) );
|
||||
|
||||
//printf("router @ %p\n", PNS_ROUTER::GetInstance());
|
||||
PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 );
|
||||
PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, aColor, 10000 );
|
||||
|
||||
l.Clear();
|
||||
l.Append ( p - VECTOR2I(50000, -50000) );
|
||||
l.Append ( p + VECTOR2I(50000, -50000) );
|
||||
l.Append( aP - 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;
|
||||
|
||||
VECTOR2I o = b.GetOrigin();
|
||||
VECTOR2I s = b.GetSize();
|
||||
VECTOR2I o = aB.GetOrigin();
|
||||
VECTOR2I s = aB.GetSize();
|
||||
|
||||
l.Append( o );
|
||||
l.Append( o.x + s.x, o.y );
|
||||
l.Append( o.x + s.x, o.y + s.y );
|
||||
l.Append( o.x, o.y + s.y );
|
||||
l.Append( o );
|
||||
|
||||
l.Append ( o );
|
||||
l.Append ( o.x + s.x, o.y );
|
||||
l.Append ( o.x + s.x, o.y + s.y );
|
||||
l.Append ( o.x, o.y + s.y );
|
||||
l.Append ( o );
|
||||
|
||||
//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;
|
||||
|
||||
l.Append ( s.A );
|
||||
l.Append ( s.B );
|
||||
|
||||
PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, color, 10000 );
|
||||
l.Append( aS.A );
|
||||
l.Append( aS.B );
|
||||
|
||||
PNS_ROUTER::GetInstance()->DisplayDebugLine( l, aColor, 10000 );
|
||||
}
|
||||
|
||||
void DrawDebugDirs ( VECTOR2D p, int mask, int color )
|
||||
{
|
||||
BOX2I b ( p - VECTOR2I ( 10000, 10000 ), VECTOR2I ( 20000, 20000 ) );
|
||||
|
||||
DrawDebugBox ( b, color );
|
||||
for (int i = 0; i < 8; i++)
|
||||
void DrawDebugDirs( VECTOR2D aP, int aMask, int aColor )
|
||||
{
|
||||
BOX2I b( aP - VECTOR2I( 10000, 10000 ), VECTOR2I( 20000, 20000 ) );
|
||||
|
||||
DrawDebugBox( b, aColor );
|
||||
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;
|
||||
DrawDebugSeg ( SEG (p, p+v), color );
|
||||
|
||||
VECTOR2I v = DIRECTION_45( ( DIRECTION_45::Directions ) i ).ToVector() * 100000;
|
||||
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 *vb = static_cast <const PNS_VIA *> (aItemB);
|
||||
|
||||
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);
|
||||
const PNS_VIA* va = static_cast<const PNS_VIA*>( aItemA );
|
||||
const PNS_VIA* vb = static_cast<const PNS_VIA*>( aItemB );
|
||||
|
||||
return la->ChangedArea (lb);
|
||||
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 );
|
||||
}
|
||||
|
||||
return OPT_BOX2I();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,12 +41,12 @@ const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
|
|||
|
||||
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg );
|
||||
|
||||
void DrawDebugPoint ( VECTOR2I p, int color );
|
||||
void DrawDebugBox ( BOX2I b, int color );
|
||||
void DrawDebugSeg ( SEG s, int color );
|
||||
void DrawDebugDirs ( VECTOR2D p, int mask, int color );
|
||||
void DrawDebugPoint( VECTOR2I aP, int aColor );
|
||||
void DrawDebugBox( BOX2I aB, int aColor );
|
||||
void DrawDebugSeg( SEG aS, int aColor );
|
||||
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
|
||||
|
|
|
@ -96,12 +96,13 @@ PNS_VIA* PNS_VIA::Clone ( ) const
|
|||
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() )
|
||||
{
|
||||
BOX2I tmp = Shape()->BBox( );
|
||||
tmp.Merge ( aOther->Shape()->BBox( ) );
|
||||
BOX2I tmp = Shape()->BBox();
|
||||
tmp.Merge ( aOther->Shape()->BBox() );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
|
|
@ -146,8 +146,8 @@ public:
|
|||
return 1;
|
||||
}
|
||||
|
||||
OPT_BOX2I ChangedArea ( const PNS_VIA *aOther ) const;
|
||||
|
||||
OPT_BOX2I ChangedArea( const PNS_VIA* aOther ) const;
|
||||
|
||||
private:
|
||||
int m_diameter;
|
||||
int m_drill;
|
||||
|
|
|
@ -99,7 +99,7 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
|
|||
pnew.Append( path_walk[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] ) );
|
||||
else
|
||||
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_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] ) );
|
||||
else
|
||||
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;
|
||||
|
||||
if(m_forceWinding)
|
||||
if( m_forceWinding )
|
||||
{
|
||||
s_cw = m_forceCw ? IN_PROGRESS : STUCK;
|
||||
s_ccw = m_forceCw ? STUCK : IN_PROGRESS;
|
||||
m_forceSingleDirection = true;
|
||||
|
||||
} else {
|
||||
|
||||
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();
|
||||
|
||||
if( m_forceLongerPath )
|
||||
aWalkPath = (len_cw > len_ccw ? path_cw : path_ccw);
|
||||
aWalkPath = ( len_cw > len_ccw ? path_cw : path_ccw );
|
||||
else
|
||||
aWalkPath = (len_cw < len_ccw ? path_cw : path_ccw);
|
||||
aWalkPath = ( len_cw < len_ccw ? path_cw : path_ccw );
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -244,7 +242,7 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::Route( const PNS_LINE& aInitia
|
|||
return STUCK;
|
||||
if( aWalkPath.CPoint( 0 ) != aInitialPath.CPoint( 0 ) )
|
||||
return STUCK;
|
||||
|
||||
|
||||
WALKAROUND_STATUS st = s_ccw == DONE || s_cw == DONE ? DONE : STUCK;
|
||||
|
||||
if( st == DONE )
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
return st;
|
||||
}
|
||||
|
|
|
@ -24,70 +24,70 @@
|
|||
template<class T>
|
||||
class RANGE
|
||||
{
|
||||
public:
|
||||
RANGE( T aMin, T aMax ) :
|
||||
m_min( aMin ),
|
||||
m_max( aMax ),
|
||||
m_defined( true ) {}
|
||||
public:
|
||||
RANGE( T aMin, T aMax ) :
|
||||
m_min( aMin ),
|
||||
m_max( aMax ),
|
||||
m_defined( true ) {}
|
||||
|
||||
RANGE():
|
||||
m_defined( false ) {}
|
||||
RANGE():
|
||||
m_defined( false ) {}
|
||||
|
||||
T MinV() const
|
||||
{
|
||||
return m_min;
|
||||
}
|
||||
T MinV() const
|
||||
{
|
||||
return m_min;
|
||||
}
|
||||
|
||||
T MaxV() const
|
||||
{
|
||||
return m_max;
|
||||
}
|
||||
T MaxV() const
|
||||
{
|
||||
return m_max;
|
||||
}
|
||||
|
||||
void Set( T aMin, T aMax ) const
|
||||
{
|
||||
m_max = aMax;
|
||||
m_min = aMin;
|
||||
}
|
||||
void Set( T aMin, T aMax ) const
|
||||
{
|
||||
m_max = aMax;
|
||||
m_min = aMin;
|
||||
}
|
||||
|
||||
void Grow( T aValue )
|
||||
{
|
||||
if( !m_defined )
|
||||
{
|
||||
m_min = aValue;
|
||||
m_max = aValue;
|
||||
m_defined = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_min = std::min( m_min, aValue );
|
||||
m_max = std::max( m_max, aValue );
|
||||
}
|
||||
}
|
||||
void Grow( T aValue )
|
||||
{
|
||||
if( !m_defined )
|
||||
{
|
||||
m_min = aValue;
|
||||
m_max = aValue;
|
||||
m_defined = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_min = std::min( m_min, aValue );
|
||||
m_max = std::max( m_max, aValue );
|
||||
}
|
||||
}
|
||||
|
||||
bool Inside( const T& aValue ) const
|
||||
{
|
||||
if( !m_defined )
|
||||
return true;
|
||||
bool Inside( const T& aValue ) const
|
||||
{
|
||||
if( !m_defined )
|
||||
return true;
|
||||
|
||||
return aValue >= m_min && aValue <= m_max;
|
||||
}
|
||||
return aValue >= m_min && aValue <= m_max;
|
||||
}
|
||||
|
||||
bool Overlaps ( const RANGE<T>& aOther ) const
|
||||
{
|
||||
if( !m_defined || !aOther.m_defined )
|
||||
return true;
|
||||
bool Overlaps ( const RANGE<T>& aOther ) const
|
||||
{
|
||||
if( !m_defined || !aOther.m_defined )
|
||||
return true;
|
||||
|
||||
return m_max >= aOther.m_min && m_min <= aOther.m_max;
|
||||
}
|
||||
return m_max >= aOther.m_min && m_min <= aOther.m_max;
|
||||
}
|
||||
|
||||
bool Defined() const
|
||||
{
|
||||
return m_defined;
|
||||
}
|
||||
bool Defined() const
|
||||
{
|
||||
return m_defined;
|
||||
}
|
||||
|
||||
private:
|
||||
T m_min, m_max;
|
||||
bool m_defined;
|
||||
private:
|
||||
T m_min, m_max;
|
||||
bool m_defined;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,37 +17,36 @@
|
|||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __RANGED_NUM_H
|
||||
#define __RANGED_NUM_H
|
||||
|
||||
template <class T> class RANGED_NUM {
|
||||
public:
|
||||
RANGED_NUM ( T aValue = 0, T aTollerancePlus = 0, T aTolleranceMinus = 0) :
|
||||
m_value (aValue),
|
||||
m_tollerancePlus ( aTollerancePlus ),
|
||||
m_tolleranceMinus ( aTolleranceMinus )
|
||||
{}
|
||||
public:
|
||||
RANGED_NUM( T aValue = 0, T aTolerancePlus = 0, T aToleranceMinus = 0 ) :
|
||||
m_value( aValue ),
|
||||
m_tolerancePlus( aTolerancePlus ),
|
||||
m_toleranceMinus( aToleranceMinus )
|
||||
{}
|
||||
|
||||
operator T()
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
operator T()
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
RANGED_NUM& operator= ( const T aValue )
|
||||
{
|
||||
m_value = aValue;
|
||||
return *this;
|
||||
}
|
||||
RANGED_NUM& operator=( const T aValue )
|
||||
{
|
||||
m_value = aValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Matches ( const T& aOther ) const
|
||||
{
|
||||
return ( aOther >= m_value - m_tolleranceMinus && aOther <= m_value + m_tollerancePlus );
|
||||
}
|
||||
bool Matches( const T& aOther ) const
|
||||
{
|
||||
return ( aOther >= m_value - m_toleranceMinus && aOther <= m_value + m_tolerancePlus );
|
||||
}
|
||||
|
||||
private:
|
||||
T m_value, m_tollerancePlus, m_tolleranceMinus;
|
||||
|
||||
private:
|
||||
T m_value, m_tolerancePlus, m_toleranceMinus;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -166,11 +166,11 @@ public:
|
|||
|
||||
if( bds.m_ViasDimensionsList[i].m_Drill <= 0 )
|
||||
{
|
||||
msg << _ (", drill: default");
|
||||
msg << _(", drill: default");
|
||||
}
|
||||
else
|
||||
{
|
||||
msg << _ (", drill: ") << drill;
|
||||
msg << _(", drill: ") << drill;
|
||||
}
|
||||
|
||||
if( i == 0 )
|
||||
|
@ -256,10 +256,10 @@ public:
|
|||
AppendSubMenu( trackMenu, wxT( "Select Track Width" ) );
|
||||
|
||||
Add( ACT_CustomTrackWidth );
|
||||
|
||||
|
||||
if ( aMode == PNS_MODE_ROUTE_DIFF_PAIR )
|
||||
Add( ACT_SetDpDimensions );
|
||||
|
||||
|
||||
AppendSeparator();
|
||||
Add( ACT_RouterOptions );
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ ROUTER_TOOL::~ROUTER_TOOL()
|
|||
|
||||
void ROUTER_TOOL::Reset( RESET_REASON aReason )
|
||||
{
|
||||
printf("RESET\n");
|
||||
//printf("RESET\n");
|
||||
if( m_router )
|
||||
delete m_router;
|
||||
|
||||
|
@ -293,12 +293,13 @@ void ROUTER_TOOL::Reset( RESET_REASON aReason )
|
|||
|
||||
if( getView() )
|
||||
m_router->SetView( getView() );
|
||||
|
||||
|
||||
Go( &ROUTER_TOOL::RouteSingleTrace, COMMON_ACTIONS::routerActivateSingle.MakeEvent() );
|
||||
Go( &ROUTER_TOOL::RouteDiffPair, COMMON_ACTIONS::routerActivateDiffPair.MakeEvent() );
|
||||
Go( &ROUTER_TOOL::TuneSingleTrace, COMMON_ACTIONS::routerActivateTuneSingleTrace.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
int ROUTER_TOOL::getDefaultWidth( int aNetCode )
|
||||
{
|
||||
int w, d1, d2;
|
||||
|
@ -452,9 +453,9 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
|
|||
}
|
||||
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;
|
||||
|
||||
PNS_MEANDER_SETTINGS settings = placer->Settings();
|
||||
|
@ -479,10 +480,9 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
|
|||
|
||||
else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) )
|
||||
{
|
||||
|
||||
PNS_SIZES_SETTINGS sizes ( m_savedSizes );
|
||||
sizes.ImportCurrent ( m_board->GetDesignSettings() );
|
||||
m_router->UpdateSizes ( sizes );
|
||||
PNS_SIZES_SETTINGS sizes( m_savedSizes );
|
||||
sizes.ImportCurrent( m_board->GetDesignSettings() );
|
||||
m_router->UpdateSizes( sizes );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -496,7 +496,7 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
|
|||
if( aEvent.IsMotion() || aEvent.IsClick() )
|
||||
{
|
||||
bool snapEnabled = !aEvent.Modifier( MD_SHIFT );
|
||||
|
||||
|
||||
VECTOR2I p( aEvent.Position() );
|
||||
startItem = pickSingleItem( p );
|
||||
m_router->EnableSnapping ( snapEnabled );
|
||||
|
@ -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() );
|
||||
}
|
||||
|
||||
|
||||
int ROUTER_TOOL::getStartLayer( const PNS_ITEM* aItem )
|
||||
{
|
||||
int tl = getView()->GetTopLayer();
|
||||
|
@ -597,6 +598,8 @@ int ROUTER_TOOL::getStartLayer( const PNS_ITEM* aItem )
|
|||
|
||||
return tl;
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_TOOL::switchLayerOnViaPlacement()
|
||||
{
|
||||
int al = m_frame->GetActiveLayer();
|
||||
|
@ -616,10 +619,11 @@ void ROUTER_TOOL::switchLayerOnViaPlacement()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
|
||||
const int layerCount = bds.GetCopperLayerCount();
|
||||
int currentLayer = m_router->GetCurrentLayer();
|
||||
|
||||
|
@ -651,7 +655,6 @@ bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType )
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
sizes.SetViaType ( aType );
|
||||
m_router->ToggleViaPlacement( );
|
||||
m_router->UpdateSizes( sizes );
|
||||
|
@ -667,9 +670,9 @@ bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType )
|
|||
void ROUTER_TOOL::performRouting()
|
||||
{
|
||||
bool saveUndoBuffer = true;
|
||||
|
||||
int routingLayer = getStartLayer ( m_startItem );
|
||||
m_frame->SetActiveLayer( ToLAYER_ID ( routingLayer ) );
|
||||
|
||||
int routingLayer = getStartLayer( m_startItem );
|
||||
m_frame->SetActiveLayer( ToLAYER_ID( routingLayer ) );
|
||||
// fixme: switch on invisible layer
|
||||
|
||||
if( m_startItem && m_startItem->Net() >= 0 )
|
||||
|
@ -686,19 +689,18 @@ void ROUTER_TOOL::performRouting()
|
|||
|
||||
PNS_SIZES_SETTINGS sizes ( m_savedSizes );
|
||||
sizes.Init ( m_board, m_startItem );
|
||||
sizes.AddLayerPair ( m_frame->GetScreen()->m_Route_Layer_TOP,
|
||||
m_frame->GetScreen()->m_Route_Layer_BOTTOM );
|
||||
sizes.AddLayerPair( m_frame->GetScreen()->m_Route_Layer_TOP,
|
||||
m_frame->GetScreen()->m_Route_Layer_BOTTOM );
|
||||
m_router->UpdateSizes( sizes );
|
||||
|
||||
if ( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) )
|
||||
{
|
||||
wxMessageBox ( m_router->FailureReason(), _("Error") );
|
||||
highlightNet ( false );
|
||||
wxMessageBox( m_router->FailureReason(), _( "Error" ) );
|
||||
highlightNet( false );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_tuneStatusPopup = new PNS_TUNE_STATUS_POPUP ( m_frame );
|
||||
m_tuneStatusPopup = new PNS_TUNE_STATUS_POPUP( m_frame );
|
||||
m_tuneStatusPopup->Popup();
|
||||
|
||||
m_endItem = NULL;
|
||||
|
@ -715,16 +717,14 @@ void ROUTER_TOOL::performRouting()
|
|||
}
|
||||
else if( evt->IsMotion() )
|
||||
{
|
||||
|
||||
wxPoint p = wxGetMousePosition();
|
||||
p.x+=20;
|
||||
p.y+=20;
|
||||
m_tuneStatusPopup->Update (m_router);
|
||||
m_tuneStatusPopup->Move(p);
|
||||
|
||||
p.x += 20;
|
||||
p.y += 20;
|
||||
m_tuneStatusPopup->Update( m_router );
|
||||
m_tuneStatusPopup->Move( p );
|
||||
|
||||
updateEndItem( *evt );
|
||||
m_router->SetOrthoMode ( evt->Modifier ( MD_CTRL ) );
|
||||
m_router->SetOrthoMode( evt->Modifier ( MD_CTRL ) );
|
||||
m_router->Move( m_endSnapPoint, m_endItem );
|
||||
}
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
|
@ -796,24 +796,28 @@ void ROUTER_TOOL::performRouting()
|
|||
highlightNet( false );
|
||||
}
|
||||
|
||||
|
||||
int ROUTER_TOOL::RouteSingleTrace( TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Route Track" ) );
|
||||
return mainLoop( PNS_MODE_ROUTE_SINGLE );
|
||||
}
|
||||
|
||||
|
||||
int ROUTER_TOOL::RouteDiffPair( TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Router Differential Pair" ) );
|
||||
return mainLoop( PNS_MODE_ROUTE_DIFF_PAIR );
|
||||
}
|
||||
|
||||
|
||||
int ROUTER_TOOL::TuneSingleTrace( TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Track Length" ) );
|
||||
return mainLoop( PNS_MODE_TUNE_SINGLE );
|
||||
}
|
||||
|
||||
|
||||
int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
||||
{
|
||||
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
|
||||
|
@ -825,7 +829,7 @@ int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
|||
Activate();
|
||||
|
||||
m_router->SetMode ( aMode );
|
||||
|
||||
|
||||
m_ctls->SetSnapping( true );
|
||||
m_ctls->ShowCursor( true );
|
||||
|
||||
|
@ -875,7 +879,8 @@ int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ROUTER_TOOL::InlineDrag ( TOOL_EVENT& aEvent )
|
||||
|
||||
int ROUTER_TOOL::InlineDrag( TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
|
||||
|
@ -903,7 +908,7 @@ int ROUTER_TOOL::InlineDrag ( TOOL_EVENT& aEvent )
|
|||
{
|
||||
updateEndItem( *evt );
|
||||
m_router->Move( m_endSnapPoint, m_endItem );
|
||||
}
|
||||
}
|
||||
else if( evt->IsUp( BUT_LEFT ) )
|
||||
{
|
||||
if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
|
||||
|
@ -919,6 +924,7 @@ int ROUTER_TOOL::InlineDrag ( TOOL_EVENT& aEvent )
|
|||
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_TOOL::performDragging()
|
||||
{
|
||||
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
|
||||
|
|
|
@ -57,16 +57,15 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
|
|||
{
|
||||
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);
|
||||
if(!l->SegmentCount())
|
||||
const PNS_LINE* l=static_cast<const PNS_LINE*>( aItem );
|
||||
if( !l->SegmentCount() )
|
||||
return;
|
||||
}
|
||||
|
||||
assert( m_originLayer >= 0 );
|
||||
|
||||
|
||||
m_layer = m_originLayer;
|
||||
m_color = getLayerColor( m_originLayer );
|
||||
m_color.a = 0.8;
|
||||
|
@ -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++ )
|
||||
aGal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );
|
||||
|
|
|
@ -50,19 +50,19 @@ public:
|
|||
PR_POINT,
|
||||
PR_SHAPE
|
||||
};
|
||||
|
||||
|
||||
ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem = NULL, KIGFX::VIEW_GROUP* aParent = NULL );
|
||||
~ROUTER_PREVIEW_ITEM();
|
||||
|
||||
void Update( const PNS_ITEM* aItem );
|
||||
|
||||
void StuckMarker( VECTOR2I& aPosition );
|
||||
|
||||
|
||||
void Line( const SHAPE_LINE_CHAIN& aLine, int aWidth = 0, int aStyle = 0 );
|
||||
void Box( const BOX2I& aBox, int aStyle = 0 );
|
||||
void Point ( const VECTOR2I& aPos, int aStyle = 0);
|
||||
|
||||
void SetColor( const KIGFX::COLOR4D& aColor )
|
||||
void SetColor( const KIGFX::COLOR4D& aColor )
|
||||
{
|
||||
m_color = aColor;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ private:
|
|||
SHAPE* m_shape;
|
||||
|
||||
ITEM_TYPE m_type;
|
||||
|
||||
|
||||
int m_style;
|
||||
int m_width;
|
||||
int m_layer;
|
||||
|
|
|
@ -87,7 +87,7 @@ static TOOL_ACTION ACT_SetDpDimensions( "pcbnew.InteractiveRouter.SetDpDimension
|
|||
|
||||
ROUTER_TOOL::ROUTER_TOOL() :
|
||||
PNS_TOOL_BASE( "pcbnew.InteractiveRouter" )
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
@ -229,10 +229,10 @@ public:
|
|||
AppendSubMenu( trackMenu, wxT( "Select Track Width" ) );
|
||||
|
||||
Add( ACT_CustomTrackWidth );
|
||||
|
||||
|
||||
if ( aMode == PNS_MODE_ROUTE_DIFF_PAIR )
|
||||
Add( ACT_SetDpDimensions );
|
||||
|
||||
|
||||
AppendSeparator();
|
||||
Add( PNS_TOOL_BASE::ACT_RouterOptions );
|
||||
}
|
||||
|
@ -248,12 +248,12 @@ ROUTER_TOOL::~ROUTER_TOOL()
|
|||
void ROUTER_TOOL::Reset( RESET_REASON aReason )
|
||||
{
|
||||
PNS_TOOL_BASE::Reset( aReason );
|
||||
|
||||
|
||||
Go( &ROUTER_TOOL::RouteSingleTrace, COMMON_ACTIONS::routerActivateSingle.MakeEvent() );
|
||||
Go( &ROUTER_TOOL::RouteDiffPair, COMMON_ACTIONS::routerActivateDiffPair.MakeEvent() );
|
||||
Go( &ROUTER_TOOL::DpDimensionsDialog, COMMON_ACTIONS::routerActivateDpDimensionsDialog.MakeEvent() );
|
||||
Go( &ROUTER_TOOL::SettingsDialog, COMMON_ACTIONS::routerActivateSettingsDialog.MakeEvent() );
|
||||
|
||||
|
||||
}
|
||||
|
||||
int ROUTER_TOOL::getDefaultWidth( int aNetCode )
|
||||
|
@ -381,7 +381,7 @@ void ROUTER_TOOL::switchLayerOnViaPlacement()
|
|||
bool ROUTER_TOOL::onViaCommand( VIATYPE_T aType )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
|
||||
const int layerCount = bds.GetCopperLayerCount();
|
||||
int currentLayer = m_router->GetCurrentLayer();
|
||||
|
||||
|
@ -449,7 +449,7 @@ bool ROUTER_TOOL::prepareInteractive()
|
|||
sizes.AddLayerPair ( m_frame->GetScreen()->m_Route_Layer_TOP,
|
||||
m_frame->GetScreen()->m_Route_Layer_BOTTOM );
|
||||
m_router->UpdateSizes( sizes );
|
||||
|
||||
|
||||
if ( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) )
|
||||
{
|
||||
wxMessageBox ( m_router->FailureReason(), _("Error") );
|
||||
|
@ -570,7 +570,7 @@ int ROUTER_TOOL::DpDimensionsDialog( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
m_router->UpdateSizes( sizes );
|
||||
m_savedSizes = sizes;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -612,7 +612,7 @@ int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
|
|||
Activate();
|
||||
|
||||
m_router->SetMode ( aMode );
|
||||
|
||||
|
||||
m_ctls->SetSnapping( true );
|
||||
m_ctls->ShowCursor( true );
|
||||
|
||||
|
|
|
@ -26,17 +26,17 @@
|
|||
class TIME_LIMIT
|
||||
{
|
||||
public:
|
||||
TIME_LIMIT( int aMilliseconds = 0 );
|
||||
~TIME_LIMIT();
|
||||
TIME_LIMIT( int aMilliseconds = 0 );
|
||||
~TIME_LIMIT();
|
||||
|
||||
bool Expired() const;
|
||||
void Restart();
|
||||
bool Expired() const;
|
||||
void Restart();
|
||||
|
||||
void Set( int aMilliseconds );
|
||||
void Set( int aMilliseconds );
|
||||
|
||||
private:
|
||||
int m_limitMs;
|
||||
int64_t m_startTics;
|
||||
int m_limitMs;
|
||||
int64_t m_startTics;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,22 +61,22 @@ TOOL_ACTION COMMON_ACTIONS::findMove( "pcbnew.InteractiveSelection.FindMove",
|
|||
// Edit tool actions
|
||||
TOOL_ACTION COMMON_ACTIONS::editFootprintInFpEditor( "pcbnew.InteractiveEdit.editFootprintInFpEditor",
|
||||
AS_CONTEXT, MD_CTRL + 'E',
|
||||
"Open in Footprint Editor",
|
||||
"Open in Footprint Editor",
|
||||
"Opens the selected footprint in the Footprint Editor" );
|
||||
|
||||
TOOL_ACTION COMMON_ACTIONS::copyPadToSettings ( "pcbnew.InteractiveEdit.copyPadToSettings",
|
||||
AS_CONTEXT, 0,
|
||||
"Copy pad settings to Current Settings",
|
||||
"Copy pad settings to Current Settings",
|
||||
"Copies the properties of selected pad to the current template pad settings." );
|
||||
|
||||
TOOL_ACTION COMMON_ACTIONS::copySettingsToPads ( "pcbnew.InteractiveEdit.copySettingsToPads",
|
||||
AS_CONTEXT, 0,
|
||||
"Copy Current Settings to pads",
|
||||
"Copy Current Settings to pads",
|
||||
"Copies the current template pad settings to the selected pad(s)." );
|
||||
|
||||
TOOL_ACTION COMMON_ACTIONS::globalEditPads ( "pcbnew.InteractiveEdit.globalPadEdit",
|
||||
AS_CONTEXT, 0,
|
||||
"Global Pad Edition",
|
||||
"Global Pad Edition",
|
||||
"Changes pad properties globally." );
|
||||
|
||||
TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit",
|
||||
|
@ -481,13 +481,13 @@ boost::optional<TOOL_EVENT> COMMON_ACTIONS::TranslateLegacyId( int aId )
|
|||
|
||||
case ID_TUNE_SINGLE_TRACK_LEN_BUTT:
|
||||
return COMMON_ACTIONS::routerActivateTuneSingleTrace.MakeEvent();
|
||||
|
||||
|
||||
case ID_TUNE_DIFF_PAIR_LEN_BUTT:
|
||||
return COMMON_ACTIONS::routerActivateTuneDiffPair.MakeEvent();
|
||||
|
||||
|
||||
case ID_TUNE_DIFF_PAIR_SKEW_BUTT:
|
||||
return COMMON_ACTIONS::routerActivateTuneDiffPairSkew.MakeEvent();
|
||||
|
||||
|
||||
case ID_MENU_INTERACTIVE_ROUTER_SETTINGS:
|
||||
return COMMON_ACTIONS::routerActivateSettingsDialog.MakeEvent();
|
||||
|
||||
|
|
|
@ -116,10 +116,10 @@ public:
|
|||
static TOOL_ACTION arcPosture;
|
||||
|
||||
// Push and Shove Router Tool
|
||||
|
||||
|
||||
/// Activation of the Push and Shove router
|
||||
static TOOL_ACTION routerActivateSingle;
|
||||
|
||||
|
||||
/// Activation of the Push and Shove router (differential pair mode)
|
||||
static TOOL_ACTION routerActivateDiffPair;
|
||||
|
||||
|
@ -128,14 +128,14 @@ public:
|
|||
|
||||
/// Activation of the Push and Shove router (diff pair tuning mode)
|
||||
static TOOL_ACTION routerActivateTuneDiffPair;
|
||||
|
||||
|
||||
/// Activation of the Push and Shove router (skew tuning mode)
|
||||
static TOOL_ACTION routerActivateTuneDiffPairSkew;
|
||||
|
||||
/// Activation of the Push and Shove settings dialogs
|
||||
static TOOL_ACTION routerActivateSettingsDialog;
|
||||
static TOOL_ACTION routerActivateDpDimensionsDialog;
|
||||
|
||||
|
||||
|
||||
/// Activation of the Push and Shove router (inline dragging mode)
|
||||
static TOOL_ACTION routerInlineDrag;
|
||||
|
|
|
@ -80,8 +80,8 @@ bool EDIT_TOOL::Init()
|
|||
m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::NotEmpty );
|
||||
|
||||
// Footprint actions
|
||||
m_selectionTool->AddMenuItem( COMMON_ACTIONS::editFootprintInFpEditor,
|
||||
SELECTION_CONDITIONS::OnlyType ( PCB_MODULE_T ) &&
|
||||
m_selectionTool->AddMenuItem( COMMON_ACTIONS::editFootprintInFpEditor,
|
||||
SELECTION_CONDITIONS::OnlyType ( PCB_MODULE_T ) &&
|
||||
SELECTION_CONDITIONS::Count ( 1 ) );
|
||||
|
||||
m_offset.x = 0;
|
||||
|
@ -94,12 +94,12 @@ bool EDIT_TOOL::Init()
|
|||
|
||||
bool EDIT_TOOL::invokeInlineRouter()
|
||||
{
|
||||
TRACK *track = uniqueSelected<TRACK> ();
|
||||
VIA *via = uniqueSelected<VIA> ();
|
||||
TRACK *track = uniqueSelected<TRACK>();
|
||||
VIA *via = uniqueSelected<VIA>();
|
||||
|
||||
if( track || via )
|
||||
{
|
||||
printf("Calling interactive drag\n");
|
||||
//printf("Calling interactive drag\n");
|
||||
m_toolMgr->RunAction( COMMON_ACTIONS::routerInlineDrag, true );
|
||||
return true;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
bool unselect = selection.Empty();
|
||||
|
||||
// Be sure that there is at least one item that we can modify. If nothing was selected before,
|
||||
// try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
|
||||
// try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
|
||||
if( !hoverSelection( selection ) )
|
||||
{
|
||||
setTransitions();
|
||||
|
@ -184,15 +184,12 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
|
||||
VECTOR2I mousePos = evt->Position();
|
||||
|
||||
m_cursor = grid.Align ( evt->Position() );
|
||||
isDragAndDrop = evt->IsDrag( BUT_LEFT );
|
||||
|
||||
m_cursor = grid.Align( evt->Position() );
|
||||
isDragAndDrop = evt->IsDrag( BUT_LEFT );
|
||||
|
||||
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 );
|
||||
|
||||
wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) -
|
||||
|
@ -206,40 +203,39 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
else // Prepare to start dragging
|
||||
{
|
||||
m_selectionTool->SanitizeSelection( );
|
||||
|
||||
if ( selection.Empty() )
|
||||
m_selectionTool->SanitizeSelection();
|
||||
|
||||
if( selection.Empty() )
|
||||
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();
|
||||
|
||||
if ( lockFlags == SELECTION_LOCKED )
|
||||
|
||||
if( lockFlags == SELECTION_LOCKED )
|
||||
break;
|
||||
else if ( lockFlags == SELECTION_LOCK_OVERRIDE )
|
||||
else if( lockFlags == SELECTION_LOCK_OVERRIDE )
|
||||
lockOverride = true;
|
||||
|
||||
|
||||
// Save items, so changes can be undone
|
||||
editFrame->OnModify();
|
||||
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
|
||||
|
||||
VECTOR2I origin;
|
||||
|
||||
|
||||
if( evt->IsDrag( BUT_LEFT ) )
|
||||
mousePos = evt->DragOrigin();
|
||||
|
||||
// origin = grid.Align ( evt->DragOrigin() );
|
||||
//else
|
||||
origin = grid.Align ( mousePos );
|
||||
origin = grid.Align( mousePos );
|
||||
|
||||
if( selection.Size() == 1 )
|
||||
{
|
||||
// Set the current cursor position to the first dragged item origin, so the
|
||||
// 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 );
|
||||
grid.SetAuxAxes ( true, m_cursor );
|
||||
grid.SetAuxAxes( true, m_cursor );
|
||||
|
||||
VECTOR2I o = VECTOR2I( selection.Item<BOARD_ITEM>( 0 )->GetPosition() );
|
||||
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() -
|
||||
wxPoint( origin.x, origin.y );
|
||||
|
||||
getViewControls()->ForceCursorPosition ( true, origin );
|
||||
|
||||
getViewControls()->ForceCursorPosition( true, origin );
|
||||
}
|
||||
|
||||
controls->SetAutoPan( true );
|
||||
|
@ -263,8 +257,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
if (!isDragAndDrop || !lockOverride )
|
||||
{
|
||||
if( !isDragAndDrop || !lockOverride )
|
||||
break; // Finish
|
||||
|
||||
lockOverride = false;
|
||||
|
@ -543,7 +537,6 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem )
|
|||
|
||||
if( m_editModules )
|
||||
{
|
||||
|
||||
MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
|
||||
module->SetLastEditTime();
|
||||
board->m_Status_Pcb = 0; // it is done in the legacy view
|
||||
|
@ -562,19 +555,20 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem )
|
|||
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)." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
getView()->Remove( aItem );
|
||||
board->Remove( aItem );
|
||||
}
|
||||
|
||||
|
||||
aItem->DeleteStructure();
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -653,19 +647,19 @@ bool EDIT_TOOL::hoverSelection( const SELECTION& aSelection, bool aSanitize )
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if ( aSanitize )
|
||||
if( aSanitize )
|
||||
m_selectionTool->SanitizeSelection();
|
||||
|
||||
if ( aSelection.Empty() )
|
||||
if( aSelection.Empty() )
|
||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||
|
||||
|
||||
return !aSelection.Empty();
|
||||
}
|
||||
|
||||
|
@ -707,9 +701,10 @@ void EDIT_TOOL::processChanges( const PICKED_ITEMS_LIST* aList )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
MODULE *mod = uniqueSelected <MODULE> ();
|
||||
MODULE *mod = uniqueSelected<MODULE>();
|
||||
|
||||
if( !mod )
|
||||
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 );
|
||||
|
||||
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
|
||||
|
||||
editor->Show( true );
|
||||
|
|
|
@ -156,15 +156,15 @@ private:
|
|||
|
||||
bool invokeInlineRouter();
|
||||
|
||||
template <class T> T* uniqueSelected()
|
||||
template<class T> T* uniqueSelected()
|
||||
{
|
||||
const SELECTION& selection = m_selectionTool->GetSelection();
|
||||
|
||||
if(selection.items.GetCount() > 1)
|
||||
if( selection.items.GetCount() > 1 )
|
||||
return NULL;
|
||||
|
||||
BOARD_ITEM *item = selection.Item<BOARD_ITEM>( 0 );
|
||||
return dyn_cast<T*> (item);
|
||||
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
|
||||
return dyn_cast<T*>( item );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -40,223 +40,230 @@
|
|||
|
||||
#include "grid_helper.h"
|
||||
|
||||
GRID_HELPER::GRID_HELPER ( PCB_BASE_FRAME *aFrame ) :
|
||||
m_frame ( aFrame )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GRID_HELPER::~GRID_HELPER ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GRID_HELPER::SetGrid ( int aSize )
|
||||
{
|
||||
assert ( false );
|
||||
}
|
||||
|
||||
void GRID_HELPER::SetOrigin ( const VECTOR2I& aOrigin )
|
||||
GRID_HELPER::GRID_HELPER( PCB_BASE_FRAME* aFrame ) :
|
||||
m_frame( aFrame )
|
||||
{
|
||||
}
|
||||
|
||||
VECTOR2I GRID_HELPER::GetGrid ()
|
||||
|
||||
GRID_HELPER::~GRID_HELPER()
|
||||
{
|
||||
PCB_SCREEN *screen = m_frame->GetScreen();
|
||||
|
||||
const wxRealPoint& size = screen->GetGridSize();
|
||||
|
||||
return VECTOR2I ( KiROUND ( size.x ), KiROUND ( size.y ) );
|
||||
}
|
||||
|
||||
VECTOR2I GRID_HELPER::GetOrigin ()
|
||||
|
||||
void GRID_HELPER::SetGrid( int aSize )
|
||||
{
|
||||
return VECTOR2I ( 0, 0 );
|
||||
assert( false );
|
||||
}
|
||||
|
||||
void GRID_HELPER::SetAuxAxes ( bool aEnable, const VECTOR2I aOrigin, bool aEnableDiagonal)
|
||||
{
|
||||
if( aEnable )
|
||||
m_auxAxis = aOrigin;
|
||||
else
|
||||
m_auxAxis = boost::optional <VECTOR2I> ();
|
||||
|
||||
m_diagonalAuxAxesEnable = aEnable;
|
||||
void GRID_HELPER::SetOrigin( const VECTOR2I& aOrigin )
|
||||
{
|
||||
}
|
||||
|
||||
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::GetGrid()
|
||||
{
|
||||
PCB_SCREEN* screen = m_frame->GetScreen();
|
||||
|
||||
const wxRealPoint& size = screen->GetGridSize();
|
||||
|
||||
return VECTOR2I ( KiROUND( size.x ), KiROUND( size.y ) );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::GetOrigin()
|
||||
{
|
||||
return VECTOR2I( 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
void GRID_HELPER::SetAuxAxes( bool aEnable, const VECTOR2I aOrigin, bool aEnableDiagonal )
|
||||
{
|
||||
if( aEnable )
|
||||
m_auxAxis = aOrigin;
|
||||
else
|
||||
m_auxAxis = boost::optional<VECTOR2I>();
|
||||
|
||||
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,
|
||||
round( ( aPoint.y - gridOffset.y ) / gridSize.y ) * gridSize.y + gridOffset.y );
|
||||
|
||||
if ( !m_auxAxis )
|
||||
return nearest;
|
||||
if( !m_auxAxis )
|
||||
return nearest;
|
||||
|
||||
if ( std::abs ( m_auxAxis->x - aPoint.x) < std::abs ( nearest.x - aPoint.x ) )
|
||||
nearest.x = m_auxAxis->x;
|
||||
if( std::abs( m_auxAxis->x - aPoint.x) < std::abs( nearest.x - aPoint.x ) )
|
||||
nearest.x = m_auxAxis->x;
|
||||
|
||||
if ( std::abs ( m_auxAxis->y - aPoint.y) < std::abs ( nearest.y - aPoint.y ) )
|
||||
nearest.y = m_auxAxis->y;
|
||||
if( std::abs( m_auxAxis->y - aPoint.y) < std::abs( nearest.y - aPoint.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();
|
||||
computeAnchors( aItem, aMousePos );
|
||||
|
||||
computeAnchors( aItem, aMousePos );
|
||||
|
||||
double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
|
||||
double lineSnapMinCornerDistance = 50.0 / worldScale;
|
||||
|
||||
ANCHOR* nearestOutline = nearestAnchor ( aMousePos, OUTLINE, LSET::AllLayersMask() );
|
||||
ANCHOR* nearestCorner = nearestAnchor ( aMousePos, CORNER, LSET::AllLayersMask() );
|
||||
ANCHOR* nearestOrigin = nearestAnchor ( aMousePos, ORIGIN, LSET::AllLayersMask() );
|
||||
ANCHOR* best = NULL;
|
||||
double minDist = std::numeric_limits<double>::max();
|
||||
ANCHOR* nearestOutline = nearestAnchor( aMousePos, OUTLINE, LSET::AllLayersMask() );
|
||||
ANCHOR* nearestCorner = nearestAnchor( aMousePos, CORNER, LSET::AllLayersMask() );
|
||||
ANCHOR* nearestOrigin = nearestAnchor( aMousePos, ORIGIN, LSET::AllLayersMask() );
|
||||
ANCHOR* best = NULL;
|
||||
double minDist = std::numeric_limits<double>::max();
|
||||
|
||||
if (nearestOrigin)
|
||||
{
|
||||
minDist = nearestOrigin->Distance(aMousePos);
|
||||
best = nearestOrigin;
|
||||
}
|
||||
|
||||
if (nearestCorner)
|
||||
{
|
||||
double dist = nearestCorner->Distance(aMousePos);
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
best = nearestCorner;
|
||||
}
|
||||
}
|
||||
|
||||
if (nearestOutline)
|
||||
if( nearestOrigin )
|
||||
{
|
||||
double dist = nearestOutline->Distance(aMousePos);
|
||||
if (minDist > lineSnapMinCornerDistance && dist < minDist)
|
||||
best = nearestOutline;
|
||||
minDist = nearestOrigin->Distance( aMousePos );
|
||||
best = nearestOrigin;
|
||||
}
|
||||
|
||||
if( nearestCorner )
|
||||
{
|
||||
double dist = nearestCorner->Distance( aMousePos );
|
||||
if( dist < minDist )
|
||||
{
|
||||
minDist = dist;
|
||||
best = nearestCorner;
|
||||
}
|
||||
}
|
||||
|
||||
if( nearestOutline )
|
||||
{
|
||||
double dist = nearestOutline->Distance( aMousePos );
|
||||
if( minDist > lineSnapMinCornerDistance && dist < minDist )
|
||||
best = nearestOutline;
|
||||
}
|
||||
|
||||
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>::iterator it, it_end;
|
||||
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
|
||||
|
||||
m_frame->GetGalCanvas()->GetView()->Query( aArea, selectedItems ); // Get the list of selected items
|
||||
m_frame->GetGalCanvas()->GetView()->Query( aArea, selectedItems ); // Get the list of selected items
|
||||
|
||||
for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
|
||||
for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
|
||||
if( item->ViewIsVisible() )
|
||||
items.insert ( item );
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
|
||||
if( item->ViewIsVisible() )
|
||||
items.insert ( item );
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
VECTOR2I GRID_HELPER::BestSnapAnchor ( const VECTOR2I &aOrigin, BOARD_ITEM *aDraggedItem )
|
||||
{
|
||||
double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
|
||||
int snapRange = (int) (100.0 / worldScale);
|
||||
|
||||
BOX2I bb ( VECTOR2I ( aOrigin.x - snapRange / 2, aOrigin.y - snapRange/2) , VECTOR2I (snapRange, snapRange) );
|
||||
VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I &aOrigin, BOARD_ITEM* aDraggedItem )
|
||||
{
|
||||
double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
|
||||
int snapRange = (int) ( 100.0 / worldScale );
|
||||
|
||||
BOX2I bb( VECTOR2I( aOrigin.x - snapRange / 2, aOrigin.y - snapRange/2 ), VECTOR2I( snapRange, snapRange ) );
|
||||
|
||||
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() );
|
||||
ANCHOR *nearest = nearestAnchor ( aOrigin, CORNER | SNAPPABLE, layers );
|
||||
LSET layers( aDraggedItem->GetLayer() );
|
||||
ANCHOR* nearest = nearestAnchor( aOrigin, CORNER | SNAPPABLE, layers );
|
||||
|
||||
VECTOR2I nearestGrid = Align ( aOrigin );
|
||||
double gridDist = (nearestGrid - aOrigin).EuclideanNorm();
|
||||
if (nearest)
|
||||
VECTOR2I nearestGrid = Align( aOrigin );
|
||||
double gridDist = ( nearestGrid - aOrigin ).EuclideanNorm();
|
||||
if( nearest )
|
||||
{
|
||||
double snapDist = nearest->Distance ( aOrigin );
|
||||
double snapDist = nearest->Distance( aOrigin );
|
||||
|
||||
if(nearest && snapDist < gridDist)
|
||||
return nearest->pos;
|
||||
}
|
||||
if( nearest && snapDist < gridDist )
|
||||
return nearest->pos;
|
||||
}
|
||||
|
||||
return nearestGrid;
|
||||
return nearestGrid;
|
||||
}
|
||||
|
||||
void GRID_HELPER::computeAnchors ( BOARD_ITEM *aItem, const VECTOR2I& aRefPos )
|
||||
{
|
||||
VECTOR2I origin;
|
||||
|
||||
|
||||
switch ( aItem->Type() )
|
||||
void GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos )
|
||||
{
|
||||
VECTOR2I origin;
|
||||
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case PCB_MODULE_T:
|
||||
{
|
||||
MODULE *mod = static_cast <MODULE *> (aItem);
|
||||
addAnchor ( mod->GetPosition(), ORIGIN | SNAPPABLE, mod );
|
||||
MODULE* mod = static_cast<MODULE*>( aItem );
|
||||
addAnchor( mod->GetPosition(), ORIGIN | SNAPPABLE, mod );
|
||||
|
||||
for( D_PAD* pad = mod->Pads(); pad; pad = pad->Next() )
|
||||
addAnchor( pad->GetPosition(), CORNER | SNAPPABLE, pad );
|
||||
|
||||
for (D_PAD *pad = mod->Pads(); pad; pad = pad->Next() )
|
||||
addAnchor ( pad->GetPosition(), CORNER | SNAPPABLE, pad );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_MODULE_EDGE_T:
|
||||
case PCB_LINE_T:
|
||||
{
|
||||
DRAWSEGMENT *dseg = static_cast <DRAWSEGMENT*> (aItem);
|
||||
DRAWSEGMENT* dseg = static_cast<DRAWSEGMENT*>( aItem );
|
||||
VECTOR2I start = dseg->GetStart();
|
||||
VECTOR2I end = dseg->GetEnd();
|
||||
//LAYER_ID layer = dseg->GetLayer();
|
||||
|
||||
//LAYER_ID layer = dseg->GetLayer();
|
||||
|
||||
switch( dseg->GetShape() )
|
||||
{
|
||||
case S_CIRCLE:
|
||||
{
|
||||
int r = (start - end).EuclideanNorm();
|
||||
|
||||
addAnchor ( start, ORIGIN | 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 );
|
||||
int r = ( start - end ).EuclideanNorm();
|
||||
|
||||
addAnchor( start, ORIGIN | 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 );
|
||||
break;
|
||||
}
|
||||
|
||||
case S_ARC:
|
||||
{
|
||||
origin = dseg->GetCenter();
|
||||
addAnchor ( dseg->GetArcStart(), CORNER | SNAPPABLE, dseg );
|
||||
addAnchor ( dseg->GetArcEnd(), CORNER | SNAPPABLE, dseg );
|
||||
addAnchor ( origin, ORIGIN | SNAPPABLE, dseg );
|
||||
break;
|
||||
addAnchor( dseg->GetArcStart(), CORNER | SNAPPABLE, dseg );
|
||||
addAnchor( dseg->GetArcEnd(), CORNER | SNAPPABLE, dseg );
|
||||
addAnchor( origin, ORIGIN | SNAPPABLE, dseg );
|
||||
break;
|
||||
}
|
||||
|
||||
case S_SEGMENT:
|
||||
{
|
||||
origin.x = start.x + ( start.x - end.x ) / 2;
|
||||
origin.y = start.y + ( start.y - end.y ) / 2;
|
||||
addAnchor ( start, CORNER | SNAPPABLE, dseg );
|
||||
addAnchor ( end, CORNER | SNAPPABLE, dseg );
|
||||
addAnchor ( origin, ORIGIN, dseg );
|
||||
addAnchor( start, CORNER | SNAPPABLE, dseg );
|
||||
addAnchor( end, CORNER | SNAPPABLE, dseg );
|
||||
addAnchor( origin, ORIGIN, dseg );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
origin = dseg->GetStart();
|
||||
addAnchor ( origin, ORIGIN | SNAPPABLE, dseg );
|
||||
addAnchor( origin, ORIGIN | SNAPPABLE, dseg );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -265,70 +272,68 @@ void GRID_HELPER::computeAnchors ( BOARD_ITEM *aItem, const VECTOR2I& aRefPos )
|
|||
|
||||
case PCB_TRACE_T:
|
||||
{
|
||||
TRACK *track = static_cast <TRACK*> (aItem);
|
||||
TRACK* track = static_cast<TRACK*>( aItem );
|
||||
VECTOR2I start = track->GetStart();
|
||||
VECTOR2I end = track->GetEnd();
|
||||
origin.x = start.x + ( start.x - end.x ) / 2;
|
||||
origin.y = start.y + ( start.y - end.y ) / 2;
|
||||
addAnchor ( start, CORNER | SNAPPABLE, track );
|
||||
addAnchor ( end, CORNER | SNAPPABLE, track );
|
||||
addAnchor ( origin, ORIGIN, track);
|
||||
addAnchor( start, CORNER | SNAPPABLE, track );
|
||||
addAnchor( end, CORNER | SNAPPABLE, track );
|
||||
addAnchor( origin, ORIGIN, track);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case PCB_ZONE_AREA_T:
|
||||
{
|
||||
const CPolyLine* outline = static_cast<const ZONE_CONTAINER*>( aItem )->Outline();
|
||||
int cornersCount = outline->GetCornersCount();
|
||||
|
||||
|
||||
SHAPE_LINE_CHAIN lc;
|
||||
lc.SetClosed ( true );
|
||||
|
||||
lc.SetClosed( true );
|
||||
|
||||
for( int i = 0; i < cornersCount; ++i )
|
||||
{
|
||||
const VECTOR2I p ( outline->GetPos( i ) );
|
||||
addAnchor ( p, CORNER, aItem );
|
||||
lc.Append ( p );
|
||||
}
|
||||
const VECTOR2I p ( outline->GetPos( i ) );
|
||||
addAnchor( p, CORNER, aItem );
|
||||
lc.Append( p );
|
||||
}
|
||||
|
||||
addAnchor( lc.NearestPoint ( aRefPos ), OUTLINE, aItem );
|
||||
addAnchor( lc.NearestPoint( aRefPos ), OUTLINE, aItem );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_MODULE_TEXT_T:
|
||||
case PCB_TEXT_T:
|
||||
addAnchor ( aItem->GetPosition(), ORIGIN, aItem );
|
||||
addAnchor( aItem->GetPosition(), ORIGIN, aItem );
|
||||
default:
|
||||
|
||||
|
||||
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();
|
||||
ANCHOR *best = NULL;
|
||||
double minDist = std::numeric_limits<double>::max();
|
||||
ANCHOR* best = NULL;
|
||||
|
||||
BOOST_FOREACH( ANCHOR& a, m_anchors )
|
||||
{
|
||||
if ( !aMatchLayers [ a.item->GetLayer() ] )
|
||||
continue;
|
||||
BOOST_FOREACH( ANCHOR& a, m_anchors )
|
||||
{
|
||||
if( !aMatchLayers[a.item->GetLayer()] )
|
||||
continue;
|
||||
|
||||
if ( ( aFlags & a.flags ) != aFlags )
|
||||
continue;
|
||||
if( ( aFlags & a.flags ) != aFlags )
|
||||
continue;
|
||||
|
||||
double dist = a.Distance(aPos);
|
||||
double dist = a.Distance( aPos );
|
||||
|
||||
if(dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
best = &a;
|
||||
}
|
||||
}
|
||||
if( dist < minDist )
|
||||
{
|
||||
minDist = dist;
|
||||
best = &a;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
|
|
@ -37,69 +37,68 @@ class PCB_BASE_FRAME;
|
|||
class GRID_HELPER {
|
||||
public:
|
||||
|
||||
GRID_HELPER ( PCB_BASE_FRAME *aFrame );
|
||||
~GRID_HELPER ();
|
||||
GRID_HELPER( PCB_BASE_FRAME* aFrame );
|
||||
~GRID_HELPER();
|
||||
|
||||
void SetGrid ( int aSize );
|
||||
void SetOrigin ( const VECTOR2I& aOrigin );
|
||||
|
||||
VECTOR2I GetGrid ();
|
||||
VECTOR2I GetOrigin ();
|
||||
void SetGrid( int aSize );
|
||||
void SetOrigin( const VECTOR2I& aOrigin );
|
||||
|
||||
void SetAuxAxes ( bool aEnable, const VECTOR2I aOrigin = VECTOR2I(0, 0), bool aEnableDiagonal = false );
|
||||
|
||||
VECTOR2I Align ( const VECTOR2I& aPoint );
|
||||
VECTOR2I GetGrid();
|
||||
VECTOR2I GetOrigin();
|
||||
|
||||
VECTOR2I BestDragOrigin ( const VECTOR2I &aMousePos, BOARD_ITEM *aItem );
|
||||
VECTOR2I BestSnapAnchor ( const VECTOR2I &aOrigin, BOARD_ITEM *aDraggedItem );
|
||||
void SetAuxAxes( bool aEnable, const VECTOR2I aOrigin = VECTOR2I( 0, 0 ), bool aEnableDiagonal = false );
|
||||
|
||||
VECTOR2I Align( const VECTOR2I& aPoint );
|
||||
|
||||
VECTOR2I BestDragOrigin ( const VECTOR2I &aMousePos, BOARD_ITEM* aItem );
|
||||
VECTOR2I BestSnapAnchor ( const VECTOR2I &aOrigin, BOARD_ITEM* aDraggedItem );
|
||||
|
||||
private:
|
||||
enum ANCHOR_FLAGS {
|
||||
CORNER = 0x1,
|
||||
OUTLINE = 0x2,
|
||||
SNAPPABLE = 0x4,
|
||||
ORIGIN = 0x8
|
||||
};
|
||||
|
||||
enum ANCHOR_FLAGS {
|
||||
CORNER = 0x1,
|
||||
OUTLINE = 0x2,
|
||||
SNAPPABLE = 0x4,
|
||||
ORIGIN = 0x8
|
||||
};
|
||||
struct ANCHOR
|
||||
{
|
||||
ANCHOR( VECTOR2I aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM* aItem = NULL ):
|
||||
pos( aPos ), flags( aFlags ), item( aItem ) {} ;
|
||||
|
||||
struct ANCHOR
|
||||
{
|
||||
ANCHOR ( VECTOR2I aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM *aItem = NULL ):
|
||||
pos (aPos), flags (aFlags), item (aItem) {} ;
|
||||
VECTOR2I pos;
|
||||
int flags;
|
||||
BOARD_ITEM* item;
|
||||
|
||||
VECTOR2I pos;
|
||||
int flags;
|
||||
BOARD_ITEM *item;
|
||||
|
||||
double Distance ( const VECTOR2I& aP )
|
||||
{
|
||||
return (aP - pos).EuclideanNorm();
|
||||
}
|
||||
double Distance( const VECTOR2I& aP )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
m_anchors.push_back( ANCHOR( aPos, aFlags, aItem ) );
|
||||
}
|
||||
void addAnchor( VECTOR2I aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM* aItem = NULL )
|
||||
{
|
||||
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 ()
|
||||
{
|
||||
m_anchors.clear();
|
||||
}
|
||||
void clearAnchors ()
|
||||
{
|
||||
m_anchors.clear();
|
||||
}
|
||||
|
||||
PCB_BASE_FRAME* m_frame;
|
||||
boost::optional<VECTOR2I> m_auxAxis;
|
||||
bool m_diagonalAuxAxesEnable;
|
||||
PCB_BASE_FRAME* m_frame;
|
||||
boost::optional<VECTOR2I> m_auxAxis;
|
||||
bool m_diagonalAuxAxesEnable;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <class_pcb_text.h>
|
||||
#include <class_drawsegment.h>
|
||||
|
||||
|
||||
#include <wxPcbStruct.h>
|
||||
#include <collectors.h>
|
||||
#include <confirm.h>
|
||||
|
@ -277,7 +276,7 @@ bool SELECTION_TOOL::selectCursor( const VECTOR2I& aWhere, bool aOnDrag )
|
|||
// Remove unselectable items
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -294,8 +293,7 @@ bool SELECTION_TOOL::selectCursor( const VECTOR2I& aWhere, bool aOnDrag )
|
|||
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
||||
default:
|
||||
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
|
||||
guessSelectionCandidates( collector );
|
||||
|
||||
|
@ -306,7 +304,7 @@ bool SELECTION_TOOL::selectCursor( const VECTOR2I& aWhere, bool aOnDrag )
|
|||
|
||||
return true;
|
||||
}
|
||||
else if( collector.GetCount() > 1 )
|
||||
else if( collector.GetCount() > 1 )
|
||||
{
|
||||
if( aOnDrag )
|
||||
Wait ( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) );
|
||||
|
@ -414,6 +412,7 @@ void SELECTION_TOOL::setTransitions()
|
|||
Go( &SELECTION_TOOL::findMove, COMMON_ACTIONS::findMove.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
SELECTION_LOCK_FLAGS SELECTION_TOOL::CheckLock()
|
||||
{
|
||||
if( !m_locked || m_editModules )
|
||||
|
@ -521,6 +520,7 @@ void SELECTION_TOOL::findCallback( BOARD_ITEM* aItem )
|
|||
{
|
||||
clearSelection();
|
||||
select( aItem );
|
||||
getView()->SetCenter( VECTOR2D( aItem->GetPosition() ) );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
|
@ -571,9 +571,9 @@ void SELECTION_TOOL::clearSelection()
|
|||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
|
||||
|
||||
item->ViewHide ( false );
|
||||
item->ViewHide( false );
|
||||
item->ClearSelected();
|
||||
item->ViewUpdate ( KIGFX::VIEW_ITEM::GEOMETRY ) ;
|
||||
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ) ;
|
||||
}
|
||||
m_selection.clear();
|
||||
|
||||
|
@ -742,6 +742,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
|||
case PCB_MODULE_TEXT_T:
|
||||
if( m_multiple && !m_editModules )
|
||||
return false;
|
||||
|
||||
return aItem->ViewIsVisible() && board->IsLayerVisible( aItem->GetLayer() );
|
||||
|
||||
// These are not selectable
|
||||
|
@ -751,7 +752,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
|||
if( m_multiple && !m_editModules )
|
||||
return false;
|
||||
|
||||
MODULE *mod = static_cast<const D_PAD *> (aItem) -> GetParent();
|
||||
MODULE* mod = static_cast<const D_PAD*>( aItem )->GetParent();
|
||||
if( mod && mod->IsLocked() )
|
||||
return false;
|
||||
|
||||
|
@ -781,7 +782,7 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem )
|
|||
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() );
|
||||
|
||||
|
@ -838,7 +839,7 @@ void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem ) const
|
|||
m_selection.group->Add( aItem );
|
||||
|
||||
// Hide the original item, so it is shown only on overlay
|
||||
aItem->ViewHide (true);
|
||||
aItem->ViewHide( true );
|
||||
aItem->SetSelected();
|
||||
}
|
||||
|
||||
|
@ -848,7 +849,7 @@ void SELECTION_TOOL::unselectVisually( BOARD_ITEM* aItem ) const
|
|||
m_selection.group->Remove( aItem );
|
||||
|
||||
// Restore original item visibility
|
||||
aItem->ViewHide (false);
|
||||
aItem->ViewHide( false );
|
||||
aItem->ClearSelected();
|
||||
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:
|
||||
return static_cast <MODULE *> (aItem)->GetFootprintRect().GetArea();
|
||||
return static_cast <MODULE*>( aItem )->GetFootprintRect().GetArea();
|
||||
|
||||
case PCB_TRACE_T:
|
||||
{
|
||||
TRACK *t = static_cast<TRACK *> (aItem);
|
||||
TRACK* t = static_cast<TRACK*>( aItem );
|
||||
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();
|
||||
|
||||
if(!aCollector.GetCount())
|
||||
if( !aCollector.GetCount() )
|
||||
return 0.0;
|
||||
|
||||
for(int i = 0; i < aCollector.GetCount(); i++)
|
||||
for( int i = 0; i < aCollector.GetCount(); i++ )
|
||||
{
|
||||
BOARD_ITEM *item = aCollector[i];
|
||||
if(item->Type() == aType)
|
||||
best = std::min(best, calcArea ( item ));
|
||||
BOARD_ITEM* item = aCollector[i];
|
||||
if( item->Type() == aType )
|
||||
best = std::min( best, calcArea( item ) );
|
||||
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
static double calcMaxArea ( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
|
||||
|
||||
static double calcMaxArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
|
||||
{
|
||||
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];
|
||||
if(item->Type() == aType)
|
||||
best = std::max(best, calcArea ( item ));
|
||||
BOARD_ITEM* item = aCollector[i];
|
||||
if( item->Type() == aType )
|
||||
best = std::max(best, calcArea( item ) );
|
||||
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
double calcRatio ( double a, double b )
|
||||
|
||||
double calcRatio( double a, double b )
|
||||
{
|
||||
if ( a == 0.0 && b == 0.0 )
|
||||
return 1.0;
|
||||
|
@ -958,11 +963,12 @@ double calcRatio ( double a, double b )
|
|||
return a / b;
|
||||
}
|
||||
|
||||
|
||||
// todo: explain the selection heuristics
|
||||
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 modulePadMinCoverRatio = 0.45;
|
||||
const double padViaAreaRatio = 0.5;
|
||||
|
@ -970,63 +976,64 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
|
|||
const double trackTrackLengthRatio = 0.3;
|
||||
const double textToFeatureMinRatio = 0.2;
|
||||
const double textToFootprintMinRatio = 0.4;
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
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 ( silkLayers[item->GetLayer() ] )
|
||||
if ( silkLayers[item->GetLayer()] )
|
||||
preferred.insert ( item );
|
||||
}
|
||||
|
||||
if( preferred.size() != 0)
|
||||
if( preferred.size() != 0 )
|
||||
{
|
||||
aCollector.Empty();
|
||||
|
||||
BOOST_FOREACH( BOARD_ITEM *item, preferred )
|
||||
BOOST_FOREACH( BOARD_ITEM* item, preferred )
|
||||
aCollector.Append( item );
|
||||
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 )
|
||||
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 )
|
||||
{
|
||||
BOARD_ITEM *item = aCollector[j];
|
||||
double areaRatio = calcRatio ( textArea, calcArea ( item ) );
|
||||
BOARD_ITEM* item = aCollector[j];
|
||||
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_PAD_T:
|
||||
case PCB_LINE_T:
|
||||
case PCB_VIA_T:
|
||||
case PCB_MODULE_T:
|
||||
if ( areaRatio > textToFeatureMinRatio )
|
||||
if( areaRatio > textToFeatureMinRatio )
|
||||
{
|
||||
printf("t after moduleRejected\n");
|
||||
rejected.insert ( txt );
|
||||
//printf("t after moduleRejected\n");
|
||||
rejected.insert( txt );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1035,53 +1042,55 @@ 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 maxArea = calcMaxArea ( aCollector, PCB_MODULE_T );
|
||||
double minArea = calcMinArea( 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 )
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( aCollector.CountType ( PCB_PAD_T ) > 0 )
|
||||
{
|
||||
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();
|
||||
|
||||
if(ratio < modulePadMinCoverRatio)
|
||||
if( ratio < modulePadMinCoverRatio )
|
||||
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 )
|
||||
if ( VIA *via = dyn_cast<VIA*> ( aCollector[i] ) )
|
||||
{
|
||||
if( VIA* via = dyn_cast<VIA*>( aCollector[i] ) )
|
||||
{
|
||||
double viaArea = calcArea ( via );
|
||||
double viaArea = calcArea( via );
|
||||
|
||||
for( int j = 0; j < aCollector.GetCount(); ++j )
|
||||
{
|
||||
BOARD_ITEM *item = aCollector[j];
|
||||
double areaRatio = calcRatio ( viaArea, calcArea ( item ) );
|
||||
BOARD_ITEM* item = aCollector[j];
|
||||
double areaRatio = calcRatio ( viaArea, calcArea( item ) );
|
||||
|
||||
if( item->Type() == PCB_MODULE_T && areaRatio < modulePadMinCoverRatio )
|
||||
rejected.insert( item );
|
||||
|
@ -1089,18 +1098,19 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
|
|||
if( item->Type() == PCB_PAD_T && areaRatio < padViaAreaRatio )
|
||||
rejected.insert( item );
|
||||
|
||||
if ( TRACK *track = dyn_cast<TRACK*> ( item ) )
|
||||
if( TRACK* track = dyn_cast<TRACK*>( item ) )
|
||||
{
|
||||
if( track->GetNetCode() != via->GetNetCode() )
|
||||
continue;
|
||||
|
||||
double lenRatio = (double) ( track->GetLength() + track->GetWidth()) / (double) via->GetWidth();
|
||||
double lenRatio = (double) ( track->GetLength() + track->GetWidth() ) / (double) via->GetWidth();
|
||||
|
||||
if( lenRatio > trackViaLengthRatio )
|
||||
rejected.insert( track );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nTracks = aCollector.CountType ( PCB_TRACE_T );
|
||||
|
@ -1123,79 +1133,84 @@ void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) c
|
|||
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 )
|
||||
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;
|
||||
if( ratio > trackTrackLengthRatio)
|
||||
rejected.insert(track);
|
||||
}
|
||||
|
||||
if( ratio > trackTrackLengthRatio )
|
||||
rejected.insert( track) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if( ratio < modulePadMinCoverRatio )
|
||||
{
|
||||
printf("rejectModule\n");
|
||||
//printf("rejectModule\n");
|
||||
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()
|
||||
{
|
||||
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 )
|
||||
{
|
||||
BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
|
||||
|
||||
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
|
||||
if( mod && ( mod->PadsLocked( ) || mod->IsLocked( ) ) )
|
||||
rejected.insert ( item );
|
||||
if( mod && ( mod->PadsLocked() || mod->IsLocked() ) )
|
||||
rejected.insert( item );
|
||||
|
||||
// case 2: multi-item selection contains both the module and its pads - remove the pads
|
||||
if (mod && m_selection.items.FindItem ( mod ) >= 0 )
|
||||
rejected.insert ( item );
|
||||
if( mod && m_selection.items.FindItem( mod ) >= 0 )
|
||||
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 );
|
||||
|
||||
if( itemIdx >= 0 )
|
||||
m_selection.items.RemovePicker( itemIdx );
|
||||
|
||||
rejected.erase(item);
|
||||
rejected.erase( item );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::generateMenu()
|
||||
{
|
||||
// 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::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
|
||||
const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
|
||||
|
|
|
@ -166,7 +166,7 @@ public:
|
|||
|
||||
///> 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)
|
||||
bool SanitizeSelection( );
|
||||
bool SanitizeSelection();
|
||||
|
||||
///> Item selection event handler.
|
||||
int SelectItem( const TOOL_EVENT& aEvent );
|
||||
|
@ -194,7 +194,7 @@ private:
|
|||
* a menu is shown, otherise function finishes without selecting anything.
|
||||
* @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()
|
||||
|
|
|
@ -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 <tool/tool_manager.h>
|
||||
|
@ -14,7 +38,7 @@
|
|||
#include <router/router_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 ROUTER_TOOL );
|
||||
|
|
|
@ -486,7 +486,6 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule,
|
|||
|
||||
m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
|
||||
GetGalCanvas()->ForceRefresh();
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue