wxArt2D
route.h
Go to the documentation of this file.
1 /*! \file wx/canvas/route.h
2  \brief routing of wires.
3 
4  Classes for auto (re)routing wires (a2dWirePolylineL) are here.
5 
6  \author Michael Sögtrop
7 
8  Copyright: 2003-2004 (c) Michael Sögtrop
9 
10  Licence: wxWidgets Licence
11 
12  RCS-ID: $Id: wire.h,v 1.9 2006/12/13 21:43:24 titato Exp $
13 */
14 
15 #ifndef __WXROUTE_H__
16 #define __WXROUTE_H__
17 
18 #ifndef WX_PRECOMP
19 #include "wx/wx.h"
20 #endif
21 
22 #include "wx/canvas/candefs.h"
23 
24 class a2dWirePolylineL;
25 
26 //! Class for rerouting wires
27 /*! This class implements a usual Lee router. The one special thing is, that there are
28  penalties for corners. This makes routing a bit complicated, because the lowest cost
29  to reach one point might not be the best for succeeding from this point, as the following
30  example shows:
31 
32  0-1 0- 3
33  | |
34  1-14 16
35  | |
36  2-15 19
37  | |
38  3-16 22
39  | |
40  29 25
41 
42  The numbers are cost. 0 is the routing start point. The points with cost 1..3 are
43  lying on the original line and have a low cost for this reason. The destination
44  is the point with a cost of 29/25. The important point is, that the target can
45  be reached via the right path with higher intermediate cost with lower final cost.
46 
47  To get true least cost routing, the cost is stored for every raster point for the
48  four incomming directions.
49 */
50 
51 class A2DCANVASDLLEXP a2dRouteData : public a2dObject
52 {
53 public:
54  //! Standard constructor takes the show object under which is routed
55  /*! The boundingbox of the child objects in showobject is taken as the area in which to route
56  a wire. This with a certain margin added, in order to route around the outer objects too.
57  Temporary tool objects are skipped from this boundingbox.
58  The boundingbox is divided into a rectangular grid, each grid of size m_raster.
59  The grid points are points where a routed wire can be routed onto.
60  Buffers are allocated to maintain information on the grid points, e.g. which grid points are
61  occupied by objects, and therefore a wire can not be routed there.
62  a2dWirePolylineL objects marked with property PROPID_rerouteadded, indicates a wire to be rerouted,
63  and will not be added to the occupation area. Only polylines are currently added accurate to the occuption area.
64  Meaning the right grid points are disabled for routing. For the other objects currently the boundingbox is used.
65  */
66  a2dRouteData( a2dCanvasObject* showobject, bool final );
67 
68  //! Destructor
69  ~a2dRouteData();
70 
71  //! the size of the raster
72  static void SetRaster( double raster ) { m_raster = raster; }
73 
74  //! Reroute a wire
75  /*!
76  Reroute the given wire, between a start and end pin.
77  The start or end pin is used as a start for producing a border wave,
78  which sets route points to a cost to reach that route point.
79  At the same time the wave itself is expanded at the point with the best cost first.
80  If that point is already reached through another part of the border wave,
81  that point is removed from the wave, else based on the current border point a new point a new
82  border point is created, followed by removing the current best border point.
83  In the end the target pin or wire will be reached and the border wave will be empty.
84  While the border wave is working itself like this through the routing points, the best route is
85  via pointer in the route points.
86 
87  \param wire on input this is the wire in its original (edited but unadjusted) state
88  \param dispin the pin that became disconnected
89  \param startpin the pin where routing starts
90  \param startisbegin the pin where routing starts is the begin point of the wire
91  \param final last route to destination
92  \return true if wire was changed
93  */
94  bool RerouteWire( a2dWirePolylineL* wire, a2dPin* dispin, a2dPin* startpin, bool startisbegin, bool final );
95 
96  //! flags for RoutePoint
98  {
99  flag_original = 0x01,
100  flag_targetwire = 0x02,
101  flag_targetpin = 0x04,
102  flag_targetapprox = 0x08,
103  flag_reachable = 0x10,
104  flag_final = 0x20
105  };
106  //! directions for RoutePoint
108  {
109  dir_xminus = 0,
110  dir_xplus = 1,
111  dir_yminus = 2,
112  dir_yplus = 3,
113 
114  //! start point
115  dir_start = 4,
116 
117  //! min usual direction value
118  dir_min = 0,
119  //! max usual direction value
120  dir_max = 3,
121  //! number of usual direction values
122  dir_count = 4,
123  //! result of dir1^dir2 for two opposing directions
124  dir_invxor = 1
125  };
126  //! the data structure holding the per point information
127  /*!
128  a two dimensional array of RoutePoint is used for routing information, like which points are excluded
129  from routing because they are occupied by other objects.
130  Next to that the route os the wire to be routed is stored via previous and next pointers.
131  Per grid point four RoutePoint are maintained, for the four directions a wire can enter this grid point.
132  */
133  struct RoutePoint
134  {
135  //! minimum cost to reach this point
136  unsigned int m_cost;
137  //! various flags
138  unsigned short m_flags;
139  //! direction to the source (only set if reachable)
140  unsigned char m_direction;
141  //! direction of the previous point
142  unsigned char m_prevdir;
143  //! coordinates of this point (only set if reachable)
144  unsigned short m_x, m_y;
145  };
146 
147  //! An entry in the border queue
148  /*!
149  Used in BorderQueue, for storing the route of a wire.
150  */
151  struct BorderPoint
152  {
153  //! minimum cost to reach this point
154  unsigned int m_cost;
155  //! direction to the source
156  unsigned char m_direction;
157  //! direction of the previous point
158  unsigned char m_prevdir;
159  //! coordinates of this point
160  unsigned short m_x, m_y;
161  //! pointer to the next point with same cost in the queue or to a free point
163  };
164 
165  //! This is a priority queue for border points
166  /*! This queue makes use of the following facts:
167  - The priorities (costs) are discrete
168  - As the relative cost from one point to its next is limited,
169  there can only be priorities from the current min-priority to
170  min-priority + max-dist in the queue, so a ring buffer can be used
171  - priorities added to the list are always larger than the smallest
172  priority in the list (step cost is >0).
173  */
175  {
176  public:
177  //! constructor
178  BorderQueue();
179  //! destructor
180  ~BorderQueue();
181  //! Add a border object
182  void Add( const BorderPoint& brdr );
183  //! Get the best border point
185  {
186  wxASSERT( m_costring[ m_mincostindex ] );
187  return *m_costring[ m_mincostindex ];
188  }
189  //! Remove the best border point
190  void RmvBest();
191  //! Check if the queue is empty
192  bool IsNotEmpty()
193  {
194  return m_costring[ m_mincostindex ] != 0;
195  }
196 
197  protected:
198  //! some constants
199  enum
200  {
201  //! number of descrete cost values ( a power of 2 )
202  m_ncost = 1024,
203  //! bit mask to project a cost value to a ring buffer index (1-m_ncost)
204  m_costmask = 1023,
205  };
206 
207  //! Memory allocation block
208  struct AllocBlock
209  {
210  enum
211  {
212  //! number of border points in an allocation block
213  m_pointsperblock = 1024
214  };
215  BorderPoint m_memory[m_pointsperblock];
216  AllocBlock* m_next;
217  };
218 
219  //! ring index of the current minimum cost (starting point or ring buffer )
220  unsigned m_mincostindex;
221  //! The starting points of the cost lists
222  BorderPoint* m_costring[m_ncost];
223  //! The starting point of the free list
225  //! Current memory allocation block
227  //! Number of free elements in memory allocation block
229 
230  public:
231 #ifdef _DEBUG
232  unsigned m_mincost;
233 #endif
234 #ifdef PRFL_ENBL
235  int m_count;
236 #endif
237  };
238 
239 protected:
240 
241  //! Get an element of the vertical occupation array
242  unsigned short& GetVerticalOccupation( int x, int y )
243  {
244  wxASSERT( x >= 0 && x <= m_width );
245  wxASSERT( y >= 0 && y <= m_height );
246  return m_verticaloccupation[ m_widthp1 * y + x ];
247  }
248 
249  //! Get an element of the horizontal occupation array
250  unsigned short& GetHorizontalOccupation( int x, int y )
251  {
252  wxASSERT( x >= 0 && x <= m_width );
253  wxASSERT( y >= 0 && y <= m_height );
254  return m_horizontaloccupation[ m_widthp1 * y + x ];
255  }
256 
257  //! Is an element of the vertical occupation array
258  bool IsVerticalOccupied( int x, int y )
259  {
260  wxASSERT( x >= 0 && x <= m_width );
261  wxASSERT( y >= 0 && y <= m_height );
262  return m_verticaloccupation[ m_widthp1 * y + x ] > 0;
263  }
264 
265  //! Is an element of the horizontal occupation array
266  bool IsHorizontalOccupied( int x, int y )
267  {
268  wxASSERT( x >= 0 && x <= m_width );
269  wxASSERT( y >= 0 && y <= m_height );
270  return m_horizontaloccupation[ m_widthp1 * y + x ] > 0;
271  }
272 
273  //! Get an element of the route point array
274  RoutePoint& GetRoutePoint( int x, int y, int dir )
275  {
276  wxASSERT( x >= 0 && x <= m_width );
277  wxASSERT( y >= 0 && y <= m_height );
278  wxASSERT( dir >= dir_min && dir <= dir_max );
279  return m_routepoints[ ( m_widthp1 * y + x ) * dir_count + ( dir - dir_min ) ];
280  }
281 
282  //! add a bounding box to the occupied area
283  /*!
284  All grid points within the rectangle are incremented by incr in the
285  vertical and horizontal occupation buffers.
286  */
287  void AddOccupationRect( const a2dBoundingBox& bbox, short incr );
288 
289  //! add a polyline to the occupation area
290  /*!
291  All vertical and horizontal lines are set into the vertical and horizontal occupation areas
292  as being occupied. That is the grid points where those lines pass, are incremented by incr.
293  */
294  void AddOccupationPolyline( const a2dVertexList* points, const a2dAffineMatrix& trns, short incr );
295 
296  //! Set a RoutePoint flag in a rectangle
297  void SetFlagRect( const a2dBoundingBox& bbox, RoutePointFlag flag );
298 
299  //! Set a RoutePoint flag along a polyline
300  /*!
301  Vertical and horizontal segments result in a set in the routepoints which the cover.
302  That is for all directions in a routepoint.
303  */
304  void SetFlagPolyline( const a2dVertexList* points, const a2dAffineMatrix& trns, RoutePointFlag flag );
305 
306  //! Set a flag in the route points for all directions
307  void SetFlagRoutePointAllDirs( int x, int y, RoutePointFlag flag )
308  {
309  RoutePoint* routepoints = &GetRoutePoint( x, y, dir_min );
310  routepoints[0].m_flags |= flag;
311  routepoints[1].m_flags |= flag;
312  routepoints[2].m_flags |= flag;
313  routepoints[3].m_flags |= flag;
314  }
315 
316  //! Add a new point on the route
317  /*! Based on the point where we are and a next point and direction,
318  a new border point is added (unless already reached).
319  The cost for the new point is calculated based on:
320  \li if is on the orginal wire +1
321  \li not on original wire +3
322  \li corner compared to current point direction +10
323  \li crossing occupied area +10 (in case of diagonal lines?)
324 
325  This is a large function, but it is inlined for speed
326  */
327  inline void AddBorderPoint(
328  BorderQueue* queue, RoutePoint* current,
329  int nextx, int nexty,
330  int dir, int prevdir
331  );
332 
333  //! Calculates the routing relevant bounding box of an object
334  /*! This includes one level of childs, but no pins
335  Pins are not included because their size may change during routing and
336  this might lead to pre-final / final inconsistencies.
337  */
338  a2dBoundingBox CalculateRoutingBbox( a2dCanvasObject* object );
339 
340  //! Dump the occupation arrays
341  void DumpOccupation( FILE* file );
342  void DumpCost();
343  void DumpVertexList( a2dVertexList* list );
344 
345  //! if true, the raster is initialized
346  bool m_ok;
347  //! the show object given in the constructor
349  //! width of the routing raster array
350  int m_width;
351  //! width of the routing raster array + 1
353  //! height of the routing raster array
354  int m_height;
355  //! height of the routing raster array + 1
357  //! the size of the raster
358  static double m_raster;
359  //! the inverse size of the raster
360  double m_rasterinv;
361  //! the limits of the raster area
362  int m_rasterminx, m_rastermaxx, m_rasterminy, m_rastermaxy;
363  //! an extra border in the raster area around the bounding box
365 
366  //! occupation counts for vertical edges ( a 2d array )
367  unsigned short* m_verticaloccupation;
368  //! occupation counts for horizontal edges ( a 2d array )
369  unsigned short* m_horizontaloccupation;
370  //! Routing points
372 
373  //! File for debug dumps
374 #ifdef DUMP_FINAL
375  FILE* m_dump;
376 #endif
377 
378  //! for wxStaticCast
379  DECLARE_DYNAMIC_CLASS( a2dRouteData )
380 
381  virtual a2dObject* DoClone( CloneOptions options, a2dRefMap* refs ) const { return NULL; };
382 
383 #if wxART2D_USE_CVGIO
384 
385  virtual void DoSave( wxObject* WXUNUSED( parent ), a2dIOHandlerXmlSerOut& WXUNUSED( out ), a2dXmlSer_flag WXUNUSED( xmlparts ), a2dObjectList* WXUNUSED( towrite ) )
386  {
387  wxASSERT( 0 );
388  }
389  virtual void DoLoad( wxObject* WXUNUSED( parent ), a2dIOHandlerXmlSerIn& WXUNUSED( parser ), a2dXmlSer_flag WXUNUSED( xmlparts ) )
390  {
391  wxASSERT( 0 );
392  }
393 
394 #endif //wxART2D_USE_CVGIO
395 };
396 
397 #endif
unsigned short * m_horizontaloccupation
occupation counts for horizontal edges ( a 2d array )
Definition: route.h:369
This is a priority queue for border points.
Definition: route.h:174
RoutePoint * m_routepoints
Routing points.
Definition: route.h:371
double m_rasterborder
an extra border in the raster area around the bounding box
Definition: route.h:364
unsigned short & GetHorizontalOccupation(int x, int y)
Get an element of the horizontal occupation array.
Definition: route.h:250
class to map references to objects stored in XML, in order to make the connection later on...
Definition: gen.h:3462
AllocBlock * m_memory
Current memory allocation block.
Definition: route.h:226
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
Load settings.
Definition: route.h:389
unsigned short m_x
coordinates of this point
Definition: route.h:160
a2dPin is used in a2dCanvasObject to add pins to it.
Definition: canpin.h:233
Ref Counted base object.
Definition: gen.h:1045
BorderPoint * m_next
pointer to the next point with same cost in the queue or to a free point
Definition: route.h:162
An entry in the border queue.
Definition: route.h:151
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:819
void SetFlagRoutePointAllDirs(int x, int y, RoutePointFlag flag)
Set a flag in the route points for all directions.
Definition: route.h:307
const BorderPoint & GetBest()
Get the best border point.
Definition: route.h:184
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
vertex list of line and arc segments.
Definition: polyver.h:600
defenitions an no more
int m_widthp1
width of the routing raster array + 1
Definition: route.h:352
unsigned int m_cost
minimum cost to reach this point
Definition: route.h:136
int m_heightp1
height of the routing raster array + 1
Definition: route.h:356
unsigned m_mincostindex
ring index of the current minimum cost (starting point or ring buffer )
Definition: route.h:220
RoutePointDirection
directions for RoutePoint
Definition: route.h:107
int m_freememory
Number of free elements in memory allocation block.
Definition: route.h:228
a2dWirePolylineL is a polyline that adjusts itself when the objects it connects move ...
Definition: wire.h:42
RoutePoint & GetRoutePoint(int x, int y, int dir)
Get an element of the route point array.
Definition: route.h:274
unsigned char m_prevdir
direction of the previous point
Definition: route.h:158
a2dCanvasObject * m_showobject
the show object given in the constructor
Definition: route.h:348
static void SetRaster(double raster)
the size of the raster
Definition: route.h:72
Class for rerouting wires.
Definition: route.h:51
virtual void DoSave(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList *towrite)
Save settings.
Definition: route.h:385
bool IsNotEmpty()
Check if the queue is empty.
Definition: route.h:192
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:862
unsigned char m_direction
direction to the source
Definition: route.h:156
Memory allocation block.
Definition: route.h:208
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
int m_width
width of the routing raster array
Definition: route.h:350
unsigned char m_prevdir
direction of the previous point
Definition: route.h:142
static double m_raster
the size of the raster
Definition: route.h:358
BorderPoint * m_freelist
The starting point of the free list.
Definition: route.h:224
unsigned short & GetVerticalOccupation(int x, int y)
Get an element of the vertical occupation array.
Definition: route.h:242
the data structure holding the per point information
Definition: route.h:133
unsigned short m_x
coordinates of this point (only set if reachable)
Definition: route.h:144
bool m_ok
if true, the raster is initialized
Definition: route.h:346
unsigned char m_direction
direction to the source (only set if reachable)
Definition: route.h:140
RoutePointFlag
flags for RoutePoint
Definition: route.h:97
bool IsHorizontalOccupied(int x, int y)
Is an element of the horizontal occupation array.
Definition: route.h:266
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
double m_rasterinv
the inverse size of the raster
Definition: route.h:360
unsigned short * m_verticaloccupation
occupation counts for vertical edges ( a 2d array )
Definition: route.h:367
unsigned short m_flags
various flags
Definition: route.h:138
int m_rasterminx
the limits of the raster area
Definition: route.h:362
int m_height
height of the routing raster array
Definition: route.h:354
list of a2dObject&#39;s
Definition: gen.h:3157
CloneOptions
options for cloning
Definition: gen.h:1200
unsigned int m_cost
minimum cost to reach this point
Definition: route.h:154
bool IsVerticalOccupied(int x, int y)
Is an element of the vertical occupation array.
Definition: route.h:258
route.h Source File -- Sun Oct 12 2014 17:04:23 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation