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.

678 lines
21 KiB

19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
18 years ago
18 years ago
18 years ago
19 years ago
18 years ago
19 years ago
18 years ago
19 years ago
18 years ago
19 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
  1. /*****************************/
  2. /* Localisation des elements */
  3. /*****************************/
  4. #include "fctsys.h"
  5. #include "common.h"
  6. #include "pcbnew.h"
  7. #include "protos.h"
  8. /**
  9. * Function RefPos
  10. * returns the reference position, coming from either the mouse position or the
  11. * the cursor position, based on whether the typeloc has the CURSEUR_OFF_GRILLE
  12. * flag ORed in or not.
  13. * @param typeloc int with possible CURSEUR_OFF_GRILLE bit on.
  14. * @return wxPoint - The reference point, either the mouse position or
  15. * the cursor position.
  16. */
  17. wxPoint inline RefPos( int typeloc )
  18. {
  19. return ActiveScreen->RefPos( (typeloc & CURSEUR_OFF_GRILLE) != 0 );
  20. }
  21. /*******************************************************************/
  22. TRACK* Locate_Via( BOARD* Pcb, const wxPoint& pos, int layer )
  23. /*******************************************************************/
  24. /* Localise une via au point pX,pY
  25. * Si layer < 0 la via sera localisee quelle que soit la couche
  26. * Si layer = 0 .. 15 la via sera localisee selon son type:
  27. * - traversante : toutes couches
  28. * - aveugle = entre couches utiles
  29. * - borgnes idem
  30. * Entree : coord du point de reference, couche
  31. * Sortie: NULL si pas de via
  32. * (TRACK*) adresse de la via
  33. */
  34. {
  35. TRACK* track;
  36. for( track = Pcb->m_Track; track; track = track->Next() )
  37. {
  38. if( track->Type() != TYPEVIA )
  39. continue;
  40. if( track->m_Start != pos )
  41. continue;
  42. if( track->GetState( BUSY | DELETED ) )
  43. continue;
  44. if( layer < 0 )
  45. break;
  46. if( track->IsOnLayer( layer ) )
  47. break;
  48. }
  49. return track;
  50. }
  51. /*******************************************************************/
  52. TRACK* Locate_Via_Area( TRACK* aStart, const wxPoint& pos, int layer )
  53. /*******************************************************************/
  54. {
  55. TRACK* track;
  56. for( track = aStart; track; track = track->Next() )
  57. {
  58. if( track->Type() != TYPEVIA )
  59. continue;
  60. if( !track->HitTest(pos) )
  61. continue;
  62. if( track->GetState( BUSY | DELETED ) )
  63. continue;
  64. if( layer < 0 )
  65. break;
  66. if( track->IsOnLayer( layer ) )
  67. break;
  68. }
  69. return track;
  70. }
  71. /********************************************************************/
  72. D_PAD* Locate_Pad_Connecte( BOARD* Pcb, TRACK* ptr_piste, int extr )
  73. /********************************************************************/
  74. /* localisation de la pastille connectee au point de piste a tester
  75. * entree : ptr_piste: pointeur sur le segment de piste
  76. * extr = flag = START -> debut du segment a tester
  77. * = END -> fin du segment a tester
  78. * retourne:
  79. * un pointeur sur la description de la pastille si localisation
  80. * pointeur NULL si pastille non trouvee
  81. */
  82. {
  83. D_PAD* ptr_pad = NULL;
  84. wxPoint ref_pos;
  85. int masque_layer = g_TabOneLayerMask[ptr_piste->GetLayer()];
  86. if( extr == START )
  87. {
  88. ref_pos = ptr_piste->m_Start;
  89. }
  90. else
  91. {
  92. ref_pos = ptr_piste->m_End;
  93. }
  94. for( MODULE* module = Pcb->m_Modules; module; module = module->Next() )
  95. {
  96. ptr_pad = Locate_Pads( module, ref_pos, masque_layer );
  97. if( ptr_pad != NULL )
  98. break;
  99. }
  100. return ptr_pad;
  101. }
  102. /*************************************************
  103. * D_PAD * Locate_Any_Pad( BOARD* Pcb, int typeloc, bool OnlyCurrentLayer)
  104. * D_PAD* Locate_Any_Pad( BOARD* Pcb, int ref_pos, bool OnlyCurrentLayer)
  105. *************************************************/
  106. /*
  107. * localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou
  108. * par la souris, recherche faite sur toutes les empreintes.
  109. * entree :
  110. * - coord souris
  111. * ou ref_pos
  112. * retourne:
  113. * pointeur sur la description de la pastille si localisation
  114. * pointeur NULL si pastille non trouvee
  115. * num_empr = numero d'empreinte du pad
  116. *
  117. * la priorit est donne a la couche active
  118. */
  119. D_PAD* Locate_Any_Pad( BOARD* Pcb, int typeloc, bool OnlyCurrentLayer )
  120. {
  121. wxPoint ref_pos = RefPos( typeloc );
  122. return Locate_Any_Pad( Pcb, ref_pos, OnlyCurrentLayer );
  123. }
  124. D_PAD* Locate_Any_Pad( BOARD* Pcb, const wxPoint& ref_pos, bool OnlyCurrentLayer )
  125. {
  126. int layer_mask = g_TabOneLayerMask[ ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer];
  127. for( MODULE* module=Pcb->m_Modules; module; module = module->Next() )
  128. {
  129. D_PAD* pt_pad;
  130. /* First: Search a pad on the active layer: */
  131. if( ( pt_pad = Locate_Pads( module, ref_pos, layer_mask ) ) != NULL )
  132. return pt_pad;
  133. /* If not found, search on other layers: */
  134. if( !OnlyCurrentLayer )
  135. {
  136. if( ( pt_pad = Locate_Pads( module, ref_pos, ALL_LAYERS ) ) != NULL )
  137. return pt_pad;
  138. }
  139. }
  140. return NULL;
  141. }
  142. /******************************************************************************/
  143. /* D_PAD* Locate_Pads(MODULE * module, int masque_layer,int typeloc) */
  144. /* D_PAD* Locate_Pads(MODULE * module, const wxPoint & ref_pos,int masque_layer) */
  145. /******************************************************************************/
  146. /* localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou
  147. * par la souris, concernant l'empreinte en cours.
  148. * entree :
  149. * - parametres generaux de l'empreinte mise a jour par caract()
  150. * - masque_layer = couche(s) (bit_masque)sur laquelle doit etre la pastille
  151. * retourne:
  152. * un pointeur sur la description de la pastille si localisation
  153. * pointeur NULL si pastille non trouvee
  154. */
  155. D_PAD* Locate_Pads( MODULE* module, int masque_layer, int typeloc )
  156. {
  157. wxPoint ref_pos = RefPos( typeloc );
  158. return Locate_Pads( module, ref_pos, masque_layer );
  159. }
  160. D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int masque_layer )
  161. {
  162. for( D_PAD* pt_pad = module->m_Pads; pt_pad; pt_pad = pt_pad->Next() )
  163. {
  164. /* ... et sur la bonne couche */
  165. if( (pt_pad->m_Masque_Layer & masque_layer) == 0 )
  166. continue;
  167. if( pt_pad->HitTest( ref_pos ) )
  168. return pt_pad;
  169. }
  170. return NULL;
  171. }
  172. /**
  173. * Function Locate_Prefered_Module
  174. * locates a footprint by its bounding rectangle. If several footprints
  175. * are possible, then the priority is: the closest on the active layer, then closest.
  176. * The current mouse or cursor coordinates are grabbed from the active window
  177. * to performe hit-testing.
  178. * distance is calculated via manhattan distance from the center of the bounding rectangle
  179. * to the cursor postition.
  180. *
  181. * @param Pcb The BOARD to search within.
  182. * @param typeloc Flag bits, tuning the search, see pcbnew.h
  183. * @return MODULE* - the best module or NULL if none.
  184. */
  185. MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc )
  186. {
  187. MODULE* pt_module;
  188. int lx, ly; /* dimensions du rectangle d'encadrement du module */
  189. MODULE* module = NULL; /* module localise sur la couche active */
  190. MODULE* Altmodule = NULL; /* module localise sur les couches non actives */
  191. int min_dim = 0x7FFFFFFF; /* dim mini du module localise sur la couche active */
  192. int alt_min_dim = 0x7FFFFFFF; /* dim mini du module localise sur les couches non actives */
  193. int layer; /* pour calcul de couches prioritaires */
  194. wxPoint ref_pos; /* coord du point de reference pour la localisation */
  195. ref_pos = RefPos( typeloc );
  196. pt_module = Pcb->m_Modules;
  197. for( ; pt_module; pt_module = (MODULE*) pt_module->Pnext )
  198. {
  199. // is the ref point within the module's bounds?
  200. if( !pt_module->HitTest( ref_pos ) )
  201. continue;
  202. // if caller wants to ignore locked modules, and this one is locked, skip it.
  203. if( (typeloc & IGNORE_LOCKED) && pt_module->IsLocked() )
  204. continue;
  205. /* calcul de priorite: la priorite est donnee a la couche
  206. * d'appartenance du module et a la couche cuivre si le module
  207. * est sur couche serigr,adhesive cuivre, a la couche cmp si le module
  208. * est sur couche serigr,adhesive composant */
  209. layer = pt_module->GetLayer();
  210. if( layer==ADHESIVE_N_CU || layer==SILKSCREEN_N_CU )
  211. layer = COPPER_LAYER_N;
  212. else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP )
  213. layer = CMP_N;
  214. /* Localisation: test des dimensions minimales, choix du meilleur candidat */
  215. /* calcul des dimensions du cadre :*/
  216. int offx = pt_module->m_BoundaryBox.m_Size.x/2 +
  217. pt_module->m_BoundaryBox.m_Pos.x +
  218. pt_module->m_Pos.x;
  219. int offy = pt_module->m_BoundaryBox.m_Size.y/2
  220. + pt_module->m_BoundaryBox.m_Pos.y
  221. + pt_module->m_Pos.y;
  222. //off x & offy point to the middle of the box.
  223. int dist = abs(ref_pos.x - offx) + abs(ref_pos.y - offy);
  224. lx = pt_module->m_BoundaryBox.GetWidth();
  225. ly = pt_module->m_BoundaryBox.GetHeight();
  226. //int dist = MIN(lx, ly); // to pick the smallest module (kinda screwy with same-sized modules -- this is bad!)
  227. if( ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer == layer ){
  228. if( dist <= min_dim ){
  229. /* meilleure empreinte localisee sur couche active */
  230. module = pt_module;
  231. min_dim = dist;
  232. }
  233. }
  234. else if( !(typeloc & MATCH_LAYER)
  235. && ( !(typeloc & VISIBLE_ONLY) || IsModuleLayerVisible( layer ) ) )
  236. {
  237. if( dist <= alt_min_dim )
  238. {
  239. /* meilleure empreinte localisee sur autres couches */
  240. Altmodule = pt_module;
  241. alt_min_dim = dist;
  242. }
  243. }
  244. }
  245. if( module )
  246. {
  247. return module;
  248. }
  249. if( Altmodule )
  250. {
  251. return Altmodule;
  252. }
  253. return NULL;
  254. }
  255. /******************************************************************/
  256. inline bool IsPointsAreNear(wxPoint & p1, wxPoint & p2, int max_dist)
  257. /******************************************************************/
  258. /*
  259. return true if the dist between p1 and p2 < max_dist
  260. Currently in test (currently rasnest algos work only if p1 == p2)
  261. */
  262. {
  263. #if 0 // Do not change it: does not work
  264. {
  265. int dist;
  266. dist = abs(p1.x - p2.x) + abs (p1.y - p2.y);
  267. dist *= 7;
  268. dist /= 10;
  269. if ( dist < max_dist ) return true;
  270. }
  271. #else
  272. if ( p1 == p2 ) return true;
  273. #endif
  274. return false;
  275. }
  276. /**************************************************************/
  277. TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base,
  278. TRACK* pt_lim, int extr )
  279. /**************************************************************/
  280. /** Search for the track (or via) segment which is connected to the track segment PtRefSegm
  281. * if extr == START, the starting track segment PtRefSegm is used to locate a connected segment
  282. * if extr == END, the ending track segment PtRefSegm is used
  283. * The test connection consider only end track segments
  284. *
  285. * Search is made from pt_base to pt_lim (in the track linked list)
  286. * if pt_lim == NULL, the search is made from pt_base to the end of list
  287. *
  288. * In order to have a fast computation time:
  289. * a first search is made considering only the +/- 50 next door neightbour of PtRefSegm.
  290. * if no track is found : the entire list is tested
  291. *
  292. * @param PtRefSegm = reference segment
  293. * @param pt_base = lower limit for search
  294. * @param pt_lim = upper limit for search (can be NULL)
  295. * @param extr = START or END = end of ref track segment to use in tests
  296. */
  297. {
  298. #define NEIGHTBOUR_COUNT_MAX 50
  299. TRACK* PtSegmB, * PtSegmN;
  300. int Reflayer;
  301. wxPoint pos_ref;
  302. int ii;
  303. int max_dist;
  304. if( extr == START )
  305. pos_ref = PtRefSegm->m_Start;
  306. else
  307. pos_ref = PtRefSegm->m_End;
  308. Reflayer = PtRefSegm->ReturnMaskLayer();
  309. /* 1ere passe */
  310. PtSegmB = PtSegmN = PtRefSegm;
  311. for( ii = 0; ii < NEIGHTBOUR_COUNT_MAX; ii++ )
  312. {
  313. if( (PtSegmN == NULL) && (PtSegmB == NULL) )
  314. break;
  315. if( PtSegmN )
  316. {
  317. if( PtSegmN->GetState( BUSY | DELETED ) )
  318. goto suite;
  319. if( PtSegmN == PtRefSegm )
  320. goto suite;
  321. /* max_dist is the max distance between 2 tack ends which ensure a copper continuty */
  322. max_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2;
  323. if( IsPointsAreNear(pos_ref, PtSegmN->m_Start, max_dist) )
  324. { /* Test des couches */
  325. if( Reflayer & PtSegmN->ReturnMaskLayer() )
  326. return PtSegmN;
  327. }
  328. if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) )
  329. { /* Test des couches */
  330. if( Reflayer & PtSegmN->ReturnMaskLayer() )
  331. return PtSegmN;
  332. }
  333. suite:
  334. if( PtSegmN == pt_lim )
  335. PtSegmN = NULL;
  336. else
  337. PtSegmN = (TRACK*) PtSegmN->Pnext;
  338. }
  339. if( PtSegmB )
  340. {
  341. if( PtSegmB->GetState( BUSY | DELETED ) )
  342. goto suite1;
  343. if( PtSegmB == PtRefSegm )
  344. goto suite1;
  345. max_dist = (PtSegmB->m_Width + PtRefSegm->m_Width)/2;
  346. if( IsPointsAreNear(pos_ref, PtSegmB->m_Start, max_dist) )
  347. { /* Test des couches */
  348. if( Reflayer & PtSegmB->ReturnMaskLayer() )
  349. return PtSegmB;
  350. }
  351. if( IsPointsAreNear(pos_ref, PtSegmB->m_End, max_dist) )
  352. { /* Test des couches */
  353. if( Reflayer & PtSegmB->ReturnMaskLayer() )
  354. return PtSegmB;
  355. }
  356. suite1:
  357. if( PtSegmB == pt_base )
  358. PtSegmB = NULL;
  359. else if( PtSegmB->Type() != TYPEPCB )
  360. PtSegmB = (TRACK*) PtSegmB->Pback;
  361. else
  362. PtSegmB = NULL;
  363. }
  364. }
  365. /* Recherche generale */
  366. for( PtSegmN = pt_base; PtSegmN != NULL; PtSegmN = (TRACK*) PtSegmN->Pnext )
  367. {
  368. if( PtSegmN->GetState( DELETED | BUSY ) )
  369. {
  370. if( PtSegmN == pt_lim )
  371. break;
  372. continue;
  373. }
  374. if( PtSegmN == PtRefSegm )
  375. {
  376. if( PtSegmN == pt_lim )
  377. break;
  378. continue;
  379. }
  380. max_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2;
  381. if( IsPointsAreNear(pos_ref,PtSegmN->m_Start, max_dist) )
  382. { /* Test des couches */
  383. if( Reflayer & PtSegmN->ReturnMaskLayer() )
  384. return PtSegmN;
  385. }
  386. if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) )
  387. { /* Test des couches */
  388. if( Reflayer & PtSegmN->ReturnMaskLayer() )
  389. return PtSegmN;
  390. }
  391. if( PtSegmN == pt_lim )
  392. break;
  393. }
  394. return NULL;
  395. }
  396. /****************************************************************************/
  397. /* TRACK *Locate_Pistes(TRACK * start_adresse, int MasqueLayer,int typeloc) */
  398. /* TRACK *Locate_Pistes(TRACK * start_adresse, int ref_pos.x, int ref_pos.y,*/
  399. /* int MasqueLayer) */
  400. /****************************************************************************/
  401. /*
  402. * 1 - routine de localisation du segment de piste pointe par la souris.
  403. * 2 - routine de localisation du segment de piste pointe par le point
  404. * ref_pos.x , ref_pos.y.r
  405. *
  406. * La recherche commence a l'adresse start_adresse
  407. */
  408. TRACK* Locate_Pistes( TRACK* start_adresse, int MasqueLayer, int typeloc )
  409. {
  410. wxPoint ref_pos = RefPos( typeloc );
  411. return Locate_Pistes( start_adresse, ref_pos, MasqueLayer );
  412. }
  413. TRACK* Locate_Pistes( TRACK* start_adresse, const wxPoint& ref_pos, int MasqueLayer )
  414. {
  415. for( TRACK* Track = start_adresse; Track; Track = (TRACK*) Track->Pnext )
  416. {
  417. if( Track->GetState( BUSY | DELETED ) )
  418. continue;
  419. if( (g_DesignSettings.m_LayerColor[Track->GetLayer()] & ITEM_NOT_SHOW) )
  420. continue;
  421. if( Track->Type() == TYPEVIA ) /* VIA rencontree */
  422. {
  423. if( Track->HitTest( ref_pos ) )
  424. return Track;
  425. }
  426. else
  427. {
  428. if( MasqueLayer != -1 )
  429. if( (g_TabOneLayerMask[Track->GetLayer()] & MasqueLayer) == 0 )
  430. continue; /* Segments sur couches differentes */
  431. if( Track->HitTest( ref_pos ) )
  432. return Track;
  433. }
  434. }
  435. return NULL;
  436. }
  437. /****************************************************************/
  438. /* TRACK * Locate_Zone(TRACK * start_adresse, int layer, */
  439. /* int typeloc) */
  440. /* TRACK * Locate_Zone(TRACK * start_adresse, */
  441. /* const wxPoint & ref_pos, */
  442. /* int layer) */
  443. /****************************************************************/
  444. /*
  445. * 1 - routine de localisation du segment de zone pointe par la souris.
  446. * 2 - routine de localisation du segment de zone pointe par le point
  447. * ref_pos.x , ref_pos.y.r
  448. *
  449. * Si layer == -1 , le tst de la couche n'est pas fait
  450. *
  451. * La recherche commence a l'adresse start_adresse
  452. */
  453. TRACK* Locate_Zone( TRACK* start_adresse, int layer, int typeloc )
  454. {
  455. wxPoint ref_pos = RefPos( typeloc );
  456. return Locate_Zone( start_adresse, ref_pos, layer );
  457. }
  458. TRACK* Locate_Zone( TRACK* start_adresse, const wxPoint& ref_pos, int layer )
  459. {
  460. for( TRACK* Zone = start_adresse; Zone; Zone = (TRACK*) Zone->Pnext )
  461. {
  462. if( (layer != -1) && (Zone->GetLayer() != layer) )
  463. continue;
  464. if( Zone->HitTest( ref_pos ) )
  465. return Zone;
  466. }
  467. return NULL;
  468. }
  469. /*******************************************************************************/
  470. D_PAD* Fast_Locate_Pad_Connecte( BOARD* Pcb, const wxPoint& ref_pos, int masque_layer )
  471. /*******************************************************************************/
  472. /* Routine cherchant le pad de centre px,py,
  473. * sur la couche indiquee par masque_layer (bit a bit)
  474. * ( extremite de piste )
  475. * La liste des pads doit deja exister.
  476. *
  477. * retourne :
  478. * NULL si pas de pad localise.
  479. * pointeur sur la structure descr_pad correspondante si pad trouve
  480. * (bonne position ET bonne couche).
  481. */
  482. {
  483. D_PAD* pad;
  484. LISTE_PAD* ptr_pad, * lim;
  485. lim = (LISTE_PAD*) Pcb->m_Pads + Pcb->m_NbPads;
  486. for( ptr_pad = (LISTE_PAD*) Pcb->m_Pads; ptr_pad < lim; ptr_pad++ )
  487. {
  488. pad = *ptr_pad;
  489. if( pad->m_Pos != ref_pos )
  490. continue;
  491. /* Pad peut-etre trouve ici : il doit etre sur la bonne couche */
  492. if( pad->m_Masque_Layer & masque_layer )
  493. return pad;
  494. }
  495. return NULL;
  496. }
  497. /***********************************************************************************/
  498. TRACK* Fast_Locate_Piste( TRACK* start_adr, TRACK* end_adr,
  499. const wxPoint& ref_pos, int MaskLayer )
  500. /***********************************************************************************/
  501. /* Localiste le segment dont une extremite coincide avec le point x,y
  502. * sur les couches donnees par masklayer
  503. * la recherche se fait de l'adresse start_adr a end_adr
  504. * si end_adr = NULL, recherche jusqu'a la fin de la liste
  505. * Les segments de piste marques avec le flag DELETED ne sont pas
  506. * pris en compte
  507. */
  508. {
  509. TRACK* PtSegm;
  510. if( start_adr == NULL )
  511. return NULL;
  512. for( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext )
  513. {
  514. if( PtSegm->GetState( DELETED | BUSY ) == 0 )
  515. {
  516. if( ref_pos == PtSegm->m_Start )
  517. {
  518. /* Test des couches */
  519. if( MaskLayer & PtSegm->ReturnMaskLayer() )
  520. return PtSegm;
  521. }
  522. if( ref_pos == PtSegm->m_End )
  523. {
  524. /* Test des couches */
  525. if( MaskLayer & PtSegm->ReturnMaskLayer() )
  526. return PtSegm;
  527. }
  528. }
  529. if( PtSegm == end_adr )
  530. break;
  531. }
  532. return NULL;
  533. }
  534. /*******************************************************************/
  535. TRACK* Fast_Locate_Via( TRACK* start_adr, TRACK* end_adr,
  536. const wxPoint& pos, int MaskLayer )
  537. /*******************************************************************/
  538. /* Localise la via de centre le point x,y , sur les couches donnees
  539. * par masklayer
  540. * la recherche se fait de l'adresse start_adr a end_adr.
  541. * si end_adr = NULL, recherche jusqu'a la fin de la liste
  542. * les vias dont le parametre State a le bit DELETED ou BUSY = 1 sont ignorees
  543. */
  544. {
  545. TRACK* PtSegm;
  546. for( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext )
  547. {
  548. if( PtSegm->Type() == TYPEVIA )
  549. {
  550. if( pos == PtSegm->m_Start )
  551. {
  552. if( PtSegm->GetState( BUSY | DELETED ) == 0 )
  553. {
  554. /* Test des couches */
  555. if( MaskLayer & PtSegm->ReturnMaskLayer() )
  556. return PtSegm;
  557. }
  558. }
  559. }
  560. if( PtSegm == end_adr )
  561. break;
  562. }
  563. return NULL;
  564. }