KiCad PCB EDA Suite
ar_matrix.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
7  *
8  * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 #include "ar_matrix.h"
29 #include "ar_cell.h"
30 
31 #include <common.h>
32 #include <math_for_graphics.h>
33 #include <trigo.h>
34 
35 #include <class_drawsegment.h>
36 #include <class_pad.h>
37 #include <class_track.h>
38 
40 {
41  m_BoardSide[0] = m_BoardSide[1] = nullptr;
42  m_DistSide[0] = m_DistSide[1] = nullptr;
43  m_DirSide[0] = m_DirSide[1] = nullptr;
44  m_opWriteCell = nullptr;
45  m_InitMatrixDone = false;
46  m_Nrows = 0;
47  m_Ncols = 0;
48  m_MemSize = 0;
50  m_GridRouting = 0;
51  m_RouteCount = 0;
52 }
53 
54 
56 {
57 }
58 
59 // was: bool AR_MATRIX::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly )
60 // aUseBoardEdgesOnly ? aPcb->GetBoardEdgesBoundingBox() : aPcb->GetBoundingBox();
61 
62 bool AR_MATRIX::ComputeMatrixSize( const EDA_RECT& aBoundingBox )
63 {
64  // The boundary box must have its start point on routing grid:
65  m_BrdBox = aBoundingBox;
66 
69 
70  // The boundary box must have its end point on routing grid:
71  wxPoint end = m_BrdBox.GetEnd();
72 
73  end.x -= end.x % m_GridRouting;
74  end.x += m_GridRouting;
75 
76  end.y -= end.y % m_GridRouting;
77  end.y += m_GridRouting;
78 
79  m_BrdBox.SetEnd( end );
80 
83 
84  // gives a small margin
85  m_Ncols += 1;
86  m_Nrows += 1;
87 
88  return true;
89 }
90 
91 
93 {
94  if( m_Nrows <= 0 || m_Ncols <= 0 )
95  return 0;
96 
97  m_InitMatrixDone = true; // we have been called
98 
99  // give a small margin for memory allocation:
100  int ii = ( m_Nrows + 1 ) * ( m_Ncols + 1 );
101 
102  int side = AR_SIDE_BOTTOM;
103  for( int jj = 0; jj < m_RoutingLayersCount; jj++ ) // m_RoutingLayersCount = 1 or 2
104  {
105  m_BoardSide[side] = nullptr;
106  m_DistSide[side] = nullptr;
107  m_DirSide[side] = nullptr;
108 
109  // allocate matrix & initialize everything to empty
110  m_BoardSide[side] = (MATRIX_CELL*) operator new( ii * sizeof( MATRIX_CELL ) );
111  memset( m_BoardSide[side], 0, ii * sizeof( MATRIX_CELL ) );
112 
113  if( m_BoardSide[side] == nullptr )
114  return -1;
115 
116  // allocate Distances
117  m_DistSide[side] = (DIST_CELL*) operator new( ii * sizeof( DIST_CELL ) );
118  memset( m_DistSide[side], 0, ii * sizeof( DIST_CELL ) );
119 
120  if( m_DistSide[side] == nullptr )
121  return -1;
122 
123  // allocate Dir (chars)
124  m_DirSide[side] = (char*) operator new( ii );
125  memset( m_DirSide[side], 0, ii );
126 
127  if( m_DirSide[side] == nullptr )
128  return -1;
129 
130  side = AR_SIDE_TOP;
131  }
132 
133  m_MemSize =
134  m_RouteCount * ii * ( sizeof( MATRIX_CELL ) + sizeof( DIST_CELL ) + sizeof( char ) );
135 
136  return m_MemSize;
137 }
138 
139 
141 {
142  int ii;
143 
144  m_InitMatrixDone = false;
145 
146  for( ii = 0; ii < AR_MAX_ROUTING_LAYERS_COUNT; ii++ )
147  {
148  // de-allocate Dir matrix
149  if( m_DirSide[ii] )
150  {
151  delete m_DirSide[ii];
152  m_DirSide[ii] = nullptr;
153  }
154 
155  // de-allocate Distances matrix
156  if( m_DistSide[ii] )
157  {
158  delete m_DistSide[ii];
159  m_DistSide[ii] = nullptr;
160  }
161 
162  // de-allocate cells matrix
163  if( m_BoardSide[ii] )
164  {
165  delete m_BoardSide[ii];
166  m_BoardSide[ii] = nullptr;
167  }
168  }
169 
170  m_Nrows = m_Ncols = 0;
171 }
172 
173 // Initialize m_opWriteCell member to make the aLogicOp
175 {
176  switch( aLogicOp )
177  {
178  default:
180 
182 
184 
186 
188  }
189 }
190 
191 
192 /* return the value stored in a cell
193  */
194 AR_MATRIX::MATRIX_CELL AR_MATRIX::GetCell( int aRow, int aCol, int aSide )
195 {
196  MATRIX_CELL* p;
197 
198  p = m_BoardSide[aSide];
199  return p[aRow * m_Ncols + aCol];
200 }
201 
202 
203 /* basic cell operation : WRITE operation
204  */
205 void AR_MATRIX::SetCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
206 {
207  MATRIX_CELL* p;
208 
209  p = m_BoardSide[aSide];
210  p[aRow * m_Ncols + aCol] = x;
211 }
212 
213 
214 /* basic cell operation : OR operation
215  */
216 void AR_MATRIX::OrCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
217 {
218  MATRIX_CELL* p;
219 
220  p = m_BoardSide[aSide];
221  p[aRow * m_Ncols + aCol] |= x;
222 }
223 
224 
225 /* basic cell operation : XOR operation
226  */
227 void AR_MATRIX::XorCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
228 {
229  MATRIX_CELL* p;
230 
231  p = m_BoardSide[aSide];
232  p[aRow * m_Ncols + aCol] ^= x;
233 }
234 
235 
236 /* basic cell operation : AND operation
237  */
238 void AR_MATRIX::AndCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
239 {
240  MATRIX_CELL* p;
241 
242  p = m_BoardSide[aSide];
243  p[aRow * m_Ncols + aCol] &= x;
244 }
245 
246 
247 /* basic cell operation : ADD operation
248  */
249 void AR_MATRIX::AddCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
250 {
251  MATRIX_CELL* p;
252 
253  p = m_BoardSide[aSide];
254  p[aRow * m_Ncols + aCol] += x;
255 }
256 
257 
258 // fetch distance cell
259 AR_MATRIX::DIST_CELL AR_MATRIX::GetDist( int aRow, int aCol, int aSide ) // fetch distance cell
260 {
261  DIST_CELL* p;
262 
263  p = m_DistSide[aSide];
264  return p[aRow * m_Ncols + aCol];
265 }
266 
267 
268 // store distance cell
269 void AR_MATRIX::SetDist( int aRow, int aCol, int aSide, DIST_CELL x )
270 {
271  DIST_CELL* p;
272 
273  p = m_DistSide[aSide];
274  p[aRow * m_Ncols + aCol] = x;
275 }
276 
277 
278 // fetch direction cell
279 int AR_MATRIX::GetDir( int aRow, int aCol, int aSide )
280 {
281  DIR_CELL* p;
282 
283  p = m_DirSide[aSide];
284  return (int) ( p[aRow * m_Ncols + aCol] );
285 }
286 
287 
288 // store direction cell
289 void AR_MATRIX::SetDir( int aRow, int aCol, int aSide, int x )
290 {
291  DIR_CELL* p;
292 
293  p = m_DirSide[aSide];
294  p[aRow * m_Ncols + aCol] = (char) x;
295 }
296 
297 /* The tables of distances and keep out areas are established on the basis of a
298  * 50 units grid size (the pitch between the cells is 50 units).
299  * The actual distance could be computed by a scaling factor, but this is
300  * not needed, we can use only reduced values
301  */
302 
303 /* calculate approximate distance (manhattan distance)
304  */
305 int AR_MATRIX::GetApxDist( int r1, int c1, int r2, int c2 )
306 {
307  int d1, d2; /* row and column deltas */
308 
309  if( ( d1 = r1 - r2 ) < 0 ) /* get absolute row delta */
310  d1 = -d1;
311 
312  if( ( d2 = c1 - c2 ) < 0 ) /* get absolute column delta */
313  d2 = -d2;
314 
315  return ( d1 + d2 ) * 50;
316 }
317 
318 
319 /* distance to go thru a cell (en mils) */
320 static const int dist[10][10] = { /* OT=Otherside, OR=Origin (source) cell */
321  /*..........N, NE, E, SE, S, SW, W, NW, OT, OR */
322  /* N */ { 50, 60, 35, 60, 99, 60, 35, 60, 12, 12 },
323  /* NE */ { 60, 71, 60, 71, 60, 99, 60, 71, 23, 23 },
324  /* E */ { 35, 60, 50, 60, 35, 60, 99, 60, 12, 12 },
325  /* SE */ { 60, 71, 60, 71, 60, 71, 60, 99, 23, 23 },
326  /* S */ { 99, 60, 35, 60, 50, 60, 35, 60, 12, 12 },
327  /* SW */ { 60, 99, 60, 71, 60, 71, 60, 71, 23, 23 },
328  /* W */ { 35, 60, 99, 60, 35, 60, 50, 60, 12, 12 },
329  /* NW */ { 60, 71, 60, 99, 60, 71, 60, 71, 23, 23 },
330 
331  /* OT */ { 12, 23, 12, 23, 12, 23, 12, 23, 99, 99 },
332  /* OR */ { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }
333 };
334 
335 
336 /* penalty for extraneous holes and corners, scaled by sharpness of turn */
337 static const int penalty[10][10] = { /* OT=Otherside, OR=Origin (source) cell */
338  /*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
339  /* N */ { 0, 5, 10, 15, 20, 15, 10, 5, 50, 0 },
340  /* NE */ { 5, 0, 5, 10, 15, 20, 15, 10, 50, 0 },
341  /* E */ { 10, 5, 0, 5, 10, 15, 20, 15, 50, 0 },
342  /* SE */ { 15, 10, 5, 0, 5, 10, 15, 20, 50, 0 },
343  /* S */ { 20, 15, 10, 5, 0, 5, 10, 15, 50, 0 },
344  /* SW */ { 15, 20, 15, 10, 5, 0, 5, 10, 50, 0 },
345  /* W */ { 10, 15, 20, 15, 10, 5, 0, 5, 50, 0 },
346  /* NW */ { 5, 10, 15, 20, 15, 10, 5, 0, 50, 0 },
347 
348  /* OT */ { 50, 50, 50, 50, 50, 50, 50, 50, 100, 0 },
349  /* OR */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
350 };
351 
352 
353 /* penalty pour directions preferencielles */
354 #define PN 20
355 static const int dir_penalty_TOP[10][10] = {
356  /* OT=Otherside, OR=Origin (source) cell */
357  /*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
358  /* N */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
359  /* NE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
360  /* E */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
361  /* SE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
362  /* S */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
363  /* SW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
364  /* W */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
365  /* NW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
366 
367  /* OT */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
368  /* OR */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 }
369 };
370 
371 
372 static int dir_penalty_BOTTOM[10][10] = {
373  /* OT=Otherside, OR=Origin (source) cell */
374  /*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
375  /* N */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
376  /* NE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
377  /* E */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
378  /* SE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
379  /* S */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
380  /* SW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
381  /* W */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
382  /* NW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
383 
384  /* OT */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
385  /* OR */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 }
386 };
387 
388 /*
389 ** x is the direction to enter the cell of interest.
390 ** y is the direction to exit the cell of interest.
391 ** z is the direction to really exit the cell, if y=FROM_OTHERSIDE.
392 **
393 ** return the distance of the trace through the cell of interest.
394 ** the calculation is driven by the tables above.
395 */
396 
397 
398 /* calculate distance (with penalty) of a trace through a cell
399 */
400 int AR_MATRIX::CalcDist( int x, int y, int z, int side )
401 {
402  int adjust, ldist;
403 
404  adjust = 0; /* set if hole is encountered */
405 
406  if( x == CELL_IS_EMPTY )
407  x = 10;
408 
409  if( y == CELL_IS_EMPTY )
410  {
411  y = 10;
412  }
413  else if( y == FROM_OTHERSIDE )
414  {
415  if( z == CELL_IS_EMPTY )
416  z = 10;
417 
418  adjust = penalty[x - 1][z - 1];
419  }
420 
421  ldist = dist[x - 1][y - 1] + penalty[x - 1][y - 1] + adjust;
422 
423  if( m_RouteCount > 1 )
424  {
425  if( side == AR_SIDE_BOTTOM )
426  ldist += dir_penalty_TOP[x - 1][y - 1];
427 
428  if( side == AR_SIDE_TOP )
429  ldist += dir_penalty_BOTTOM[x - 1][y - 1];
430  }
431 
432  return ldist * 10;
433 }
434 
435 
436 #define OP_CELL( layer, dy, dx ) \
437  { \
438  if( layer == UNDEFINED_LAYER ) \
439  { \
440  WriteCell( dy, dx, AR_SIDE_BOTTOM, color ); \
441  if( m_RoutingLayersCount > 1 ) \
442  WriteCell( dy, dx, AR_SIDE_TOP, color ); \
443  } \
444  else \
445  { \
446  if( layer == m_routeLayerBottom ) \
447  WriteCell( dy, dx, AR_SIDE_BOTTOM, color ); \
448  if( m_RoutingLayersCount > 1 ) \
449  if( layer == m_routeLayerTop ) \
450  WriteCell( dy, dx, AR_SIDE_TOP, color ); \
451  } \
452  }
453 
454 /* Fills all cells inside a segment
455  * half-width = lg, org = ux0,uy0 end = ux1,uy1
456  * coordinates are in PCB units
457  */
458 void AR_MATRIX::drawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
459  int color, AR_MATRIX::CELL_OP op_logic )
460 {
461  int64_t row, col;
462  int64_t inc;
463  int64_t row_max, col_max, row_min, col_min;
464  int64_t demi_pas;
465 
466  int cx, cy, dx, dy;
467 
468 
469  //printf("segmQcq %d %d %d %d\n", ux0, uy0, ux1, uy1);
470 
471  SetCellOperation( op_logic );
472 
473  // Make coordinate ux1 tj > ux0 to simplify calculations
474  if( ux1 < ux0 )
475  {
476  std::swap( ux1, ux0 );
477  std::swap( uy1, uy0 );
478  }
479 
480  // Calculating the incrementing the Y axis
481  inc = 1;
482 
483  if( uy1 < uy0 )
484  inc = -1;
485 
486  demi_pas = m_GridRouting / 2;
487 
488  col_min = ( ux0 - lg ) / m_GridRouting;
489 
490  if( col_min < 0 )
491  col_min = 0;
492 
493  col_max = ( ux1 + lg + demi_pas ) / m_GridRouting;
494 
495  if( col_max > ( m_Ncols - 1 ) )
496  col_max = m_Ncols - 1;
497 
498  if( inc > 0 )
499  {
500  row_min = ( uy0 - lg ) / m_GridRouting;
501  row_max = ( uy1 + lg + demi_pas ) / m_GridRouting;
502  }
503  else
504  {
505  row_min = ( uy1 - lg ) / m_GridRouting;
506  row_max = ( uy0 + lg + demi_pas ) / m_GridRouting;
507  }
508 
509  if( row_min < 0 )
510  row_min = 0;
511 
512  if( row_min > ( m_Nrows - 1 ) )
513  row_min = m_Nrows - 1;
514 
515  if( row_max < 0 )
516  row_max = 0;
517 
518  if( row_max > ( m_Nrows - 1 ) )
519  row_max = m_Nrows - 1;
520 
521  dx = ux1 - ux0;
522  dy = uy1 - uy0;
523 
524  double angle;
525  if( dx )
526  {
527  angle = ArcTangente( dy, dx );
528  }
529  else
530  {
531  angle = 900;
532 
533  if( dy < 0 )
534  angle = -900;
535  }
536 
537  RotatePoint( &dx, &dy, angle ); // dx = length, dy = 0
538 
539 
540  //printf("col_min %d max %d row_min %d max %d\n", col_min, col_max, row_min, row_max);
541 
542  for( col = col_min; col <= col_max; col++ )
543  {
544  int64_t cxr;
545  cxr = ( col * m_GridRouting ) - ux0;
546 
547  for( row = row_min; row <= row_max; row++ )
548  {
549  cy = ( row * m_GridRouting ) - uy0;
550  cx = cxr;
551  RotatePoint( &cx, &cy, angle );
552 
553  if( abs( cy ) > lg )
554  continue; // The point is too far on the Y axis.
555 
556  /* This point a test is close to the segment: the position
557  * along the X axis must be tested.
558  */
559  if( ( cx >= 0 ) && ( cx <= dx ) )
560  {
561  OP_CELL( layer, row, col );
562  continue;
563  }
564 
565  // Examination of extremities are rounded.
566  if( ( cx < 0 ) && ( cx >= -lg ) )
567  {
568  if( ( ( cx * cx ) + ( cy * cy ) ) <= ( lg * lg ) )
569  OP_CELL( layer, row, col );
570 
571  continue;
572  }
573 
574  if( ( cx > dx ) && ( cx <= ( dx + lg ) ) )
575  {
576  if( ( ( ( cx - dx ) * ( cx - dx ) ) + ( cy * cy ) ) <= ( lg * lg ) )
577  OP_CELL( layer, row, col );
578 
579  continue;
580  }
581  }
582  }
583 }
584 
585 
586 /* Fills all cells of the routing matrix contained in the circle
587  * half-width = lg, center = ux0, uy0, ux1,uy1 is a point on the circle.
588  * coord are in PCB units.
589  */
590 void AR_MATRIX::traceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer, int color,
591  AR_MATRIX::CELL_OP op_logic )
592 {
593  int radius, nb_segm;
594  int x0, y0, // Starting point of the current segment trace.
595  x1, y1; // End point.
596  int ii;
597  int angle;
598 
599  radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
600 
601  x0 = x1 = radius;
602  y0 = y1 = 0;
603 
604  if( lg < 1 )
605  lg = 1;
606 
607  nb_segm = ( 2 * radius ) / lg;
608 
609  if( nb_segm < 5 )
610  nb_segm = 5;
611 
612  if( nb_segm > 100 )
613  nb_segm = 100;
614 
615  for( ii = 1; ii < nb_segm; ii++ )
616  {
617  angle = ( 3600 * ii ) / nb_segm;
618  x1 = KiROUND( cosdecideg( radius, angle ) );
619  y1 = KiROUND( sindecideg( radius, angle ) );
620  drawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic );
621  x0 = x1;
622  y0 = y1;
623  }
624 
625  drawSegmentQcq( x1 + ux0, y1 + uy0, ux0 + radius, uy0, lg, layer, color, op_logic );
626 }
627 
628 
630  int cx, int cy, int radius, LSET aLayerMask, int color, AR_MATRIX::CELL_OP op_logic )
631 {
632  int row, col;
633  int ux0, uy0, ux1, uy1;
634  int row_max, col_max, row_min, col_min;
635  int trace = 0;
636  double fdistmin, fdistx, fdisty;
637  int tstwrite = 0;
638  int distmin;
639 
640  if( aLayerMask[m_routeLayerBottom] )
641  trace = 1; // Trace on BOTTOM
642 
643  if( aLayerMask[m_routeLayerTop] )
644  if( m_RoutingLayersCount > 1 )
645  trace |= 2; // Trace on TOP
646 
647  if( trace == 0 )
648  return;
649 
650  SetCellOperation( op_logic );
651 
652  cx -= GetBrdCoordOrigin().x;
653  cy -= GetBrdCoordOrigin().y;
654 
655  distmin = radius;
656 
657  // Calculate the bounding rectangle of the circle.
658  ux0 = cx - radius;
659  uy0 = cy - radius;
660  ux1 = cx + radius;
661  uy1 = cy + radius;
662 
663  // Calculate limit coordinates of cells belonging to the rectangle.
664  row_max = uy1 / m_GridRouting;
665  col_max = ux1 / m_GridRouting;
666  row_min = uy0 / m_GridRouting; // if (uy0 > row_min*Board.m_GridRouting) row_min++;
667  col_min = ux0 / m_GridRouting; // if (ux0 > col_min*Board.m_GridRouting) col_min++;
668 
669  if( row_min < 0 )
670  row_min = 0;
671 
672  if( row_max >= ( m_Nrows - 1 ) )
673  row_max = m_Nrows - 1;
674 
675  if( col_min < 0 )
676  col_min = 0;
677 
678  if( col_max >= ( m_Ncols - 1 ) )
679  col_max = m_Ncols - 1;
680 
681  // Calculate coordinate limits of cell belonging to the rectangle.
682  if( row_min > row_max )
683  row_max = row_min;
684 
685  if( col_min > col_max )
686  col_max = col_min;
687 
688  fdistmin = (double) distmin * distmin;
689 
690  for( row = row_min; row <= row_max; row++ )
691  {
692  fdisty = (double) ( cy - ( row * m_GridRouting ) );
693  fdisty *= fdisty;
694 
695  for( col = col_min; col <= col_max; col++ )
696  {
697  fdistx = (double) ( cx - ( col * m_GridRouting ) );
698  fdistx *= fdistx;
699 
700  if( fdistmin <= ( fdistx + fdisty ) )
701  continue;
702 
703  if( trace & 1 )
704  WriteCell( row, col, AR_SIDE_BOTTOM, color );
705 
706  if( trace & 2 )
707  WriteCell( row, col, AR_SIDE_TOP, color );
708 
709  tstwrite = 1;
710  }
711  }
712 
713  if( tstwrite )
714  return;
715 
716  /* If no cell has been written, it affects the 4 neighboring diagonal
717  * (Adverse event: pad off grid in the center of the 4 neighboring
718  * diagonal) */
719  distmin = m_GridRouting / 2 + 1;
720  fdistmin = ( (double) distmin * distmin ) * 2; // Distance to center point diagonally
721 
722  for( row = row_min; row <= row_max; row++ )
723  {
724  fdisty = (double) ( cy - ( row * m_GridRouting ) );
725  fdisty *= fdisty;
726 
727  for( col = col_min; col <= col_max; col++ )
728  {
729  fdistx = (double) ( cx - ( col * m_GridRouting ) );
730  fdistx *= fdistx;
731 
732  if( fdistmin <= ( fdistx + fdisty ) )
733  continue;
734 
735  if( trace & 1 )
736  WriteCell( row, col, AR_SIDE_BOTTOM, color );
737 
738  if( trace & 2 )
739  WriteCell( row, col, AR_SIDE_TOP, color );
740  }
741  }
742 }
743 
744 
745 /* Fills all routing matrix cells contained in the arc
746  * angle = ArcAngle, half-width lg
747  * center = ux0,uy0, starting at ux1, uy1. Coordinates are in
748  * PCB units.
749  */
750 void AR_MATRIX::traceArc( int ux0, int uy0, int ux1, int uy1, double ArcAngle, int lg,
751  LAYER_NUM layer, int color, AR_MATRIX::CELL_OP op_logic )
752 {
753  int radius, nb_segm;
754  int x0, y0, // Starting point of the current segment trace
755  x1, y1; // End point
756  int ii;
757  double angle, StAngle;
758 
759 
760  radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
761 
762  x0 = ux1 - ux0;
763  y0 = uy1 - uy0;
764  StAngle = ArcTangente( uy1 - uy0, ux1 - ux0 );
765 
766  if( lg < 1 )
767  lg = 1;
768 
769  nb_segm = ( 2 * radius ) / lg;
770  nb_segm = ( nb_segm * std::abs( ArcAngle ) ) / 3600;
771 
772  if( nb_segm < 5 )
773  nb_segm = 5;
774 
775  if( nb_segm > 100 )
776  nb_segm = 100;
777 
778  for( ii = 1; ii <= nb_segm; ii++ )
779  {
780  angle = ( ArcAngle * ii ) / nb_segm;
781  angle += StAngle;
782 
783  NORMALIZE_ANGLE_POS( angle );
784 
785  x1 = KiROUND( cosdecideg( radius, angle ) );
786  y1 = KiROUND( cosdecideg( radius, angle ) );
787  drawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic );
788  x0 = x1;
789  y0 = y1;
790  }
791 }
792 
793 
794 void AR_MATRIX::TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1, double angle,
795  LSET aLayerMask, int color, AR_MATRIX::CELL_OP op_logic )
796 {
797  int row, col;
798  int cx, cy; // Center of rectangle
799  int radius; // Radius of the circle
800  int row_min, row_max, col_min, col_max;
801  int rotrow, rotcol;
802  int trace = 0;
803 
804  if( aLayerMask[m_routeLayerBottom] )
805  trace = 1; // Trace on BOTTOM
806 
807  if( aLayerMask[m_routeLayerTop] )
808  {
809  if( m_RoutingLayersCount > 1 )
810  trace |= 2; // Trace on TOP
811  }
812 
813  if( trace == 0 )
814  return;
815 
816  SetCellOperation( op_logic );
817 
818  ux0 -= GetBrdCoordOrigin().x;
819  uy0 -= GetBrdCoordOrigin().y;
820  ux1 -= GetBrdCoordOrigin().x;
821  uy1 -= GetBrdCoordOrigin().y;
822 
823  cx = ( ux0 + ux1 ) / 2;
824  cy = ( uy0 + uy1 ) / 2;
825  radius = KiROUND( Distance( ux0, uy0, cx, cy ) );
826 
827  // Calculating coordinate limits belonging to the rectangle.
828  row_max = ( cy + radius ) / m_GridRouting;
829  col_max = ( cx + radius ) / m_GridRouting;
830  row_min = ( cy - radius ) / m_GridRouting;
831 
832  if( uy0 > row_min * m_GridRouting )
833  row_min++;
834 
835  col_min = ( cx - radius ) / m_GridRouting;
836 
837  if( ux0 > col_min * m_GridRouting )
838  col_min++;
839 
840  if( row_min < 0 )
841  row_min = 0;
842 
843  if( row_max >= ( m_Nrows - 1 ) )
844  row_max = m_Nrows - 1;
845 
846  if( col_min < 0 )
847  col_min = 0;
848 
849  if( col_max >= ( m_Ncols - 1 ) )
850  col_max = m_Ncols - 1;
851 
852  for( row = row_min; row <= row_max; row++ )
853  {
854  for( col = col_min; col <= col_max; col++ )
855  {
856  rotrow = row * m_GridRouting;
857  rotcol = col * m_GridRouting;
858  RotatePoint( &rotcol, &rotrow, cx, cy, -angle );
859 
860  if( rotrow <= uy0 )
861  continue;
862 
863  if( rotrow >= uy1 )
864  continue;
865 
866  if( rotcol <= ux0 )
867  continue;
868 
869  if( rotcol >= ux1 )
870  continue;
871 
872  if( trace & 1 )
873  WriteCell( row, col, AR_SIDE_BOTTOM, color );
874 
875  if( trace & 2 )
876  WriteCell( row, col, AR_SIDE_TOP, color );
877  }
878  }
879 }
880 
881 
882 void AR_MATRIX::TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1, LSET aLayerMask,
883  int color, AR_MATRIX::CELL_OP op_logic )
884 {
885  int row, col;
886  int row_min, row_max, col_min, col_max;
887  int trace = 0;
888 
889  if( aLayerMask[m_routeLayerBottom] )
890  trace = 1; // Trace on BOTTOM
891 
892  if( aLayerMask[m_routeLayerTop] && m_RoutingLayersCount > 1 )
893  trace |= 2; // Trace on TOP
894 
895  if( trace == 0 )
896  return;
897 
898  SetCellOperation( op_logic );
899 
900  ux0 -= GetBrdCoordOrigin().x;
901  uy0 -= GetBrdCoordOrigin().y;
902  ux1 -= GetBrdCoordOrigin().x;
903  uy1 -= GetBrdCoordOrigin().y;
904 
905  // Calculating limits coord cells belonging to the rectangle.
906  row_max = uy1 / m_GridRouting;
907  col_max = ux1 / m_GridRouting;
908  row_min = uy0 / m_GridRouting;
909 
910  if( uy0 > row_min * m_GridRouting )
911  row_min++;
912 
913  col_min = ux0 / m_GridRouting;
914 
915  if( ux0 > col_min * m_GridRouting )
916  col_min++;
917 
918  if( row_min < 0 )
919  row_min = 0;
920 
921  if( row_max >= ( m_Nrows - 1 ) )
922  row_max = m_Nrows - 1;
923 
924  if( col_min < 0 )
925  col_min = 0;
926 
927  if( col_max >= ( m_Ncols - 1 ) )
928  col_max = m_Ncols - 1;
929 
930  for( row = row_min; row <= row_max; row++ )
931  {
932  for( col = col_min; col <= col_max; col++ )
933  {
934  if( trace & 1 )
935  WriteCell( row, col, AR_SIDE_BOTTOM, color );
936 
937  if( trace & 2 )
938  WriteCell( row, col, AR_SIDE_TOP, color );
939  }
940  }
941 }
942 
943 
944 /* Draws a line, if layer = -1 on all layers
945  */
947  int x0, int y0, int x1, int y1, LAYER_NUM layer, int color, AR_MATRIX::CELL_OP op_logic )
948 {
949  int dx, dy, lim;
950  int cumul, inc, il, delta;
951 
952  SetCellOperation( op_logic );
953 
954  if( x0 == x1 ) // Vertical.
955  {
956  if( y1 < y0 )
957  std::swap( y0, y1 );
958 
959  dy = y0 / m_GridRouting;
960  lim = y1 / m_GridRouting;
961  dx = x0 / m_GridRouting;
962 
963  // Clipping limits of board.
964  if( ( dx < 0 ) || ( dx >= m_Ncols ) )
965  return;
966 
967  if( dy < 0 )
968  dy = 0;
969 
970  if( lim >= m_Nrows )
971  lim = m_Nrows - 1;
972 
973  for( ; dy <= lim; dy++ )
974  {
975  OP_CELL( layer, dy, dx );
976  }
977 
978  return;
979  }
980 
981  if( y0 == y1 ) // Horizontal
982  {
983  if( x1 < x0 )
984  std::swap( x0, x1 );
985 
986  dx = x0 / m_GridRouting;
987  lim = x1 / m_GridRouting;
988  dy = y0 / m_GridRouting;
989 
990  // Clipping limits of board.
991  if( ( dy < 0 ) || ( dy >= m_Nrows ) )
992  return;
993 
994  if( dx < 0 )
995  dx = 0;
996 
997  if( lim >= m_Ncols )
998  lim = m_Ncols - 1;
999 
1000  for( ; dx <= lim; dx++ )
1001  {
1002  OP_CELL( layer, dy, dx );
1003  }
1004 
1005  return;
1006  }
1007 
1008  // Here is some perspective: using the algorithm LUCAS.
1009  if( abs( x1 - x0 ) >= abs( y1 - y0 ) ) // segment slightly inclined/
1010  {
1011  if( x1 < x0 )
1012  {
1013  std::swap( x1, x0 );
1014  std::swap( y1, y0 );
1015  }
1016 
1017  dx = x0 / m_GridRouting;
1018  lim = x1 / m_GridRouting;
1019  dy = y0 / m_GridRouting;
1020  inc = 1;
1021 
1022  if( y1 < y0 )
1023  inc = -1;
1024 
1025  il = lim - dx;
1026  cumul = il / 2;
1027  delta = abs( y1 - y0 ) / m_GridRouting;
1028 
1029  for( ; dx <= lim; )
1030  {
1031  if( ( dx >= 0 ) && ( dy >= 0 ) && ( dx < m_Ncols ) && ( dy < m_Nrows ) )
1032  {
1033  OP_CELL( layer, dy, dx );
1034  }
1035 
1036  dx++;
1037  cumul += delta;
1038 
1039  if( cumul > il )
1040  {
1041  cumul -= il;
1042  dy += inc;
1043  }
1044  }
1045  }
1046  else
1047  {
1048  if( y1 < y0 )
1049  {
1050  std::swap( x1, x0 );
1051  std::swap( y1, y0 );
1052  }
1053 
1054  dy = y0 / m_GridRouting;
1055  lim = y1 / m_GridRouting;
1056  dx = x0 / m_GridRouting;
1057  inc = 1;
1058 
1059  if( x1 < x0 )
1060  inc = -1;
1061 
1062  il = lim - dy;
1063  cumul = il / 2;
1064  delta = abs( x1 - x0 ) / m_GridRouting;
1065 
1066  for( ; dy <= lim; )
1067  {
1068  if( ( dx >= 0 ) && ( dy >= 0 ) && ( dx < m_Ncols ) && ( dy < m_Nrows ) )
1069  {
1070  OP_CELL( layer, dy, dx );
1071  }
1072 
1073  dy++;
1074  cumul += delta;
1075 
1076  if( cumul > il )
1077  {
1078  cumul -= il;
1079  dx += inc;
1080  }
1081  }
1082  }
1083 }
1084 
1086  DRAWSEGMENT* pt_segm, int color, int marge, AR_MATRIX::CELL_OP op_logic )
1087 {
1088  int half_width = ( pt_segm->GetWidth() / 2 ) + marge;
1089 
1090  // Calculate the bounding rectangle of the segment (if H, V or Via)
1091  int ux0 = pt_segm->GetStart().x - GetBrdCoordOrigin().x;
1092  int uy0 = pt_segm->GetStart().y - GetBrdCoordOrigin().y;
1093  int ux1 = pt_segm->GetEnd().x - GetBrdCoordOrigin().x;
1094  int uy1 = pt_segm->GetEnd().y - GetBrdCoordOrigin().y;
1095 
1096  //printf("traceSegm %d %d %d %d\n", ux0, uy0, ux1, uy1);
1097 
1098  LAYER_NUM layer = pt_segm->GetLayer();
1099 
1100  //if( color == VIA_IMPOSSIBLE )
1101  layer = UNDEFINED_LAYER;
1102 
1103 
1104  switch( pt_segm->GetShape() )
1105  {
1106  // The segment is here a straight line or a circle or an arc.:
1107  case S_CIRCLE: traceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); break;
1108 
1109  case S_ARC:
1110  traceArc( ux0, uy0, ux1, uy1, pt_segm->GetAngle(), half_width, layer, color, op_logic );
1111  break;
1112 
1113  // The segment is here a line segment.
1114  default: drawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); break;
1115  }
1116 }
1117 
1118 
1119 void AR_MATRIX::TraceSegmentPcb( TRACK* aTrack, int color, int marge, AR_MATRIX::CELL_OP op_logic )
1120 {
1121  int half_width = ( aTrack->GetWidth() / 2 ) + marge;
1122 
1123  // Test if VIA (filled circle need to be drawn)
1124  if( aTrack->Type() == PCB_VIA_T )
1125  {
1126  LSET layer_mask;
1127 
1128  if( aTrack->IsOnLayer( m_routeLayerBottom ) )
1129  layer_mask.set( m_routeLayerBottom );
1130 
1131  if( aTrack->IsOnLayer( m_routeLayerTop ) )
1132  {
1133  if( !layer_mask.any() )
1134  layer_mask = LSET( m_routeLayerTop );
1135  else
1136  layer_mask.set();
1137  }
1138 
1139  if( color == VIA_IMPOSSIBLE )
1140  layer_mask.set();
1141 
1142  if( layer_mask.any() )
1143  traceFilledCircle( aTrack->GetStart().x, aTrack->GetStart().y, half_width, layer_mask,
1144  color, op_logic );
1145  }
1146  else
1147  {
1148  // Calculate the bounding rectangle of the segment
1149  int ux0 = aTrack->GetStart().x - GetBrdCoordOrigin().x;
1150  int uy0 = aTrack->GetStart().y - GetBrdCoordOrigin().y;
1151  int ux1 = aTrack->GetEnd().x - GetBrdCoordOrigin().x;
1152  int uy1 = aTrack->GetEnd().y - GetBrdCoordOrigin().y;
1153 
1154  // Ordinary track
1155  PCB_LAYER_ID layer = aTrack->GetLayer();
1156 
1157  if( color == VIA_IMPOSSIBLE )
1158  layer = UNDEFINED_LAYER;
1159 
1160  drawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
1161  }
1162 }
1163 
1164 
1176  int ux0, int uy0, int ux1, int uy1, int marge, int aKeepOut, LSET aLayerMask )
1177 {
1178  int row, col;
1179  int row_min, row_max, col_min, col_max, pmarge;
1180  int trace = 0;
1181  DIST_CELL data, LocalKeepOut;
1182  int lgain, cgain;
1183 
1184  if( aLayerMask[m_routeLayerBottom] )
1185  trace = 1; // Trace on bottom layer.
1186 
1187  if( aLayerMask[m_routeLayerTop] && m_RoutingLayersCount )
1188  trace |= 2; // Trace on top layer.
1189 
1190  if( trace == 0 )
1191  return;
1192 
1193  ux0 -= m_BrdBox.GetX();
1194  uy0 -= m_BrdBox.GetY();
1195  ux1 -= m_BrdBox.GetX();
1196  uy1 -= m_BrdBox.GetY();
1197 
1198  ux0 -= marge;
1199  ux1 += marge;
1200  uy0 -= marge;
1201  uy1 += marge;
1202 
1203  pmarge = marge / m_GridRouting;
1204 
1205  if( pmarge < 1 )
1206  pmarge = 1;
1207 
1208  // Calculate the coordinate limits of the rectangle.
1209  row_max = uy1 / m_GridRouting;
1210  col_max = ux1 / m_GridRouting;
1211  row_min = uy0 / m_GridRouting;
1212 
1213  if( uy0 > row_min * m_GridRouting )
1214  row_min++;
1215 
1216  col_min = ux0 / m_GridRouting;
1217 
1218  if( ux0 > col_min * m_GridRouting )
1219  col_min++;
1220 
1221  if( row_min < 0 )
1222  row_min = 0;
1223 
1224  if( row_max >= ( m_Nrows - 1 ) )
1225  row_max = m_Nrows - 1;
1226 
1227  if( col_min < 0 )
1228  col_min = 0;
1229 
1230  if( col_max >= ( m_Ncols - 1 ) )
1231  col_max = m_Ncols - 1;
1232 
1233  for( row = row_min; row <= row_max; row++ )
1234  {
1235  lgain = 256;
1236 
1237  if( row < pmarge )
1238  lgain = ( 256 * row ) / pmarge;
1239  else if( row > row_max - pmarge )
1240  lgain = ( 256 * ( row_max - row ) ) / pmarge;
1241 
1242  for( col = col_min; col <= col_max; col++ )
1243  {
1244  // RoutingMatrix Dist map containt the "cost" of the cell
1245  // at position (row, col)
1246  // in autoplace this is the cost of the cell, when
1247  // a footprint overlaps it, near a "master" footprint
1248  // this cost is hight near the "master" footprint
1249  // and decrease with the distance
1250  cgain = 256;
1251  LocalKeepOut = aKeepOut;
1252 
1253  if( col < pmarge )
1254  cgain = ( 256 * col ) / pmarge;
1255  else if( col > col_max - pmarge )
1256  cgain = ( 256 * ( col_max - col ) ) / pmarge;
1257 
1258  cgain = ( cgain * lgain ) / 256;
1259 
1260  if( cgain != 256 )
1261  LocalKeepOut = ( LocalKeepOut * cgain ) / 256;
1262 
1263  if( trace & 1 )
1264  {
1265  data = GetDist( row, col, AR_SIDE_BOTTOM ) + LocalKeepOut;
1266  SetDist( row, col, AR_SIDE_BOTTOM, data );
1267  }
1268 
1269  if( trace & 2 )
1270  {
1271  data = GetDist( row, col, AR_SIDE_TOP );
1272  data = std::max( data, LocalKeepOut );
1273  SetDist( row, col, AR_SIDE_TOP, data );
1274  }
1275  }
1276  }
1277 }
1278 
1279 
1280 void AR_MATRIX::PlacePad( D_PAD* aPad, int color, int marge, AR_MATRIX::CELL_OP op_logic )
1281 {
1282  int dx, dy;
1283  wxPoint shape_pos = aPad->ShapePos();
1284 
1285  dx = aPad->GetSize().x / 2;
1286  dx += marge;
1287 
1288  if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
1289  {
1290  traceFilledCircle( shape_pos.x, shape_pos.y, dx, aPad->GetLayerSet(), color, op_logic );
1291  return;
1292  }
1293 
1294  dy = aPad->GetSize().y / 2;
1295  dy += marge;
1296 
1297  if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
1298  {
1299  dx += abs( aPad->GetDelta().y ) / 2;
1300  dy += abs( aPad->GetDelta().x ) / 2;
1301  }
1302 
1303  // The pad is a rectangle ( horizontal or vertical )
1304  if( int( aPad->GetOrientation() ) % 900 == 0 )
1305  {
1306  // Orientation turned 90 deg.
1307  if( aPad->GetOrientation() == 900 || aPad->GetOrientation() == 2700 )
1308  {
1309  std::swap( dx, dy );
1310  }
1311 
1312  TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy, shape_pos.x + dx,
1313  shape_pos.y + dy, aPad->GetLayerSet(), color, op_logic );
1314  }
1315  else
1316  {
1317  TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy, shape_pos.x + dx,
1318  shape_pos.y + dy, aPad->GetOrientation(), aPad->GetLayerSet(), color, op_logic );
1319  }
1320 }
int GetApxDist(int r1, int c1, int r2, int c2)
Definition: ar_matrix.cpp:305
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
#define AR_SIDE_BOTTOM
Definition: ar_matrix.h:43
void traceArc(int ux0, int uy0, int ux1, int uy1, double ArcAngle, int lg, LAYER_NUM layer, int color, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:750
char DIR_CELL
Definition: ar_matrix.h:54
int InitRoutingMatrix()
Function InitBoard initializes the data structures.
Definition: ar_matrix.cpp:92
long trace
Definition: solve.cpp:232
static const int dist[10][10]
Definition: ar_matrix.cpp:320
DIST_CELL * m_DistSide[AR_MAX_ROUTING_LAYERS_COUNT]
Definition: ar_matrix.h:57
int m_MemSize
Definition: ar_matrix.h:66
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:120
#define AR_SIDE_TOP
Definition: ar_matrix.h:42
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Function IsOnLayer tests to see if this object is on the given layer.
int m_Ncols
Definition: ar_matrix.h:65
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int m_GridRouting
Definition: ar_matrix.h:63
void tracePcbLine(int x0, int y0, int x1, int y1, LAYER_NUM layer, int color, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:946
#define FROM_OTHERSIDE
Definition: ar_cell.h:108
int color
Definition: DXF_plotter.cpp:62
void TraceFilledRectangle(int ux0, int uy0, int ux1, int uy1, double angle, LSET aLayerMask, int color, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:794
EDA_RECT m_BrdBox
Definition: ar_matrix.h:64
int GetHeight() const
Definition: eda_rect.h:118
int CalcDist(int x, int y, int z, int side)
Definition: ar_matrix.cpp:400
void CreateKeepOutRectangle(int ux0, int uy0, int ux1, int uy1, int marge, int aKeepOut, LSET aLayerMask)
Function CreateKeepOutRectangle builds the cost map: Cells ( in Dist map ) inside the rect x0...
Definition: ar_matrix.cpp:1175
void PlacePad(D_PAD *aPad, int color, int marge, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:1280
static const int penalty[10][10]
Definition: ar_matrix.cpp:337
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
void TraceSegmentPcb(DRAWSEGMENT *pt_segm, int color, int marge, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:1085
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:241
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
#define abs(a)
Definition: auxiliary.h:84
static const int delta[8][2]
Definition: solve.cpp:112
const wxPoint & GetEnd() const
Definition: class_track.h:119
int DIST_CELL
Definition: ar_matrix.h:53
void XorCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.cpp:227
Functions relatives to tracks, vias and segments used to fill zones.
PCB_LAYER_ID m_routeLayerTop
Definition: ar_matrix.h:69
PCB_LAYER_ID
A quick note on layer IDs:
STROKE_T GetShape() const
#define CELL_IS_EMPTY
Definition: ar_cell.h:35
Class LSET is a set of PCB_LAYER_IDs.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
void WriteCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.h:89
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
#define VIA_IMPOSSIBLE
Definition: ar_cell.h:44
const wxPoint & GetStart() const
Definition: class_track.h:122
void SetEnd(int x, int y)
Definition: eda_rect.h:134
void OrCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.cpp:216
Arcs (with rounded ends)
MATRIX_CELL GetCell(int aRow, int aCol, int aSide)
Definition: ar_matrix.cpp:194
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:402
void(AR_MATRIX::* m_opWriteCell)(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.h:74
int m_Nrows
Definition: ar_matrix.h:65
const wxSize & GetSize() const
Definition: class_pad.h:269
DIR_CELL * m_DirSide[AR_MAX_ROUTING_LAYERS_COUNT]
Definition: ar_matrix.h:59
void SetX(int val)
Definition: eda_rect.h:130
void SetCellOperation(CELL_OP aLogicOp)
Definition: ar_matrix.cpp:174
MATRIX_CELL * m_BoardSide[AR_MAX_ROUTING_LAYERS_COUNT]
Definition: ar_matrix.h:56
void SetCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.cpp:205
void drawSegmentQcq(int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer, int color, CELL_OP op_logic)
Definition: ar_matrix.cpp:458
void AndCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.cpp:238
Pad object description.
void SetY(int val)
Definition: eda_rect.h:131
void traceCircle(int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer, int color, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:590
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
const wxPoint GetEnd() const
Definition: eda_rect.h:114
void UnInitRoutingMatrix()
Definition: ar_matrix.cpp:140
#define OP_CELL(layer, dy, dx)
Definition: ar_matrix.cpp:436
double cosdecideg(double r, double a)
Circle generation utility: computes r * cos(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:354
double sindecideg(double r, double a)
Circle generation utility: computes r * sin(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:345
double GetAngle() const
static int dir_penalty_BOTTOM[10][10]
Definition: ar_matrix.cpp:372
Class to handle a graphic segment.
#define max(a, b)
Definition: auxiliary.h:86
int m_RoutingLayersCount
Definition: ar_matrix.h:62
bool m_InitMatrixDone
Definition: ar_matrix.h:61
int GetWidth() const
Definition: class_track.h:116
int GetDir(int aRow, int aCol, int aSide)
Definition: ar_matrix.cpp:279
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
wxPoint GetBrdCoordOrigin()
function GetBrdCoordOrigin
Definition: ar_matrix.h:99
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:382
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
const wxSize & GetDelta() const
Definition: class_pad.h:272
int GetX() const
Definition: eda_rect.h:109
void AddCell(int aRow, int aCol, int aSide, MATRIX_CELL aCell)
Definition: ar_matrix.cpp:249
void SetDir(int aRow, int aCol, int aSide, int aDir)
Definition: ar_matrix.cpp:289
void traceFilledCircle(int cx, int cy, int radius, LSET aLayerMask, int color, AR_MATRIX::CELL_OP op_logic)
Definition: ar_matrix.cpp:629
The common library.
int GetWidth() const
Definition: eda_rect.h:117
int GetWidth() const
wxPoint ShapePos() const
Definition: class_pad.cpp:517
int GetY() const
Definition: eda_rect.h:110
unsigned char MATRIX_CELL
Definition: ar_matrix.h:52
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
void SetDist(int aRow, int aCol, int aSide, DIST_CELL)
Definition: ar_matrix.cpp:269
bool ComputeMatrixSize(const EDA_RECT &aBoundingBox)
Function ComputeMatrixSize calculates the number of rows and columns of dimensions of aPcb for routin...
Definition: ar_matrix.cpp:62
double Distance(double x1, double y1, double x2, double y2)
#define AR_MAX_ROUTING_LAYERS_COUNT
Definition: ar_matrix.h:40
static const int dir_penalty_TOP[10][10]
Definition: ar_matrix.cpp:355
int m_RouteCount
Definition: ar_matrix.h:67
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
DIST_CELL GetDist(int aRow, int aCol, int aSide)
Definition: ar_matrix.cpp:259
PCB_LAYER_ID m_routeLayerBottom
Definition: ar_matrix.h:70
#define PN
Definition: ar_matrix.cpp:354