Horizon
pns_item.h
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2017 CERN
5  * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
8  *
9  * This program is free software: you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by the
11  * Free Software Foundation, either version 3 of the License, or (at your
12  * option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef __PNS_ITEM_H
24 #define __PNS_ITEM_H
25 
26 #include <memory>
27 #include <math/vector2d.h>
28 
29 #include <geometry/shape.h>
30 #include <geometry/shape_line_chain.h>
31 
32 #include "pns_layerset.h"
33 
34 class BOARD_ITEM;
35 
36 namespace PNS {
37 
38 class NODE;
39 class PNS_HORIZON_PARENT_ITEM;
40 
41 enum LineMarker {
42  MK_HEAD = ( 1 << 0 ),
43  MK_VIOLATION = ( 1 << 3 ),
44  MK_LOCKED = ( 1 << 4 ),
45  MK_DP_COUPLED = ( 1 << 5 ),
46  MK_HOLE = ( 1 << 6 )
47 };
48 
49 
56 class ITEM
57 {
58 public:
59  static const int UnusedNet = INT_MAX;
60 
62  enum PnsKind
63  {
64  SOLID_T = 1,
65  LINE_T = 2,
66  JOINT_T = 4,
67  SEGMENT_T = 8,
68  ARC_T = 16,
69  VIA_T = 32,
70  DIFF_PAIR_T = 64,
71  ANY_T = 0xff
72  };
73 
74  ITEM( PnsKind aKind )
75  {
76  m_net = UnusedNet;
77  m_movable = true;
78  m_kind = aKind;
79  m_parent = nullptr;
80  m_owner = nullptr;
81  m_marker = 0;
82  m_rank = -1;
83  m_routable = true;
84  m_isVirtual = false;
85  m_isCompoundShapePrimitive = false;
86  }
87 
88  ITEM( const ITEM& aOther )
89  {
90  m_layers = aOther.m_layers;
91  m_net = aOther.m_net;
92  m_movable = aOther.m_movable;
93  m_kind = aOther.m_kind;
94  m_parent = aOther.m_parent;
95  m_owner = aOther.m_owner; // fixme: wtf this was null?
96  m_marker = aOther.m_marker;
97  m_rank = aOther.m_rank;
98  m_routable = aOther.m_routable;
99  m_isVirtual = aOther.m_isVirtual;
100  m_isCompoundShapePrimitive = aOther.m_isCompoundShapePrimitive;
101  }
102 
103  virtual ~ITEM();
104 
108  virtual ITEM* Clone() const = 0;
109 
110  /*
111  * Returns a convex polygon "hull" of a the item, that is used as the walk-around path.
112  *
113  * @param aClearance defines how far from the body of the item the hull should be,
114  * @param aWalkaroundThickness is the width of the line that walks around this hull.
115  */
116  virtual const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0,
117  int aLayer = -1 ) const
118  {
119  return SHAPE_LINE_CHAIN();
120  }
121 
122  virtual const SHAPE_LINE_CHAIN HoleHull( int aClearance, int aWalkaroundThickness,
123  int aLayer ) const
124  {
125  return SHAPE_LINE_CHAIN();
126  }
127 
131  PnsKind Kind() const
132  {
133  return m_kind;
134  }
135 
139  bool OfKind( int aKindMask ) const
140  {
141  return ( aKindMask & m_kind ) != 0;
142  }
143 
147  std::string KindStr() const;
148 
149  void SetParent( const PNS_HORIZON_PARENT_ITEM* aParent ) { m_parent = aParent; }
150  const PNS_HORIZON_PARENT_ITEM* Parent() const { return m_parent; }
151 
152  void SetNet( int aNet ) { m_net = aNet; }
153  int Net() const { return m_net; }
154 
155  const LAYER_RANGE& Layers() const { return m_layers; }
156  void SetLayers( const LAYER_RANGE& aLayers ) { m_layers = aLayers; }
157 
158  void SetLayer( int aLayer ) { m_layers = LAYER_RANGE( aLayer, aLayer ); }
159  virtual int Layer() const { return Layers().Start(); }
160 
164  bool LayersOverlap( const ITEM* aOther ) const
165  {
166  return Layers().Overlaps( aOther->Layers() );
167  }
168 
172  NODE* Owner() const { return m_owner; }
173 
177  void SetOwner( NODE* aOwner ) { m_owner = aOwner; }
178 
182  bool BelongsTo( NODE* aNode ) const
183  {
184  return m_owner == aNode;
185  }
186 
196  bool Collide( const ITEM* aOther, const NODE* aNode, bool aDifferentNetsOnly = true ) const;
197 
201  virtual const SHAPE* Shape() const
202  {
203  return nullptr;
204  }
205 
206  virtual const SHAPE* Hole() const
207  {
208  return nullptr;
209  }
210 
211  virtual void Mark( int aMarker ) const { m_marker = aMarker; }
212  virtual void Unmark( int aMarker = -1 ) const { m_marker &= ~aMarker; }
213  virtual int Marker() const { return m_marker; }
214 
215  virtual void SetRank( int aRank ) { m_rank = aRank; }
216  virtual int Rank() const { return m_rank; }
217 
218  virtual VECTOR2I Anchor( int n ) const
219  {
220  return VECTOR2I();
221  }
222 
223  virtual int AnchorCount() const
224  {
225  return 0;
226  }
227 
228  bool IsLocked() const
229  {
230  return Marker() & MK_LOCKED;
231  }
232 
233  void SetRoutable( bool aRoutable ) { m_routable = aRoutable; }
234  bool IsRoutable() const { return m_routable; }
235 
236  bool IsVirtual() const
237  {
238  return m_isVirtual;
239  }
240 
241  void SetIsCompoundShapePrimitive() { m_isCompoundShapePrimitive = true; }
242  bool IsCompoundShapePrimitive() const { return m_isCompoundShapePrimitive; }
243 
244 private:
245  bool collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferentNetsOnly ) const;
246 
247 protected:
248  PnsKind m_kind;
249 
250  const PNS_HORIZON_PARENT_ITEM* m_parent;
251  NODE* m_owner;
252  LAYER_RANGE m_layers;
253 
254  bool m_movable;
255  int m_net;
256  mutable int m_marker;
257  int m_rank;
258  bool m_routable;
259  bool m_isVirtual;
260  bool m_isCompoundShapePrimitive;
261 };
262 
263 template<typename T, typename S>
264 std::unique_ptr<T> ItemCast( std::unique_ptr<S> aPtr )
265 {
266  static_assert( std::is_base_of<ITEM, S>::value, "Need to be handed a ITEM!" );
267  static_assert( std::is_base_of<ITEM, T>::value, "Need to cast to an ITEM!" );
268  return std::unique_ptr<T>( static_cast<T*>( aPtr.release() ) );
269 }
270 
271 template<typename T>
272 std::unique_ptr< typename std::remove_const<T>::type > Clone( const T& aItem )
273 {
274  static_assert( std::is_base_of<ITEM, T>::value, "Need to be handed an ITEM!" );
275  return std::unique_ptr<typename std::remove_const<T>::type>( aItem.Clone() );
276 }
277 
278 }
279 
280 #endif // __PNS_ITEM_H
Represent a contiguous set of PCB layers.
Definition: pns_layerset.h:32
Base class for PNS router board items.
Definition: pns_item.h:57
void SetOwner(NODE *aOwner)
Set the node that owns this item.
Definition: pns_item.h:177
PnsKind Kind() const
Return the type (kind) of the item.
Definition: pns_item.h:131
virtual const SHAPE * Shape() const
Return the geometrical shape of the item.
Definition: pns_item.h:201
NODE * Owner() const
Return the owner of this item, or NULL if there's none.
Definition: pns_item.h:172
bool BelongsTo(NODE *aNode) const
Definition: pns_item.h:182
static const int UnusedNet
Supported item types.
Definition: pns_item.h:59
bool OfKind(int aKindMask) const
Return true if the item's type matches the mask aKindMask.
Definition: pns_item.h:139
bool Collide(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly=true) const
Check for a collision (clearance violation) with between us and item aOther.
Definition: pns_item.cpp:132
virtual ITEM * Clone() const =0
Return a deep copy of the item.
std::string KindStr() const
Returns the kind of the item, as string.
Definition: pns_item.cpp:161
bool LayersOverlap(const ITEM *aOther) const
Return true if the set of layers spanned by aOther overlaps our layers.
Definition: pns_item.h:164
Keep the router "world" - i.e.
Definition: pns_node.h:148
Definition: pns_horizon_iface.hpp:29
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Definition: shape_line_chain.h:81
An abstract shape on 2D plane.
Definition: shape.h:117