KiCad PCB EDA Suite
pns_component_dragger.cpp
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2020 CERN
5  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <memory>
22 
23 #include "pns_line.h"
24 #include "pns_solid.h"
25 #include "pns_via.h"
26 #include "pns_router.h"
27 
28 #include "pns_component_dragger.h"
29 #include "pns_debug_decorator.h"
30 
31 namespace PNS
32 {
33 
35 {
36  // ensure all variables are initialized
37  m_dragStatus = false;
38  m_currentNode = nullptr;
39 }
40 
41 
43 {
44 }
45 
46 
47 bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
48 {
49  m_currentNode = nullptr;
50  m_initialDraggedItems = aPrimitives;
51  m_p0 = aP;
52 
53  for( auto item : aPrimitives.Items() )
54  {
55  if( item.item->Kind() != ITEM::SOLID_T )
56  continue;
57 
58  auto solid = static_cast<SOLID*>( item.item );
59  auto jt = m_world->FindJoint( solid->Pos(), solid );
60 
61  m_solids.insert( solid );
62 
63  for( auto link : jt->LinkList() )
64  {
65  if( link.item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
66  {
67  LINKED_ITEM* li = static_cast<LINKED_ITEM*>( link.item );
68  int segIndex;
69 
70  auto l0 = m_world->AssembleLine( li, &segIndex );
71 
72 // printf( "solid %p jt %p fanout %d segs %d\n", solid, jt, jt->LinkCount(),
74 
76 
77  cn.origLine = l0;
78  cn.attachedPad = solid;
79  m_conns.push_back( cn );
80  }
81  }
82  }
83 
84 // printf( "Total: %d conns to drag\n", m_conns.size() );
85 
86  return true;
87 }
88 
90 {
93 
94  for( auto item : m_initialDraggedItems.Items() )
95  m_currentNode->Remove( item );
96 
98 
99  for( auto item : m_solids )
100  {
101  SOLID* s = static_cast<SOLID*>( item );
102  auto p_next = aP - m_p0 + s->Pos();
103  std::unique_ptr<SOLID> snew( static_cast<SOLID*>( s->Clone() ) );
104  snew->SetPos( p_next );
105 
106  m_draggedItems.Add( snew.get() );
107  m_currentNode->Add( std::move( snew ) );
108 
109  for( auto& l : m_conns )
110  {
111  if( l.attachedPad == s )
112  {
113  l.p_orig = s->Pos();
114  l.p_next = p_next;
115  }
116  }
117  }
118 
119  for( auto& cn : m_conns )
120  {
121  auto l_new( cn.origLine );
122  l_new.Unmark();
123  l_new.ClearLinks();
124  l_new.DragCorner( cn.p_next, cn.origLine.CLine().Find( cn.p_orig ) );
125 
126  Dbg()->AddLine( l_new.CLine(), 4, 100000 );
127  m_draggedItems.Add( l_new );
128 
129  auto l_orig( cn.origLine );
130  m_currentNode->Remove( l_orig );
131  m_currentNode->Add( l_new );
132  }
133 
134  return true;
135 }
136 
138 {
139  NODE* node = CurrentNode();
140 
141  if( node )
142  {
143  bool ok;
144  if( Settings().CanViolateDRC() )
145  ok = true;
146  else
147  ok = !node->CheckColliding( m_draggedItems );
148 
149  if( !ok )
150  return false;
151 
152  Router()->CommitRouting( node );
153  return true;
154  }
155 
156  return false;
157 }
158 
160 {
162 }
163 
165 {
166  return m_draggedItems;
167 }
168 
169 }; // namespace PNS
COMPONENT_DRAGGER(ROUTER *aRouter)
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:51
NODE.
Definition: pns_node.h:145
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0, const std::string aName="")
NODE * CurrentNode() const override
Function CurrentNode()
void CommitRouting()
Definition: pns_router.cpp:443
DRAG_ALGO.
Definition: pns_drag_algo.h:42
ENTRIES & Items()
Definition: pns_itemset.h:140
bool Start(const VECTOR2I &aP, ITEM_SET &aPrimitives) override
Function Start()
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:32
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:106
void Remove(ARC *aArc)
Function Remove()
Definition: pns_node.cpp:796
std::set< SOLID * > m_solids
ROUTING_SETTINGS & Settings() const
Returns current router settings
bool Drag(const VECTOR2I &aP) override
Function Drag()
void KillChildren()
Destroys all child nodes. Applicable only to the root node.
Definition: pns_node.cpp:1288
const LINE AssembleLine(LINKED_ITEM *aSeg, int *aOriginSegmentIndex=NULL, bool aStopAtLockedJoints=false)
Function AssembleLine()
Definition: pns_node.cpp:893
ITEM * Clone() const override
Function Clone()
Definition: pns_solid.cpp:76
std::vector< DRAGGED_CONNECTION > m_conns
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:77
JOINT * FindJoint(const VECTOR2I &aPos, int aLayer, int aNet)
Function FindJoint()
Definition: pns_node.cpp:1027
const VECTOR2I & Pos() const
Definition: pns_solid.h:76
const ITEM_SET Traces() override
Function Traces()
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:427
Push and Shove diff pair dimensions (gap) settings dialog.
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Function Add()
Definition: pns_node.cpp:620
bool FixRoute() override
Function FixRoute()