You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
4.8 KiB

  1. /************************/
  2. /* Autorouting routines */
  3. /************************/
  4. #include "fctsys.h"
  5. #include "common.h"
  6. #include "pcbnew.h"
  7. #include "autorout.h"
  8. #include "cell.h"
  9. struct CWORK /* a unit of work is a hole-pair to connect */
  10. {
  11. struct CWORK* Next;
  12. int FromRow; /* source row */
  13. int FromCol; /* source column */
  14. int net_code; /* net_code */
  15. int ToRow; /* target row */
  16. int ToCol; /* target column */
  17. RATSNEST_ITEM* pt_rats; /* Corresponding ratsnest */
  18. int ApxDist; /* approximate distance */
  19. int Cost; /* cost for sort by length */
  20. int Priority; /* route priority */
  21. };
  22. /* pointers to the first and last item of work to do */
  23. static CWORK* Head = NULL;
  24. static CWORK* Tail = NULL;
  25. static CWORK* Current = NULL;
  26. void InitWork();
  27. void ReInitWork();
  28. int SetWork( int, int, int, int, int, RATSNEST_ITEM*, int );
  29. void GetWork( int*, int*, int*, int*, int*, RATSNEST_ITEM** );
  30. void SortWork();
  31. /* initialize the work list */
  32. void InitWork()
  33. {
  34. CWORK* ptr;
  35. while( ( ptr = Head ) != NULL )
  36. {
  37. Head = ptr->Next;
  38. MyFree( ptr );
  39. }
  40. Tail = Current = NULL;
  41. }
  42. /* initialize the work list */
  43. void ReInitWork()
  44. {
  45. Current = Head;
  46. }
  47. /* add a unit of work to the work list
  48. * Return:
  49. * 1 if OK
  50. * 0 if memory allocation failed
  51. */
  52. static int GetCost( int r1, int c1, int r2, int c2 );
  53. int SetWork( int r1,
  54. int c1,
  55. int n_c,
  56. int r2,
  57. int c2,
  58. RATSNEST_ITEM* pt_ch,
  59. int pri )
  60. {
  61. CWORK* p;
  62. if( ( p = (CWORK*) MyMalloc( sizeof(CWORK) ) ) != NULL )
  63. {
  64. p->FromRow = r1;
  65. p->FromCol = c1;
  66. p->net_code = n_c;
  67. p->ToRow = r2;
  68. p->ToCol = c2;
  69. p->pt_rats = pt_ch;
  70. p->ApxDist = GetApxDist( r1, c1, r2, c2 );
  71. p->Cost = GetCost( r1, c1, r2, c2 );
  72. p->Priority = pri;
  73. p->Next = NULL;
  74. if( Head ) /* attach at end */
  75. Tail->Next = p;
  76. else /* first in list */
  77. Head = Current = p;
  78. Tail = p;
  79. return 1;
  80. }
  81. else /* can't get any more memory */
  82. return 0;
  83. }
  84. /* fetch a unit of work from the work list */
  85. void GetWork( int* r1,
  86. int* c1,
  87. int* n_c,
  88. int* r2,
  89. int* c2,
  90. RATSNEST_ITEM** pt_ch )
  91. {
  92. if( Current )
  93. {
  94. *r1 = Current->FromRow;
  95. *c1 = Current->FromCol;
  96. *n_c = Current->net_code;
  97. *r2 = Current->ToRow;
  98. *c2 = Current->ToCol;
  99. *pt_ch = Current->pt_rats;
  100. Current = Current->Next;
  101. }
  102. else /* none left */
  103. {
  104. *r1 = *c1 = *r2 = *c2 = ILLEGAL;
  105. *n_c = 0;
  106. *pt_ch = NULL;
  107. }
  108. }
  109. /* order the work items; shortest (low cost) first */
  110. void SortWork()
  111. {
  112. CWORK* p;
  113. CWORK* q0; /* put PRIORITY PAD_CONNECTs in q0 */
  114. CWORK* q1; /* sort other PAD_CONNECTs in q1 */
  115. CWORK* r;
  116. q0 = q1 = NULL;
  117. while( (p = Head) != NULL ) /* prioritize each work item */
  118. {
  119. Head = Head->Next;
  120. if( p->Priority ) /* put at end of priority list */
  121. {
  122. p->Next = NULL;
  123. if( (r = q0) == NULL ) /* empty list? */
  124. q0 = p;
  125. else /* attach at end */
  126. {
  127. while( r->Next ) /* search for end */
  128. r = r->Next;
  129. r->Next = p; /* attach */
  130. }
  131. }
  132. else if( ( ( r = q1 ) == NULL ) || ( p->Cost < q1->Cost ) )
  133. {
  134. p->Next = q1;
  135. q1 = p;
  136. }
  137. else /* find proper position in list */
  138. {
  139. while( r->Next && p->Cost >= r->Next->Cost )
  140. r = r->Next;
  141. p->Next = r->Next;
  142. r->Next = p;
  143. }
  144. }
  145. if( (p = q0) != NULL ) /* any priority PAD_CONNECTs? */
  146. {
  147. while( q0->Next )
  148. q0 = q0->Next;
  149. q0->Next = q1;
  150. }
  151. else
  152. p = q1;
  153. /* reposition Head and Tail */
  154. for( Head = Current = Tail = p; Tail && Tail->Next; Tail = Tail->Next )
  155. ;
  156. }
  157. /* Calculate the cost of a net:
  158. * cost = (| dx | + | dy |) * disability
  159. * disability = 1 if dx or dy = 0, max if | dx | # | dy |
  160. */
  161. static int GetCost( int r1, int c1, int r2, int c2 )
  162. {
  163. int dx, dy, mx, my;
  164. float incl;
  165. dx = abs( c2 - c1 );
  166. dy = abs( r2 - r1 );
  167. incl = 1.0;
  168. mx = dx;
  169. my = dy;
  170. if( mx < my )
  171. {
  172. mx = dy; my = dx;
  173. }
  174. if( mx )
  175. incl += (2 * (float) my / mx);
  176. return (int) ( ( dx + dy ) * incl );
  177. }