diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index a685338d91..088cea39e3 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -57,6 +57,7 @@ #include "pns_arc.h" #include "pns_routing_settings.h" +#include "pns_sizes_settings.h" #include "pns_item.h" #include "pns_solid.h" #include "pns_segment.h" @@ -80,10 +81,10 @@ public: //virtual int Clearance( int aNetCode ) const override; virtual int DpCoupledNet( int aNet ) override; virtual int DpNetPolarity( int aNet ) override; - virtual bool DpNetPair( PNS::ITEM* aItem, int& aNetP, int& aNetN ) override; + virtual bool DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN ) override; + virtual bool IsDiffPair( const PNS::ITEM* aA, const PNS::ITEM* aB ) override; virtual bool QueryConstraint( PNS::CONSTRAINT_TYPE aType, const PNS::ITEM* aItemA, const PNS::ITEM* aItemB, int aLayer, PNS::CONSTRAINT* aConstraint ) override; - virtual wxString NetName( int aNet ) override; private: @@ -95,15 +96,10 @@ private: }; int holeRadius( const PNS::ITEM* aItem ) const; - int localPadClearance( const PNS::ITEM* aItem ) const; int matchDpSuffix( const wxString& aNetName, wxString& aComplementNet, wxString& aBaseDpName ); PNS::ROUTER_IFACE* m_routerIface; BOARD* m_board; - - std::vector m_netClearanceCache; - std::unordered_map m_localClearanceCache; - int m_defaultClearance; }; @@ -111,58 +107,6 @@ PNS_PCBNEW_RULE_RESOLVER::PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER_I m_routerIface( aRouterIface ), m_board( aBoard ) { - m_netClearanceCache.resize( m_board->GetNetCount() ); - - // Build clearance cache for net classes - for( unsigned int i = 0; i < m_board->GetNetCount(); i++ ) - { - NETINFO_ITEM* ni = m_board->FindNet( i ); - - if( ni == NULL ) - continue; - - CLEARANCE_ENT ent; - ent.coupledNet = DpCoupledNet( i ); - - wxString netClassName = ni->GetClassName(); - NETCLASSPTR nc = m_board->GetDesignSettings().GetNetClasses().Find( netClassName ); - - int clearance = nc->GetClearance(); - ent.clearance = clearance; - ent.dpClearance = nc->GetDiffPairGap(); - m_netClearanceCache[i] = ent; - - wxLogTrace( "PNS", "Add net %u netclass %s clearance %d Diff Pair clearance %d", - i, netClassName.mb_str(), clearance, ent.dpClearance ); - } - - // Build clearance cache for pads - for( MODULE* mod : m_board->Modules() ) - { - int moduleClearance = mod->GetLocalClearance(); - - for( D_PAD* pad : mod->Pads() ) - { - int padClearance = pad->GetLocalClearance(); - - if( padClearance > 0 ) - m_localClearanceCache[ pad ] = padClearance; - - else if( moduleClearance > 0 ) - m_localClearanceCache[ pad ] = moduleClearance; - } - } - - auto defaultRule = m_board->GetDesignSettings().GetNetClasses().Find ("Default"); - - if( defaultRule ) - { - m_defaultClearance = defaultRule->GetClearance(); - } - else - { - m_defaultClearance = Millimeter2iu(0.254); - } } @@ -230,21 +174,22 @@ bool PNS_PCBNEW_RULE_RESOLVER::CollideHoles( const PNS::ITEM* aA, const PNS::ITE } -int PNS_PCBNEW_RULE_RESOLVER::localPadClearance( const PNS::ITEM* aItem ) const +bool PNS_PCBNEW_RULE_RESOLVER::IsDiffPair( const PNS::ITEM* aA, const PNS::ITEM* aB ) { - if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T ) - return 0; + int net_p, net_n; - const D_PAD* pad = static_cast( aItem->Parent() ); + DpNetPair( aA, net_p, net_n ); - auto i = m_localClearanceCache.find( pad ); + if( aA->Net() == net_p && aB->Net() == net_n ) + return true; + if( aB->Net() == net_p && aA->Net() == net_n ) + return true; - if( i == m_localClearanceCache.end() ) - return 0; - - return i->second; + return false; } + + bool PNS_PCBNEW_RULE_RESOLVER::QueryConstraint( PNS::CONSTRAINT_TYPE aType, const PNS::ITEM* aItemA, const PNS::ITEM* aItemB, int aLayer, PNS::CONSTRAINT* aConstraint ) { std::shared_ptr drcEngine = m_board->GetDesignSettings().m_DRCEngine; @@ -274,24 +219,188 @@ bool PNS_PCBNEW_RULE_RESOLVER::QueryConstraint( PNS::CONSTRAINT_TYPE aType, cons return false; // should not happen } + const BOARD_ITEM* parentA = aItemA ? aItemA->Parent() : nullptr; + const BOARD_ITEM* parentB = aItemB ? aItemB->Parent() : nullptr; + DRC_CONSTRAINT hostConstraint = drcEngine->EvalRulesForItems( hostRuleType, - aItemA->Parent(), - aItemB->Parent(), + parentA, + parentB, (PCB_LAYER_ID) aLayer ); if( hostConstraint.IsNull() ) return false; + + switch ( aType ) + { + case PNS::CONSTRAINT_TYPE::CT_CLEARANCE: + case PNS::CONSTRAINT_TYPE::CT_WIDTH: + case PNS::CONSTRAINT_TYPE::CT_DIFF_PAIR_GAP: + aConstraint->m_Value = hostConstraint.GetValue(); + aConstraint->m_RuleName = hostConstraint.GetParentRule()->m_Name; + aConstraint->m_Type = aType; + return true; + } + + return false; } int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) { PNS::CONSTRAINT constraint; - bool ok = QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, aA, aB, aA->Layer(), &constraint ); + bool ok = false; + int rv; + + if( IsDiffPair( aA, aB ) ) + { + // for diff pairs, we use the gap value for shoving/dragging + ok = QueryConstraint( PNS::CONSTRAINT_TYPE::CT_DIFF_PAIR_GAP, aA, aB, aA->Layer(), &constraint ); + rv = constraint.m_Value.Opt(); + printf("QueryDPCL %d\n", rv); + } + + if( !ok ) + { + ok = QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, aA, aB, aA->Layer(), &constraint ); + rv = constraint.m_Value.Min(); + printf("QueryCL %d\n", rv); + } assert( ok ); - return constraint.m_Value.Min(); + return rv; +} + + +int PNS_KICAD_IFACE_BASE::inheritTrackWidth( PNS::ITEM* aItem ) +{ + VECTOR2I p; + + assert( aItem->Owner() != NULL ); + + switch( aItem->Kind() ) + { + case PNS::ITEM::VIA_T: + p = static_cast( aItem )->Pos(); + break; + + case PNS::ITEM::SOLID_T: + p = static_cast( aItem )->Pos(); + break; + + case PNS::ITEM::SEGMENT_T: + return static_cast( aItem )->Width(); + + default: + return 0; + } + + PNS::JOINT* jt = static_cast( aItem->Owner() )->FindJoint( p, aItem ); + + assert( jt != NULL ); + + int mval = INT_MAX; + + + PNS::ITEM_SET linkedSegs = jt->Links(); + linkedSegs.ExcludeItem( aItem ).FilterKinds( PNS::ITEM::SEGMENT_T ); + + for( PNS::ITEM* item : linkedSegs.Items() ) + { + int w = static_cast( item )->Width(); + mval = std::min( w, mval ); + } + + return ( mval == INT_MAX ? 0 : mval ); +} + + +bool PNS_KICAD_IFACE_BASE::ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* aStartItem, int aNet ) +{ + BOARD_DESIGN_SETTINGS &bds = m_board->GetDesignSettings(); + + int net = aNet; + + if( aStartItem ) + net = aStartItem->Net(); + + int trackWidth = 0; + + if( bds.m_UseConnectedTrackWidth && aStartItem != nullptr ) + { + trackWidth = inheritTrackWidth( aStartItem ); + } + + if( !trackWidth && bds.UseNetClassTrack() ) // netclass value + { + PNS::CONSTRAINT constraint; + bool ok = m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_WIDTH, aStartItem, + nullptr, aStartItem->Layer(), &constraint ); + + if( ok ) + { + trackWidth = constraint.m_Value.HasOpt() ? constraint.m_Value.Opt() : constraint.m_Value.Min(); + } + } + + if( !trackWidth ) + { + trackWidth = bds.GetCurrentTrackWidth(); + } + + aSizes.SetTrackWidth( trackWidth ); + + int viaDiameter = 0; + int viaDrill = 0; + + if( bds.UseNetClassVia() ) // netclass value + { + viaDiameter = 0; //netClass->GetViaDiameter(); + viaDrill = 0; //netClass->GetViaDrill(); // fixme + } + else + { + viaDiameter = bds.GetCurrentViaSize(); + viaDrill = bds.GetCurrentViaDrill(); + } + + aSizes.SetViaDiameter( viaDiameter ); + aSizes.SetViaDrill( viaDrill ); + + int diffPairWidth = 0; + int diffPairGap = 0; + int diffPairViaGap = 0; + + if( bds.UseNetClassDiffPair() ) + { + PNS::CONSTRAINT widthConstraint, gapConstraint; + bool okWidth = m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_WIDTH, aStartItem, + nullptr, aStartItem->Layer(), &widthConstraint ); + bool okGap = m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_DIFF_PAIR_GAP, aStartItem, + nullptr, aStartItem->Layer(), &gapConstraint ); + + if( okWidth ) + diffPairWidth = widthConstraint.m_Value.OptThenMin(); + + if( okGap ) + diffPairViaGap = diffPairGap = gapConstraint.m_Value.OptThenMin(); + } + else if( bds.UseCustomDiffPairDimensions() ) + { + diffPairWidth = bds.GetCustomDiffPairWidth(); + diffPairGap = bds.GetCustomDiffPairGap(); + diffPairViaGap = bds.GetCustomDiffPairViaGap(); + } + + //printf("DPWidth: %d gap %d\n", diffPairWidth, diffPairGap ); + + aSizes.SetDiffPairWidth( diffPairWidth ); + aSizes.SetDiffPairGap( diffPairGap ); + aSizes.SetDiffPairViaGap( diffPairViaGap ); + + aSizes.ClearLayerPairs(); + + return true; } @@ -388,7 +497,7 @@ int PNS_PCBNEW_RULE_RESOLVER::DpNetPolarity( int aNet ) } -bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( PNS::ITEM* aItem, int& aNetP, int& aNetN ) +bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN ) { if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() ) return false; diff --git a/pcbnew/router/pns_kicad_iface.h b/pcbnew/router/pns_kicad_iface.h index 986bc40b2a..1b76828832 100644 --- a/pcbnew/router/pns_kicad_iface.h +++ b/pcbnew/router/pns_kicad_iface.h @@ -36,6 +36,11 @@ class PCB_TOOL_BASE; class MODULE; class D_PAD; +namespace PNS +{ + class SIZES_SETTINGS; +} + namespace KIGFX { class VIEW; @@ -60,6 +65,7 @@ public: void AddItem( PNS::ITEM* aItem ) override; void RemoveItem( PNS::ITEM* aItem ) override; void Commit() override {} + bool ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* aStartItem, int aNet ) override; void UpdateNet( int aNetCode ) override {} @@ -89,6 +95,8 @@ protected: bool syncTextItem( PNS::NODE* aWorld, EDA_TEXT* aText, PCB_LAYER_ID aLayer ); bool syncGraphicalItem( PNS::NODE* aWorld, PCB_SHAPE* aItem ); bool syncZone( PNS::NODE* aWorld, ZONE_CONTAINER* aZone ); + int inheritTrackWidth( PNS::ITEM* aItem ); + PNS::NODE* m_world; BOARD* m_board; diff --git a/pcbnew/router/pns_node.h b/pcbnew/router/pns_node.h index 10200f2937..c7912d35fb 100644 --- a/pcbnew/router/pns_node.h +++ b/pcbnew/router/pns_node.h @@ -60,7 +60,9 @@ enum class CONSTRAINT_TYPE CT_CLEARANCE = 1, CT_DIFF_PAIR_GAP = 2, CT_LENGTH = 3, - CT_WIDTH = 4 + CT_WIDTH = 4, + CT_VIA_DIAMETER = 5, + CT_VIA_HOLE = 6 }; struct CONSTRAINT @@ -85,7 +87,9 @@ public: //virtual int Clearance( int aNetCode ) const = 0; virtual int DpCoupledNet( int aNet ) = 0; virtual int DpNetPolarity( int aNet ) = 0; - virtual bool DpNetPair( ITEM* aItem, int& aNetP, int& aNetN ) = 0; + virtual bool DpNetPair( const ITEM* aItem, int& aNetP, int& aNetN ) = 0; + + virtual bool IsDiffPair( const ITEM* aA, const ITEM* aB ) = 0; virtual bool QueryConstraint( CONSTRAINT_TYPE aType, const PNS::ITEM* aItemA, const PNS::ITEM* aItemB, int aLayer, PNS::CONSTRAINT* aConstraint ) = 0; diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 22acf58370..41e705b5b1 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -104,6 +104,7 @@ enum DRAG_MODE virtual void DisplayItem( const ITEM* aItem, int aColor = -1, int aClearance = -1, bool aEdit = false ) = 0; virtual void HideItem( ITEM* aItem ) = 0; virtual void Commit() = 0; + virtual bool ImportSizes( SIZES_SETTINGS& aSizes, ITEM* aStartItem, int aNet ) = 0; // virtual void Abort () = 0; virtual void EraseView() = 0; diff --git a/pcbnew/router/pns_sizes_settings.cpp b/pcbnew/router/pns_sizes_settings.cpp index b86f0ac401..7c2cd87287 100644 --- a/pcbnew/router/pns_sizes_settings.cpp +++ b/pcbnew/router/pns_sizes_settings.cpp @@ -29,123 +29,6 @@ namespace PNS { -int SIZES_SETTINGS::inheritTrackWidth( ITEM* aItem ) -{ - VECTOR2I p; - - assert( aItem->Owner() != NULL ); - - switch( aItem->Kind() ) - { - case ITEM::VIA_T: - p = static_cast( aItem )->Pos(); - break; - - case ITEM::SOLID_T: - p = static_cast( aItem )->Pos(); - break; - - case ITEM::SEGMENT_T: - return static_cast( aItem )->Width(); - - default: - return 0; - } - - JOINT* jt = static_cast( aItem->Owner() )->FindJoint( p, aItem ); - - assert( jt != NULL ); - - int mval = INT_MAX; - - - ITEM_SET linkedSegs = jt->Links(); - linkedSegs.ExcludeItem( aItem ).FilterKinds( ITEM::SEGMENT_T ); - - for( ITEM* item : linkedSegs.Items() ) - { - int w = static_cast( item )->Width(); - mval = std::min( w, mval ); - } - - return ( mval == INT_MAX ? 0 : mval ); -} - - -void SIZES_SETTINGS::Init( BOARD* aBoard, ITEM* aStartItem, int aNet ) -{ - BOARD_DESIGN_SETTINGS &bds = aBoard->GetDesignSettings(); - - NETCLASSPTR netClass; - int net = aNet; - - if( aStartItem ) - net = aStartItem->Net(); - - if( net >= 0 ) - { - NETINFO_ITEM* ni = aBoard->FindNet( net ); - - if( ni ) - { - wxString netClassName = ni->GetClassName(); - netClass = bds.GetNetClasses().Find( netClassName ); - } - } - - if( !netClass ) - netClass = bds.GetNetClasses().GetDefault(); - - m_trackWidth = 0; - - if( bds.m_UseConnectedTrackWidth && aStartItem != NULL ) - { - m_trackWidth = inheritTrackWidth( aStartItem ); - } - - if( !m_trackWidth && ( bds.UseNetClassTrack() && netClass != NULL ) ) // netclass value - { - m_trackWidth = netClass->GetTrackWidth(); - } - - if( !m_trackWidth ) - { - m_trackWidth = bds.GetCurrentTrackWidth(); - } - - if( bds.UseNetClassVia() && netClass != NULL ) // netclass value - { - m_viaDiameter = netClass->GetViaDiameter(); - m_viaDrill = netClass->GetViaDrill(); - } - else - { - m_viaDiameter = bds.GetCurrentViaSize(); - m_viaDrill = bds.GetCurrentViaDrill(); - } - - if( bds.UseNetClassDiffPair() && netClass != NULL ) - { - m_diffPairWidth = netClass->GetDiffPairWidth(); - m_diffPairGap = netClass->GetDiffPairGap(); - m_diffPairViaGap = netClass->GetDiffPairViaGap(); - } - else if( bds.UseCustomDiffPairDimensions() ) - { - m_diffPairWidth = bds.GetCustomDiffPairWidth(); - m_diffPairGap = bds.GetCustomDiffPairGap(); - m_diffPairViaGap = bds.GetCustomDiffPairViaGap(); - } - else - { - m_diffPairWidth = bds.m_DiffPairDimensionsList[ bds.GetDiffPairIndex() ].m_Width; - m_diffPairGap = bds.m_DiffPairDimensionsList[ bds.GetDiffPairIndex() ].m_Gap; - m_diffPairViaGap = bds.m_DiffPairDimensionsList[ bds.GetDiffPairIndex() ].m_ViaGap; - } - - m_layerPairs.clear(); -} - void SIZES_SETTINGS::ClearLayerPairs() { @@ -163,6 +46,7 @@ void SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 ) } +#if 0 void SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings ) { m_trackWidth = aSettings.GetCurrentTrackWidth(); @@ -173,6 +57,7 @@ void SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings ) m_diffPairGap = aSettings.GetCurrentDiffPairGap(); m_diffPairViaGap = aSettings.GetCurrentDiffPairViaGap(); } +#endif int SIZES_SETTINGS::GetLayerTop() const diff --git a/pcbnew/router/pns_sizes_settings.h b/pcbnew/router/pns_sizes_settings.h index 9842b31e3a..3a20474ddd 100644 --- a/pcbnew/router/pns_sizes_settings.h +++ b/pcbnew/router/pns_sizes_settings.h @@ -49,9 +49,6 @@ public: ~SIZES_SETTINGS() {}; - void Init( BOARD* aBoard, ITEM* aStartItem = NULL, int aNet = -1 ); - void ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings ); - void ClearLayerPairs(); void AddLayerPair( int aL1, int aL2 ); diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 8270eebffb..135fe2b371 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -874,9 +874,10 @@ bool ROUTER_TOOL::prepareInteractive() PNS::SIZES_SETTINGS sizes( m_router->Sizes() ); - sizes.Init( board(), m_startItem ); + m_iface->ImportSizes( sizes, m_startItem, -1 ); sizes.AddLayerPair( frame()->GetScreen()->m_Route_Layer_TOP, frame()->GetScreen()->m_Route_Layer_BOTTOM ); + m_router->UpdateSizes( sizes ); if( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) ) @@ -1635,7 +1636,8 @@ int ROUTER_TOOL::CustomTrackWidthDialog( const TOOL_EVENT& aEvent ) int ROUTER_TOOL::onTrackViaSizeChanged( const TOOL_EVENT& aEvent ) { PNS::SIZES_SETTINGS sizes( m_router->Sizes() ); - sizes.ImportCurrent( board()->GetDesignSettings() ); + + m_iface->ImportSizes( sizes, nullptr, m_router->GetCurrentNets()[0] ); m_router->UpdateSizes( sizes ); // Changing the track width can affect the placement, so call the