102 m_world = std::make_unique<NODE>();
114 m_world->SetRuleResolver(
nullptr );
134 wxCHECK( node, ret );
142 test.SetWidth(
Sizes().DiffPairGap() + 2 *
Sizes().DiffPairWidth() );
151 int distP = std::numeric_limits<int>::max();
152 int distN = std::numeric_limits<int>::max();
154 ITEM* best =
nullptr;
156 for(
const OBSTACLE& obstacle : obs )
160 if(
m_iface->GetRuleResolver()->DpNetPair( obstacle.m_item, netP, netN ) )
162 int dist = obstacle.m_item->Shape( obstacle.m_item->Layer() )->Distance( aP );
166 ret.
Add( obstacle.m_item,
false );
169 int polarity =
m_iface->GetRuleResolver()->DpNetPolarity( obstacle.m_item->Net() );
176 best = obstacle.m_item;
185 best = obstacle.m_item;
191 if( distP <
Sizes().DiffPairGap() && distN <
Sizes().DiffPairGap() )
193 ret.
Add( best,
false );
200 if( aSlopRadius > 0 )
214 for(
const OBSTACLE& obstacle : obs )
215 ret.
Add( obstacle.m_item,
false );
236 for(
auto item : aItems.
CItems() )
241 NET_HANDLE coupledNet = rr->DpCoupledNet( item->Net() );
244 PNS_DBG(
dbg(), Message, wxString::Format( wxT(
"found DP in itemset: %s/%s"),
261 if( aStartItems.
Empty() )
269 PNS_DBG(
dbg, Message, wxString::Format(wxT(
"start-drag items %d usemulti %d"),
273 if( !useMultidragger &&
Settings().GetKeepDPCouplingWhenDragging() )
280 m_dragger = std::make_unique<COMPONENT_DRAGGER>(
this );
284 else if( useMultidragger )
286 m_dragger = std::make_unique<MULTI_DRAGGER>(
this );
291 m_dragger = std::make_unique<DRAGGER>(
this );
305 if( aStartItems.
Size() == 1 )
307 else if( aStartItems.
Size() > 1 )
311 if(
m_dragger->Start( aP, aStartItems ) )
326 if(
Settings().AllowDRCViolations() )
339 wxString failureReason;
344 if( item->BoardItem() && item->BoardItem()->GetLayer() ==
Edge_Cuts )
347 if( !item->Layers().Overlaps( aLayer ) )
350 if( item->IsRoutable() )
352 failureReason = wxEmptyString;
359 switch( parent->
Type() )
366 failureReason =
_(
"Cannot start routing from a non-plated hole." );
372 ZONE* zone =
static_cast<ZONE*
>( parent );
379 failureReason = wxString::Format(
_(
"Rule area '%s' disallows tracks." ),
384 failureReason =
_(
"Rule area disallows tracks." );
392 failureReason =
_(
"Cannot start routing from a text item." );
401 if( !failureReason.IsEmpty() )
414 dummyStartSeg.
Append( startPoint );
415 dummyStartSeg.
Append( startPoint,
true );
417 dummyStartLine.
SetShape( dummyStartSeg );
419 dummyStartLine.
SetNet( aStartItem ? aStartItem->
Net() : 0 );
430 ITEM_SET dummyStartSet( &dummyStartLine );
435 for(
ITEM* item : highlightedItems )
447 SetFailureReason(
_(
"Cannot start a differential pair in the middle of nowhere." ) );
479 m_placer = std::make_unique<LINE_PLACER>(
this );
483 m_placer = std::make_unique<DIFF_PAIR_PLACER>(
this );
487 m_placer = std::make_unique<MEANDER_PLACER>(
this );
491 m_placer = std::make_unique<DP_MEANDER_PLACER>(
this );
495 m_placer = std::make_unique<MEANDER_SKEW_PLACER>(
this );
507 if(
m_placer->Start( aP, aStartItem ) )
554 ITEM*& aOtherEndItem )
562 if( placer ==
nullptr || placer->
Traces().
Size() == 0 )
567 if( trace ==
nullptr )
597 aOtherEndLayers = it->
Layers();
611 if( placer ==
nullptr || placer->
Traces().
Size() == 0 )
616 if( current ==
nullptr )
622 ITEM* otherEndItem =
nullptr;
635 Move( otherEnd, otherEndItem );
637 }
while( placer->
CurrentEnd() != moveResultPoint && triesLeft );
642 bool forceFinish =
false;
643 bool allowViolations =
false;
645 return FixRoute( otherEnd, otherEndItem, forceFinish, allowViolations );
656 if( placer ==
nullptr || placer->
Traces().
Size() == 0 )
661 if( current ==
nullptr )
668 ITEM* otherEndItem =
nullptr;
677 int nextLayer = otherEndLayers.
Overlaps( currentLayer ) ? currentLayer : otherEndLayers.
Start();
679 if( !
StartRouting( otherEnd, otherEndItem, nextLayer ) )
683 Move( currentEnd,
nullptr );
685 *aNewStartItem = otherEndItem;
708 [&](
ITEM* currentItem,
ITEM* itemToMark )
710 std::unique_ptr<ITEM> tmp( itemToMark->Clone() );
713 bool removeOriginal =
true;
718 && !itemToMark->HasUniqueShapeLayers() )
720 tmp->SetLayer( currentItem->
Layer() );
723 if( itemToMark->IsCompoundShapePrimitive() )
727 removeOriginal =
false;
733 aRemoved.push_back( itemToMark );
744 LINE* l =
static_cast<LINE*
>( item );
758 for(
const OBSTACLE& obs : obstacles )
761 if( draggedItems.
Contains( obs.m_item ) )
764 obs.m_item->Mark( obs.m_item->Marker() |
MK_VIOLATION );
765 updateItem( item, obs.m_item );
770 LINE* line =
static_cast<LINE*
>( item );
811 std::vector<const PNS::ITEM*> cacheCheckItems( added.begin(), added.end() );
814 for(
ITEM* item : added )
820 for(
ITEM* item : removed )
839 bool ret =
m_placer->Move( aP, aEndItem );
847 const LINE* l =
static_cast<const LINE*
>( item );
860 int annularWidth = std::max( 0,
via.Diameter( l->
Layer() ) -
via.Drill() ) / 2;
861 int excessHoleClearance = holeClearance - annularWidth;
880 std::vector<PNS::ITEM*>& aHeads )
882 NODE *node =
nullptr;
887 node =
m_placer->CurrentNode(
true );
904 aHeads.push_back( item->Clone() );
919 for(
ITEM* item : removed )
921 bool is_changed =
false;
927 for( NODE::ITEM_VECTOR::iterator added_it = added.begin();
928 added_it != added.end(); ++added_it )
930 if( ( *added_it )->Parent() && ( *added_it )->Parent() == item->Parent() )
932 changed.push_back( *added_it );
933 added.erase( added_it );
940 if( !is_changed && !item->IsVirtual() )
944 for(
ITEM* item : added )
946 if( !item->IsVirtual() )
950 for(
ITEM* item : changed )
952 if( !item->IsVirtual() )
971 rv =
m_placer->FixRoute( aP, aEndItem, aForceFinish );
976 rv =
m_dragger->FixRoute( aForceCommit );
1019 std::vector<NET_HANDLE> nets;
1059 return m_placer->SetLayer( aLayer );
1069 bool toggle = !
m_placer->IsPlacingVia();
1085 return std::vector<NET_HANDLE>();
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
@ ROUNDED_90
H/V with filleted corners.
@ MITERED_90
H/V only (90-degree corners)
@ ROUNDED_45
H/V/45 with filleted corners.
@ MITERED_45
H/V/45 with mitered corners (default)
KICAD_T Type() const
Returns the type of object.
Single track placement algorithm.
const DIFF_PAIR CurrentTrace() const
bool FindDpPrimitivePair(NODE *aWorld, const VECTOR2I &aP, ITEM *aItem, DP_PRIMITIVE_PAIR &aPair, wxString *aErrorMsg=nullptr)
Store starting/ending primitives (pads, vias or segments) for a differential pair.
virtual const ITEM_SET Traces()=0
Function Traces()
int Count(int aKindMask=-1) const
void Add(const LINE &aLine)
bool Contains(ITEM *aItem) const
std::vector< ITEM * > & Items()
const std::vector< ITEM * > & CItems() const
Base class for PNS router board items.
const PNS_LAYER_RANGE & Layers() const
virtual NET_HANDLE Net() const
void SetNet(NET_HANDLE aNet)
virtual int Layer() const
void SetLayer(int aLayer)
bool OfKind(int aKindMask) const
virtual VECTOR2I Anchor(int n) const
A 2D point on a given set of layers and belonging to a certain net, that links together a number of b...
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
ITEM * GetBlockingObstacle() const
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Assign a shape to the line (a polyline/line chain).
void SetWidth(int aWidth)
Set line width.
Keep the router "world" - i.e.
std::vector< ITEM * > ITEM_VECTOR
int GetClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Return the expected clearance between items a and b.
void GetUpdatedItems(ITEM_VECTOR &aRemoved, ITEM_VECTOR &aAdded)
Return the list of items removed and added in this branch with respect to the root branch.
const JOINT * FindJoint(const VECTOR2I &aPos, int aLayer, NET_HANDLE aNet) const
Search for a joint at a given position, layer and belonging to given net.
std::set< OBSTACLE > OBSTACLES
int QueryColliding(const ITEM *aItem, OBSTACLES &aObstacles, const COLLISION_SEARCH_OPTIONS &aOpts=COLLISION_SEARCH_OPTIONS()) const
Find items colliding (closer than clearance) with the item aItem.
const ITEM_SET HitTest(const VECTOR2I &aPoint) const
Find all items that contain the point aPoint.
Abstract class for a P&S placement/dragging algorithm.
virtual NODE * CurrentNode(bool aLoopsRemoved=false) const =0
Return the most recent board state.
virtual const VECTOR2I & CurrentEnd() const =0
Return the current end of the line(s) being placed/tuned.
virtual const ITEM_SET Traces()=0
Return all routed/tuned traces.
virtual const VECTOR2I & CurrentStart() const =0
Return the current start of the line(s) being placed/tuned.
virtual int CurrentLayer() const =0
Return the layer of currently routed track.
virtual const std::vector< NET_HANDLE > CurrentNets() const =0
Returns the net(s) of currently routed track(s).
virtual DEBUG_DECORATOR * GetDebugDecorator()=0
void updateView(NODE *aNode, ITEM_SET &aCurrent, bool aDragging=false)
void SetMode(ROUTER_MODE aMode)
bool moveDragging(const VECTOR2I &aP, ITEM *aItem)
bool SwitchLayer(int layer)
void ClearViewDecorations()
std::vector< PNS::ITEM * > m_leaderSegments
PLACEMENT_ALGO * Placer()
std::vector< PNS::ITEM * > GetLastCommittedLeaderSegments()
ROUTER_IFACE * GetInterface() const
void BreakSegmentOrArc(ITEM *aItem, const VECTOR2I &aP)
bool ContinueFromEnd(ITEM **aNewStartItem)
void UpdateSizes(const SIZES_SETTINGS &aSizes)
Applies stored settings.
void SetFailureReason(const wxString &aReason)
std::unique_ptr< DRAG_ALGO > m_dragger
const ITEM_SET QueryHoverItems(const VECTOR2I &aP, int aSlopRadius=0)
void SetInterface(ROUTER_IFACE *aIface)
void markViolations(NODE *aNode, ITEM_SET &aCurrent, NODE::ITEM_VECTOR &aRemoved)
std::unique_ptr< PLACEMENT_ALGO > m_placer
bool isStartingPointRoutable(const VECTOR2I &aWhere, ITEM *aItem, int aLayer)
bool IsPlacingVia() const
RULE_RESOLVER * GetRuleResolver() const
DEBUG_DECORATOR * dbg() const
ROUTING_SETTINGS & Settings()
bool movePlacing(const VECTOR2I &aP, ITEM *aItem)
bool RoutingInProgress() const
static ROUTER * GetInstance()
std::optional< VECTOR2I > UndoLastSegment()
void SetOrthoMode(bool aEnable)
bool StartDragging(const VECTOR2I &aP, ITEM *aItem, int aDragMode=DM_ANY)
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
bool areWeLengthTuning() const
int GetCurrentLayer() const
void GetUpdatedItems(std::vector< PNS::ITEM * > &aRemoved, std::vector< PNS::ITEM * > &aAdded, std::vector< PNS::ITEM * > &aHeads)
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish, bool aForceCommit)
std::unique_ptr< NODE > m_world
void ToggleViaPlacement()
ROUTING_SETTINGS * m_settings
bool hasDiffPairMembers(const ITEM_SET &aItems) const
const std::vector< NET_HANDLE > GetCurrentNets() const
bool GetNearestRatnestAnchor(VECTOR2I &aOtherEnd, PNS_LAYER_RANGE &aOtherEndLayers, ITEM *&aOtherEndItem)
bool Move(const VECTOR2I &aP, ITEM *aItem)
virtual void ClearCacheForItems(std::vector< const ITEM * > &aItems)
virtual void ClearTemporaryCaches()
virtual int Clearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true)=0
virtual void ClearCaches()
ITEM * NearestUnconnectedItem(const JOINT *aStart, int *aAnchor=nullptr, int aKindMask=ITEM::ANY_T)
bool NearestUnconnectedAnchorPoint(const LINE *aTrack, VECTOR2I &aPoint, PNS_LAYER_RANGE &aLayers, ITEM *&aItem)
Represent a contiguous set of PCB layers.
bool Overlaps(const PNS_LAYER_RANGE &aOther) const
static PNS_LAYER_RANGE All()
Shortcut for comparisons/overlap tests.
bool IsMultilayer() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Handle a list of polygons defining a copper zone.
const wxString & GetZoneName() const
bool HasKeepoutParametersSet() const
Accessor to determine if any keepout parameters are set.
static bool empty(const wxTextEntryBase *aCtrl)
Push and Shove diff pair dimensions (gap) settings dialog.
bool SplitAdjacentSegments(NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
Snaps the point aP to segment aSeg.
static ROUTER * theRouter
bool SplitAdjacentArcs(NODE *aNode, ITEM *aArc, const VECTOR2I &aP)
Snaps the point aP to arc aArc.
@ PNS_MODE_ROUTE_DIFF_PAIR
@ PNS_MODE_TUNE_DIFF_PAIR
@ PNS_MODE_TUNE_DIFF_PAIR_SKEW
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
#define PNS_DBG(dbg, method,...)
Hold an object colliding with another object, along with some useful data about the collision.
static std::vector< int > candidates(const SEGMENT_INDEX &aIndex, const SEG &aQuery, int aPadding)
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_PAD_T
class PAD, a pad in a footprint
VECTOR2< int32_t > VECTOR2I