29#include <wx/translation.h>
49 m_draggedSegmentIndex = 0;
52 m_freeAngleMode =
false;
53 m_forceMarkObstaclesMode =
false;
71 if(
via->PushoutForce( node, lead, force,
ITEM::ANY_T, iterLimit ) )
73 via->SetPos(
via->Pos() + force );
83 int w2 = aSeg->
Width() / 2;
85 auto distA = ( aP - aSeg->
Seg().
A ).EuclideanNorm();
86 auto distB = ( aP - aSeg->
Seg().
B ).EuclideanNorm();
92 psnap = aSeg->
Seg().
A;
94 else if( distB <= w2 )
96 psnap = aSeg->
Seg().
B;
110 if( item->IsVirtual() && item->OfKind(
ITEM::VIA_T ))
111 return static_cast<VVIA*
>( item );
120 int w2 = aSeg->
Width() / 2;
125 auto distA = ( aP - aSeg->
Seg().
A ).EuclideanNorm();
126 auto distB = ( aP - aSeg->
Seg().
B ).EuclideanNorm();
128 if( distA < w2 || distB < w2 )
161 if( centralAngle + maxDeviation >=
ANGLE_180 )
165 wxString::Format(
_(
"Unable to drag arc tracks of %.1f degrees or greater." ), limit.
AsDegrees() ) );
170 LINE probe =
m_world->AssembleLine( aArc, &probeIdx );
195 bool isolatedStart = ( firstArcPt == 0 );
196 bool isolatedEnd = ( lastArcPt == probe.
PointCount() - 1 );
198 if( isolatedStart || isolatedEnd )
201 int stubLen = std::max( 1, maxStubIU / 2 );
213 if( perp.
x * toMid.
x + perp.
y * toMid.
y > 0 )
216 double mag = std::hypot( (
double) perp.
x, (
double) perp.
y );
227 VECTOR2I stubFar = p0 + outwardTangent( p0 );
228 auto stub = std::make_unique<SEGMENT>(
SEG( stubFar, p0 ), aArc->
Net() );
229 stub->SetWidth( aArc->
Width() );
230 stub->SetLayers( aArc->
Layers() );
237 VECTOR2I stubFar = p1 + outwardTangent( p1 );
238 auto stub = std::make_unique<SEGMENT>(
SEG( p1, stubFar ), aArc->
Net() );
239 stub->SetWidth( aArc->
Width() );
240 stub->SetLayers( aArc->
Layers() );
276 bool foundVia =
false;
306 if( aPrimitives.
Empty() )
309 ITEM* startItem = aPrimitives[0];
333 PNS_DBG(
Dbg(), Message, wxString::Format(
"StartDragging: item %p [kind %d]",
334 startItem, (
int) startItem->
Kind() ) );
336 switch( startItem->
Kind() )
362 m_mode =
static_cast<int>( aMode );
443 if(
Settings().AllowDRCViolations() )
466 LINE draggedLine( *l );
501 bool viaPropOk =
false;
508 std::unique_ptr<VIA> draggedVia =
Clone( *
via );
510 draggedVia->SetPos( aP );
515 vias.insert( draggedVia.get() );
523 viaTargetPos = draggedVia->Pos();
538 LINE draggedLine( *l );
545 if (
m_world->CheckColliding( &draggedLine ) )
571 LINE draggedPostOpt, origLine( aOrig );
576 if(
Settings().GetOptimizeEntireDraggedTrack() )
583 if(
Settings().SmoothDraggedSegments() )
597 affectedArea =
BOX2I( aP );
600 PNS_DBG(
Dbg(), AddShape, *affectedArea,
RED, 0, wxT(
"drag-affected-area" ) );
604 PNS_DBG(
Dbg(), AddItem, &aDragged,
RED, 0, wxT(
"drag-preopt" ) );
607 optimizer.
Optimize( &aDragged, &draggedPostOpt, &origLine );
612 draggedPostOpt = aDragged;
675 if (
m_world->CheckColliding( &dragged ) )
681 draggedWalk = dragged;
706 if(
m_world->CheckColliding( &dragged ) )
712 draggedWalk = dragged;
763 auto preShoveNode =
m_shove->CurrentNode();
766 preShoveNode->Remove( draggedPreShove );
776 m_shove->AddHeads( draggedPreShove, policy );
779 LINE draggedPostShove( draggedPreShove );
784 draggedPostShove =
m_shove->GetModifiedHead( 0 );
792 draggedPostShove.
Unmark();
813 auto preShoveNode =
m_shove->CurrentNode();
816 preShoveNode->Remove( draggedPreShove );
821 m_shove->AddHeads( draggedPreShove, policy );
825 LINE draggedPostShove( draggedPreShove );
827 if( ok &&
m_shove->HeadsModified() )
828 draggedPostShove =
m_shove->GetModifiedHead( 0 );
835 draggedPostShove.
Unmark();
857 PNS_DBG(
Dbg(), Message, wxString::Format(
"head-mod %d",
858 m_shove->HeadsModified() ? 1: 0 ) );
862 newVia =
m_shove->GetModifiedHeadVia( 0 );
864 PNS_DBG(
Dbg(), Message, wxString::Format(
"newvia %d %d %d %d",
constexpr EDA_IU_SCALE pcbIUScale
std::optional< BOX2I > OPT_BOX2I
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void SetDebugDecorator(DEBUG_DECORATOR *aDecorator)
Assign a debug decorator allowing this algo to draw extra graphics for visual debugging.
void SetLogger(LOGGER *aLogger)
virtual LOGGER * Logger()
ROUTER * Router() const
Return current router settings.
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
DEBUG_DECORATOR * Dbg() const
int Width() const override
const SHAPE_ARC & CArc() const
ITEM_SET m_draggedItems
If true, moves the connection lines without maintaining 45 degrees corners.
PNS::DRAG_MODE Mode() const override
void optimizeAndUpdateDraggedLine(LINE &aDragged, const LINE &aOrig, const VECTOR2I &aP)
const ITEM_SET findViaFanoutByHandle(NODE *aNode, const VIA_HANDLE &handle)
bool startDragSegment(const VECTOR2D &aP, SEGMENT *aSeg)
VECTOR2D m_lastValidPoint
Contains the list of items that are currently modified by the dragger.
virtual bool Start(const VECTOR2I &aP, ITEM_SET &aPrimitives) override
Function Start()
NODE * CurrentNode() const override
Function CurrentNode()
bool dragViaMarkObstacles(const VIA_HANDLE &aHandle, NODE *aNode, const VECTOR2I &aP)
bool Drag(const VECTOR2I &aP) override
Function Drag()
bool startDragVia(VIA *aVia)
int m_draggedSegmentIndex
const std::vector< NET_HANDLE > CurrentNets() const override
Function CurrentNets()
bool dragShove(const VECTOR2I &aP)
void SetMode(PNS::DRAG_MODE aDragMode) override
bool dragMarkObstacles(const VECTOR2I &aP)
bool FixRoute(bool aForceCommit) override
Function FixRoute()
std::unique_ptr< SHOVE > m_shove
bool dragWalkaround(const VECTOR2I &aP)
VVIA * checkVirtualVia(const VECTOR2D &aP, SEGMENT *aSeg)
bool dragViaWalkaround(const VIA_HANDLE &aHandle, NODE *aNode, const VECTOR2I &aP)
bool m_forceMarkObstaclesMode
const ITEM_SET Traces() override
Function Traces()
bool tryWalkaround(NODE *aNode, LINE &aOrig, LINE &aWalk)
bool startDragArc(const VECTOR2D &aP, ARC *aArc)
MOUSE_TRAIL_TRACER m_mouseTrailTracer
bool propagateViaForces(NODE *node, std::set< VIA * > &vias)
DRAG_ALGO(ROUTER *aRouter)
void Add(const LINE &aLine)
std::vector< ITEM * > & Items()
Base class for PNS router board items.
virtual void Unmark(int aMarker=-1) const
const PNS_LAYER_RANGE & Layers() const
virtual NET_HANDLE Net() const
PnsKind Kind() const
Return the type (kind) of the item.
A 2D point on a given set of layers and belonging to a certain net, that links together a number of b...
const std::vector< ITEM * > & LinkList() const
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
OPT_BOX2I ChangedArea(const LINE *aOther) const
void DragArc(const VECTOR2I &aP, int aIndex)
const SHAPE_LINE_CHAIN & CLine() const
SHAPE_LINE_CHAIN & Line()
void DragCorner(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false, DIRECTION_45 aPreferredEndingDirection=DIRECTION_45())
void SetSnapThreshhold(int aThreshhold)
virtual void Unmark(int aMarker=-1) const override
void DragSegment(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false)
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
virtual void ClearLinks()
Return the number of segments that were assembled together to form this line.
Keep the router "world" - i.e.
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.
const LINE AssembleLine(LINKED_ITEM *aSeg, int *aOriginSegmentIndex=nullptr, bool aStopAtLockedJoints=false, bool aFollowLockedSegments=false, bool aAllowSegmentSizeMismatch=true)
Follow the joint map to assemble a line connecting two non-trivial joints starting from segment aSeg.
Perform various optimizations of the lines being routed, attempting to make the lines shorter and les...
void SetPreserveVertex(const VECTOR2I &aV)
void SetRestrictArea(const BOX2I &aArea, bool aStrict=true)
void SetEffortLevel(int aEffort)
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I &aV=VECTOR2I(0, 0))
@ LIMIT_CORNER_COUNT
Do not attempt to optimize if the resulting line's corner count is outside the predefined range.
@ MERGE_SEGMENTS
Reduce corner cost iteratively.
@ MERGE_COLINEAR
Merge co-linear segments.
void SetFailureReason(const wxString &aReason)
int ViaForcePropIterationLimit() const
bool SmoothDraggedSegments() const
Enable/disable smoothing segments during dragging.
PNS_MODE Mode() const
Set the routing mode.
int Width() const override
@ SHP_DONT_LOCK_ENDPOINTS
const VIA_HANDLE MakeHandle() const
void SetIterationLimit(const int aIterLimit)
void SetLengthLimit(bool aEnable, double aLengthExpansionFactor)
void SetSolidsOnly(bool aSolidsOnly)
STATUS Route(const LINE &aInitialPath, LINE &aWalkPath, bool aOptimize=true)
void SetAllowedPolicies(std::vector< WALK_POLICY > aPolicies)
EDA_ANGLE GetCentralAngle() const
Get the "central angle" of the arc - this is the angle at the point of the "pie slice".
const VECTOR2I & GetArcMid() const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
const VECTOR2I & GetCenter() const
int Split(const VECTOR2I &aP, bool aExact=false)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
static constexpr EDA_ANGLE ANGLE_180
Push and Shove diff pair dimensions (gap) settings dialog.
@ RM_MarkObstacles
Ignore collisions, mark obstacles.
@ RM_Walkaround
Only walk around.
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
#define PNS_DBG(dbg, method,...)
LINE lines[MaxWalkPolicies]
STATUS status[MaxWalkPolicies]
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D