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.

1059 lines
31 KiB

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
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
19 years ago
19 years ago
19 years ago
19 years ago
  1. /*****************************/
  2. /* Localisation des elements */
  3. /*****************************/
  4. #include "fctsys.h"
  5. #include "gr_basic.h"
  6. #include "common.h"
  7. #include "pcbnew.h"
  8. #include "trigo.h"
  9. #include "autorout.h"
  10. #include "protos.h"
  11. /* fonctions locales */
  12. EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch, int typeloc );
  13. D_PAD* Locate_Any_Pad( BOARD* Pcb, const wxPoint& ref_pos, bool OnlyCurrentLayer );
  14. /**
  15. * Function RefPos
  16. * returns the reference position, coming from either the mouse position or the
  17. * the cursor position, based on whether the typeloc has the CURSEUR_OFF_GRILLE
  18. * flag ORed in or not.
  19. * @param typeloc int with possible CURSEUR_OFF_GRILLE bit on.
  20. * @return wxPoint - The reference point, either the mouse position or
  21. * the cursor position.
  22. */
  23. wxPoint inline RefPos( int typeloc )
  24. {
  25. return ActiveScreen->RefPos( (typeloc & CURSEUR_OFF_GRILLE) != 0 );
  26. }
  27. /*************************************************************/
  28. MODULE* ReturnModule( BOARD* pcb, const wxString& reference )
  29. /*************************************************************/
  30. /*
  31. * Recherche d'un module par sa reference
  32. * Retourne:
  33. * un pointeur sur le module
  34. * Null si pas localis
  35. */
  36. {
  37. MODULE* Module = pcb->m_Modules;
  38. for( ; Module != NULL; Module = (MODULE*) Module->Pnext )
  39. {
  40. if( reference.CmpNoCase( Module->m_Reference->m_Text ) == 0 )
  41. return Module;
  42. }
  43. return NULL;
  44. }
  45. /********************************************************/
  46. D_PAD* ReturnPad( MODULE* module, const wxString& name )
  47. /********************************************************/
  48. /* Recherche d'un pad par son nom, pour le module Module
  49. */
  50. {
  51. D_PAD* pt_pad;
  52. wxString buf;
  53. if( module == NULL )
  54. return NULL;
  55. pt_pad = module->m_Pads;
  56. for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext )
  57. {
  58. pt_pad->ReturnStringPadName( buf );
  59. if( buf.CmpNoCase( name ) == 0 )
  60. return pt_pad;
  61. }
  62. return NULL;
  63. }
  64. /*******************************************************************************/
  65. EDA_BaseStruct* WinEDA_BasePcbFrame::Locate( int typeloc, int LayerSearch )
  66. /*******************************************************************************/
  67. /* General locate function
  68. * Display infos relatives to the item found
  69. * return a pointer to this item ( or NULL )
  70. */
  71. {
  72. TEXTE_PCB* pt_texte_pcb;
  73. TRACK* Track, * TrackLocate;
  74. DRAWSEGMENT* DrawSegm;
  75. MODULE* module;
  76. D_PAD* pt_pad;
  77. int masque_layer;
  78. EDA_BaseStruct* item;
  79. pt_texte_pcb = Locate_Texte_Pcb( m_Pcb->m_Drawings, LayerSearch, typeloc );
  80. if( pt_texte_pcb ) // a PCB text is found
  81. {
  82. Affiche_Infos_PCB_Texte( this, pt_texte_pcb );
  83. return pt_texte_pcb;
  84. }
  85. DrawSegm = Locate_Segment_Pcb( m_Pcb, LayerSearch, typeloc );
  86. if( DrawSegm != NULL )
  87. {
  88. Affiche_Infos_DrawSegment( this, DrawSegm );
  89. return DrawSegm;
  90. }
  91. item = Locate_Cotation( m_Pcb, LayerSearch, typeloc );
  92. if( item != NULL )
  93. return item;
  94. item = Locate_MirePcb( m_Pcb->m_Drawings, LayerSearch, typeloc );
  95. if( item != NULL )
  96. return item;
  97. /* Search for tracks and vias, with via priority */
  98. if( LayerSearch == -1 )
  99. masque_layer = ALL_LAYERS;
  100. else
  101. masque_layer = g_TabOneLayerMask[LayerSearch];
  102. Track = Locate_Pistes( m_Pcb->m_Track, masque_layer, typeloc );
  103. if( Track != NULL )
  104. {
  105. TrackLocate = Track; /* a track or a via is found */
  106. /* Search for a via */
  107. while( ( TrackLocate = Locate_Pistes( TrackLocate,
  108. masque_layer, typeloc ) ) != NULL )
  109. {
  110. Track = TrackLocate;
  111. if( TrackLocate->m_StructType == TYPEVIA )
  112. break;
  113. TrackLocate = (TRACK*) TrackLocate->Pnext;
  114. }
  115. Affiche_Infos_Piste( this, Track );
  116. return Track;
  117. }
  118. /* Search for Pads */
  119. if( ( pt_pad = Locate_Any_Pad( m_Pcb, typeloc ) ) != NULL )
  120. {
  121. pt_pad->Display_Infos( this ); return pt_pad;
  122. }
  123. /* Search for a footprint text */
  124. // First search: locate texts for footprints on copper or component layer
  125. // Priority to the active layer (component or copper).
  126. // This is useful for small smd components when 2 texts overlap but are not
  127. // on the same layer
  128. if( LayerSearch == LAYER_CUIVRE_N || LayerSearch == CMP_N )
  129. {
  130. for( module = m_Pcb->m_Modules; module != NULL; module = (MODULE*) module->Pnext )
  131. {
  132. TEXTE_MODULE* pt_texte;
  133. if( module->m_Layer != LayerSearch )
  134. continue;
  135. pt_texte = LocateTexteModule( m_Pcb, &module, typeloc | VISIBLE_ONLY );
  136. if( pt_texte != NULL )
  137. {
  138. Affiche_Infos_E_Texte( this, module, pt_texte );
  139. return pt_texte;
  140. }
  141. }
  142. }
  143. // Now Search footprint texts on all layers
  144. module = NULL;
  145. {
  146. TEXTE_MODULE* pt_texte;
  147. pt_texte = LocateTexteModule( m_Pcb, &module, typeloc | VISIBLE_ONLY );
  148. if( pt_texte != NULL )
  149. {
  150. Affiche_Infos_E_Texte( this, module, pt_texte );
  151. return pt_texte;
  152. }
  153. }
  154. /* Search for a footprint */
  155. module = Locate_Prefered_Module( m_Pcb, typeloc | VISIBLE_ONLY );
  156. if( module != NULL )
  157. {
  158. module->Display_Infos( this );
  159. return module;
  160. }
  161. /* Search for zones */
  162. if( ( TrackLocate = Locate_Zone( (TRACK*) m_Pcb->m_Zone,
  163. GetScreen()->m_Active_Layer, typeloc ) ) != NULL )
  164. {
  165. Affiche_Infos_Piste( this, TrackLocate );
  166. return TrackLocate;
  167. }
  168. MsgPanel->EraseMsgBox();
  169. return NULL;
  170. }
  171. /*******************************************************************/
  172. TRACK* Locate_Via( BOARD* Pcb, const wxPoint& pos, int layer )
  173. /*******************************************************************/
  174. /* Localise une via au point pX,pY
  175. * Si layer < 0 la via sera localisee quelle que soit la couche
  176. * Si layer = 0 .. 15 la via sera localisee selon son type:
  177. * - traversante : toutes couches
  178. * - aveugle = entre couches utiles
  179. * - borgnes idem
  180. * Entree : coord du point de reference, couche
  181. * Sortie: NULL si pas de via
  182. * (TRACK*) adresse de la via
  183. */
  184. {
  185. TRACK* Track;
  186. for( Track = Pcb->m_Track; Track != NULL; Track = Track->Next() )
  187. {
  188. if( Track->m_StructType != TYPEVIA )
  189. continue;
  190. if( Track->m_Start != pos )
  191. continue;
  192. if( Track->GetState( BUSY | DELETED ) )
  193. continue;
  194. if( layer < 0 )
  195. return Track;
  196. if( ( (SEGVIA*) Track )->IsViaOnLayer( layer ) )
  197. return Track;
  198. }
  199. return NULL;
  200. }
  201. /********************************************************************/
  202. D_PAD* Locate_Pad_Connecte( BOARD* Pcb, TRACK* ptr_piste, int extr )
  203. /********************************************************************/
  204. /* localisation de la pastille connectee au point de piste a tester
  205. * entree : ptr_piste: pointeur sur le segment de piste
  206. * extr = flag = START -> debut du segment a tester
  207. * = END -> fin du segment a tester
  208. * retourne:
  209. * un pointeur sur la description de la pastille si localisation
  210. * pointeur NULL si pastille non trouvee
  211. */
  212. {
  213. D_PAD* ptr_pad = NULL;
  214. int masque_layer;
  215. MODULE* module;
  216. wxPoint ref_pos;
  217. masque_layer = g_TabOneLayerMask[ptr_piste->m_Layer];
  218. if( extr == START )
  219. {
  220. ref_pos = ptr_piste->m_Start;
  221. }
  222. else
  223. {
  224. ref_pos = ptr_piste->m_End;
  225. }
  226. module = Pcb->m_Modules;
  227. for( ; module != NULL; module = (MODULE*) module->Pnext )
  228. {
  229. ptr_pad = Locate_Pads( module, ref_pos, masque_layer );
  230. if( ptr_pad != NULL )
  231. break;
  232. }
  233. return ptr_pad;
  234. }
  235. /****************************************************************/
  236. EDGE_MODULE* Locate_Edge_Module( MODULE* module, int typeloc )
  237. /****************************************************************/
  238. /* Localisation de segments de contour du type edge MODULE
  239. * Les contours sont de differents type:
  240. * simple : succession de droites
  241. * Arcs de cercles : on a alors debut arc, fin arc , centre
  242. * si debut arc = fin arc : cercle complet
  243. *
  244. * Retourne:
  245. * Pointeur sur le segment localise
  246. * NULL si rien trouve
  247. */
  248. {
  249. if( !module )
  250. return NULL;
  251. /* coord du point de localisation */
  252. wxPoint ref_pos = RefPos( typeloc );
  253. EDA_BaseStruct* PtStruct = module->m_Drawings;
  254. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  255. {
  256. if( PtStruct->m_StructType != TYPEEDGEMODULE )
  257. continue;
  258. // calls virtual EDGE_MODULE::HitTest()
  259. if( PtStruct->HitTest( ref_pos ) )
  260. return (EDGE_MODULE*) PtStruct;
  261. }
  262. return NULL;
  263. }
  264. /*************************************************************************/
  265. EDA_BaseStruct* Locate_Cotation( BOARD* Pcb, int LayerSearch, int typeloc )
  266. /*************************************************************************/
  267. /* Serach for a cotation item , on LayerSearch,
  268. * (if LayerSearch == -1 , no yaere restriction )
  269. * return a pointer to the located item, or NULL
  270. */
  271. {
  272. wxPoint ref_pos = RefPos( typeloc );
  273. EDA_BaseStruct* PtStruct = Pcb->m_Drawings;
  274. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  275. {
  276. if( PtStruct->m_StructType != TYPECOTATION )
  277. continue;
  278. // calls virtual COTATION::HitTest()
  279. if( PtStruct->HitTest( ref_pos ) )
  280. return (COTATION*) PtStruct;
  281. }
  282. return NULL;
  283. }
  284. /*************************************************************************/
  285. DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int LayerSearch, int typeloc )
  286. /*************************************************************************/
  287. /* Localisation de segments de contour du type drawing
  288. * Retourne:
  289. * Pointeur sur DEBUT du segment localise
  290. * NULL si rien trouve
  291. * Le segment sur la couche active est dtect en priorite
  292. */
  293. {
  294. DRAWSEGMENT* locate_segm = NULL;
  295. PCB_SCREEN* screen = (PCB_SCREEN*) ActiveScreen;
  296. wxPoint ref_pos = RefPos( typeloc );
  297. EDA_BaseStruct* PtStruct = Pcb->m_Drawings;
  298. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  299. {
  300. if( PtStruct->m_StructType != TYPEDRAWSEGMENT )
  301. continue;
  302. DRAWSEGMENT* pts = (DRAWSEGMENT*) PtStruct;
  303. if( (pts->m_Layer != LayerSearch) && (LayerSearch != -1) )
  304. continue;
  305. if( pts->HitTest( ref_pos ) )
  306. {
  307. // return this hit if layer matches, else remember in
  308. // case no layer match is found.
  309. if( pts->m_Layer == screen->m_Active_Layer )
  310. return pts;
  311. else if( !locate_segm )
  312. locate_segm = pts;
  313. }
  314. }
  315. return locate_segm;
  316. }
  317. /*************************************************
  318. * D_PAD * Locate_Any_Pad(int typeloc, bool OnlyCurrentLayer)
  319. * D_PAD* Locate_Any_Pad(int ref_pos, bool OnlyCurrentLayer)
  320. *************************************************/
  321. /*
  322. * localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou
  323. * par la souris, recherche faite sur toutes les empreintes.
  324. * entree :
  325. * - coord souris
  326. * ou ref_pos
  327. * retourne:
  328. * pointeur sur la description de la pastille si localisation
  329. * pointeur NULL si pastille non trouvee
  330. * num_empr = numero d'empreinte du pad
  331. *
  332. * la priorit est donne a la couche active
  333. */
  334. D_PAD* Locate_Any_Pad( BOARD* Pcb, int typeloc, bool OnlyCurrentLayer )
  335. {
  336. wxPoint ref_pos = RefPos( typeloc );
  337. return Locate_Any_Pad( Pcb, ref_pos, OnlyCurrentLayer );
  338. }
  339. D_PAD* Locate_Any_Pad( BOARD* Pcb, const wxPoint& ref_pos, bool OnlyCurrentLayer )
  340. {
  341. D_PAD* pt_pad;
  342. MODULE* module;
  343. int layer_mask = g_TabOneLayerMask[ ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer];
  344. module = Pcb->m_Modules;
  345. for( ; module != NULL; module = (MODULE*) module->Pnext )
  346. {
  347. /* First: Search a pad on the active layer: */
  348. if( ( pt_pad = Locate_Pads( module, ref_pos, layer_mask ) ) != NULL )
  349. return pt_pad;
  350. /* If not found, search on other layers: */
  351. if( !OnlyCurrentLayer )
  352. {
  353. if( ( pt_pad = Locate_Pads( module, ref_pos, ALL_LAYERS ) ) != NULL )
  354. return pt_pad;
  355. }
  356. }
  357. return NULL;
  358. }
  359. /******************************************************************************/
  360. /* D_PAD* Locate_Pads(MODULE * module, int masque_layer,int typeloc) */
  361. /* D_PAD* Locate_Pads(MODULE * module, const wxPoint & ref_pos,int masque_layer) */
  362. /******************************************************************************/
  363. /* localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou
  364. * par la souris, concernant l'empreinte en cours.
  365. * entree :
  366. * - parametres generaux de l'empreinte mise a jour par caract()
  367. * - masque_layer = couche(s) (bit_masque)sur laquelle doit etre la pastille
  368. * retourne:
  369. * un pointeur sur la description de la pastille si localisation
  370. * pointeur NULL si pastille non trouvee
  371. */
  372. D_PAD* Locate_Pads( MODULE* module, int masque_layer, int typeloc )
  373. {
  374. wxPoint ref_pos = RefPos( typeloc );
  375. return Locate_Pads( module, ref_pos, masque_layer );
  376. }
  377. D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int masque_layer )
  378. {
  379. D_PAD* pt_pad = module->m_Pads;
  380. for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext )
  381. {
  382. /* ... et sur la bonne couche */
  383. if( (pt_pad->m_Masque_Layer & masque_layer) == 0 )
  384. continue;
  385. if( pt_pad->HitTest( ref_pos ) )
  386. return pt_pad;
  387. }
  388. return NULL;
  389. }
  390. /********************************************************/
  391. MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc )
  392. /********************************************************/
  393. /*
  394. * localisation d'une empreinte par son rectangle d'encadrement
  395. * Si plusieurs empreintes sont possibles, la priorite est:
  396. * - sur la couche active
  397. * - la plus petite
  398. */
  399. {
  400. MODULE* pt_module;
  401. int lx, ly; /* dimensions du rectangle d'encadrement du module */
  402. MODULE* module = NULL; /* module localise sur la couche active */
  403. MODULE* Altmodule = NULL; /* module localise sur les couches non actives */
  404. int min_dim = 0x7FFFFFFF; /* dim mini du module localise sur la couche active */
  405. int alt_min_dim = 0x7FFFFFFF; /* dim mini du module localise sur les couches non actives */
  406. int layer; /* pour calcul de couches prioritaires */
  407. wxPoint ref_pos; /* coord du point de reference pour la localisation */
  408. ref_pos = RefPos( typeloc );
  409. pt_module = Pcb->m_Modules;
  410. for( ; pt_module; pt_module = (MODULE*) pt_module->Pnext )
  411. {
  412. // is the ref point within the module's bounds?
  413. if( !pt_module->HitTest( ref_pos ) )
  414. continue;
  415. // if caller wants to ignore locked modules, and this one is locked, skip it.
  416. if( (typeloc & IGNORE_LOCKED) && pt_module->IsLocked() )
  417. continue;
  418. /* calcul de priorite: la priorite est donnee a la couche
  419. * d'appartenance du module et a la couche cuivre si le module
  420. * est sur couche serigr,adhesive cuivre, a la couche cmp si le module
  421. * est sur couche serigr,adhesive composant */
  422. layer = pt_module->m_Layer;
  423. if( layer==ADHESIVE_N_CU || layer==SILKSCREEN_N_CU )
  424. layer = CUIVRE_N;
  425. else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP )
  426. layer = CMP_N;
  427. /* Localisation: test des dimensions minimales, choix du meilleur candidat */
  428. /* calcul des dimensions du cadre :*/
  429. lx = pt_module->m_BoundaryBox.GetWidth();
  430. ly = pt_module->m_BoundaryBox.GetHeight();
  431. if( ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer == layer )
  432. {
  433. if( min( lx, ly ) <= min_dim )
  434. {
  435. /* meilleure empreinte localisee sur couche active */
  436. module = pt_module;
  437. min_dim = min( lx, ly );
  438. }
  439. }
  440. else if( !(typeloc & MATCH_LAYER)
  441. && ( !(typeloc & VISIBLE_ONLY) || IsModuleLayerVisible( layer ) ) )
  442. {
  443. if( min( lx, ly ) <= alt_min_dim )
  444. {
  445. /* meilleure empreinte localisee sur autres couches */
  446. Altmodule = pt_module;
  447. alt_min_dim = min( lx, ly );
  448. }
  449. }
  450. }
  451. if( module )
  452. {
  453. return module;
  454. }
  455. if( Altmodule )
  456. {
  457. return Altmodule;
  458. }
  459. return NULL;
  460. }
  461. /*****************************************************************************/
  462. TEXTE_MODULE* LocateTexteModule( BOARD* Pcb, MODULE** PtModule, int typeloc )
  463. /*****************************************************************************/
  464. /* localisation du texte pointe par la souris (texte sur empreinte)
  465. *
  466. * si * PtModule == NULL; recherche sur tous les modules
  467. * sinon sur le module pointe par module
  468. *
  469. * retourne
  470. * - pointeur sur le texte localise ( ou NULL )
  471. * - si Ptmodule != NULL: pointeur sur module module ( non modifie sinon )
  472. *
  473. * if typeloc has the flag VISIBLE_ONLY set, only footprints which are
  474. * "visible" are considered
  475. */
  476. {
  477. EDA_BaseStruct* PtStruct;
  478. TEXTE_MODULE* pt_txt_mod;
  479. MODULE* module;
  480. wxPoint ref_pos;
  481. ref_pos = RefPos( typeloc );
  482. module = *PtModule;
  483. if( module == NULL )
  484. {
  485. module = Pcb->m_Modules;
  486. }
  487. for( ; module != NULL; module = (MODULE*) module->Pnext )
  488. {
  489. int layer = module->m_Layer;
  490. if( layer==ADHESIVE_N_CU || layer==SILKSCREEN_N_CU )
  491. layer = CUIVRE_N;
  492. else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP )
  493. layer = CMP_N;
  494. if( typeloc & VISIBLE_ONLY )
  495. {
  496. if( !IsModuleLayerVisible( layer ) )
  497. continue;
  498. }
  499. if( typeloc & MATCH_LAYER )
  500. {
  501. if( ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer != layer )
  502. continue;
  503. }
  504. // hit-test the reference text
  505. pt_txt_mod = module->m_Reference;
  506. if( pt_txt_mod->HitTest( ref_pos ) )
  507. {
  508. if( PtModule )
  509. *PtModule = module;
  510. return pt_txt_mod;
  511. }
  512. // hit-test the value text
  513. pt_txt_mod = module->m_Value;
  514. if( pt_txt_mod->HitTest( ref_pos ) )
  515. {
  516. if( PtModule )
  517. *PtModule = module;
  518. return pt_txt_mod;
  519. }
  520. // hit-test any other texts
  521. PtStruct = module->m_Drawings;
  522. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  523. {
  524. if( PtStruct->m_StructType != TYPETEXTEMODULE )
  525. continue;
  526. pt_txt_mod = (TEXTE_MODULE*) PtStruct;
  527. if( pt_txt_mod->HitTest( ref_pos ) )
  528. {
  529. if( PtModule )
  530. *PtModule = module;
  531. return pt_txt_mod;
  532. }
  533. }
  534. if( *PtModule != NULL )
  535. break; /* Recherche limitee a 1 seul module */
  536. }
  537. return NULL;
  538. }
  539. /**************************************************************/
  540. TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base,
  541. TRACK* pt_lim, int extr )
  542. /**************************************************************/
  543. /* recherche le segment connecte au segment pointe par
  544. * PtRefSegm:
  545. * si int extr = START, le point de debut du segment est utilise
  546. * si int extr = END, le point de fin du segment est utilise
  547. * La recherche ne se fait que sur les EXTREMITES des segments
  548. *
  549. * La recherche se fait de l'adresse :
  550. * pt_base a pt_lim (borne finale comprise)
  551. * si pt_lim = NULL, la recherche se fait jusqu'a la fin de la liste
  552. * Afin d'accelerer la recherche, une 1ere passe est faite, avec une recherche
  553. * realisee sur un ensemble de +/- 100 points autour du point courant.
  554. * Si echec: recherche generale
  555. */
  556. {
  557. TRACK* PtSegmB, * PtSegmN;
  558. int Reflayer;
  559. wxPoint pos_ref;
  560. int ii;
  561. if( extr == START )
  562. pos_ref = PtRefSegm->m_Start;
  563. else
  564. pos_ref = PtRefSegm->m_End;
  565. Reflayer = PtRefSegm->ReturnMaskLayer();
  566. /* 1ere passe */
  567. PtSegmB = PtSegmN = PtRefSegm;
  568. for( ii = 0; ii < 50; ii++ )
  569. {
  570. if( (PtSegmN == NULL) && (PtSegmB == NULL) )
  571. break;
  572. if( PtSegmN )
  573. {
  574. if( PtSegmN->GetState( BUSY | DELETED ) )
  575. goto suite;
  576. if( PtSegmN == PtRefSegm )
  577. goto suite;
  578. if( pos_ref == PtSegmN->m_Start )
  579. { /* Test des couches */
  580. if( Reflayer & PtSegmN->ReturnMaskLayer() )
  581. return PtSegmN;
  582. }
  583. if( pos_ref == PtSegmN->m_End )
  584. { /* Test des couches */
  585. if( Reflayer & PtSegmN->ReturnMaskLayer() )
  586. return PtSegmN;
  587. }
  588. suite:
  589. if( PtSegmN == pt_lim )
  590. PtSegmN = NULL;
  591. else
  592. PtSegmN = (TRACK*) PtSegmN->Pnext;
  593. }
  594. if( PtSegmB )
  595. {
  596. if( PtSegmB->GetState( BUSY | DELETED ) )
  597. goto suite1;
  598. if( PtSegmB == PtRefSegm )
  599. goto suite1;
  600. if( pos_ref == PtSegmB->m_Start )
  601. { /* Test des couches */
  602. if( Reflayer & PtSegmB->ReturnMaskLayer() )
  603. return PtSegmB;
  604. }
  605. if( pos_ref == PtSegmB->m_End )
  606. { /* Test des couches */
  607. if( Reflayer & PtSegmB->ReturnMaskLayer() )
  608. return PtSegmB;
  609. }
  610. suite1:
  611. if( PtSegmB == pt_base )
  612. PtSegmB = NULL;
  613. else if( PtSegmB->m_StructType != TYPEPCB )
  614. PtSegmB = (TRACK*) PtSegmB->Pback;
  615. else
  616. PtSegmB = NULL;
  617. }
  618. }
  619. /* Recherche generale */
  620. for( PtSegmN = pt_base; PtSegmN != NULL; PtSegmN = (TRACK*) PtSegmN->Pnext )
  621. {
  622. if( PtSegmN->GetState( DELETED | BUSY ) )
  623. {
  624. if( PtSegmN == pt_lim )
  625. break;
  626. continue;
  627. }
  628. if( PtSegmN == PtRefSegm )
  629. {
  630. if( PtSegmN == pt_lim )
  631. break;
  632. continue;
  633. }
  634. if( pos_ref == PtSegmN->m_Start )
  635. { /* Test des couches */
  636. if( Reflayer & PtSegmN->ReturnMaskLayer() )
  637. return PtSegmN;
  638. }
  639. if( pos_ref == PtSegmN->m_End )
  640. { /* Test des couches */
  641. if( Reflayer & PtSegmN->ReturnMaskLayer() )
  642. return PtSegmN;
  643. }
  644. if( PtSegmN == pt_lim )
  645. break;
  646. }
  647. return NULL;
  648. }
  649. /****************************************************************************/
  650. /* TRACK *Locate_Pistes(TRACK * start_adresse, int MasqueLayer,int typeloc) */
  651. /* TRACK *Locate_Pistes(TRACK * start_adresse, int ref_pos.x, int ref_pos.y,*/
  652. /* int MasqueLayer) */
  653. /****************************************************************************/
  654. /*
  655. * 1 - routine de localisation du segment de piste pointe par la souris.
  656. * 2 - routine de localisation du segment de piste pointe par le point
  657. * ref_pos.x , ref_pos.y.r
  658. *
  659. * La recherche commence a l'adresse start_adresse
  660. */
  661. TRACK* Locate_Pistes( TRACK* start_adresse, int MasqueLayer, int typeloc )
  662. {
  663. wxPoint ref_pos = RefPos( typeloc );
  664. return Locate_Pistes( start_adresse, ref_pos, MasqueLayer );
  665. }
  666. TRACK* Locate_Pistes( TRACK* start_adresse, const wxPoint& ref_pos, int MasqueLayer )
  667. {
  668. for( TRACK* Track = start_adresse; Track; Track = (TRACK*) Track->Pnext )
  669. {
  670. if( Track->GetState( BUSY | DELETED ) )
  671. continue;
  672. if( (g_DesignSettings.m_LayerColor[Track->m_Layer] & ITEM_NOT_SHOW) )
  673. continue;
  674. if( Track->m_StructType == TYPEVIA ) /* VIA rencontree */
  675. {
  676. if( Track->HitTest( ref_pos ) )
  677. return Track;
  678. }
  679. else
  680. {
  681. if( MasqueLayer != -1 )
  682. if( (g_TabOneLayerMask[Track->m_Layer] & MasqueLayer) == 0 )
  683. continue; /* Segments sur couches differentes */
  684. if( Track->HitTest( ref_pos ) )
  685. return Track;
  686. }
  687. }
  688. return NULL;
  689. }
  690. /****************************************************************/
  691. /* TRACK * Locate_Zone(TRACK * start_adresse, int layer, */
  692. /* int typeloc) */
  693. /* TRACK * Locate_Zone(TRACK * start_adresse, */
  694. /* const wxPoint & ref_pos, */
  695. /* int layer) */
  696. /****************************************************************/
  697. /*
  698. * 1 - routine de localisation du segment de zone pointe par la souris.
  699. * 2 - routine de localisation du segment de zone pointe par le point
  700. * ref_pos.x , ref_pos.y.r
  701. *
  702. * Si layer == -1 , le tst de la couche n'est pas fait
  703. *
  704. * La recherche commence a l'adresse start_adresse
  705. */
  706. TRACK* Locate_Zone( TRACK* start_adresse, int layer, int typeloc )
  707. {
  708. wxPoint ref_pos = RefPos( typeloc );
  709. return Locate_Zone( start_adresse, ref_pos, layer );
  710. }
  711. TRACK* Locate_Zone( TRACK* start_adresse, const wxPoint& ref_pos, int layer )
  712. {
  713. for( TRACK* Zone = start_adresse; Zone; Zone = (TRACK*) Zone->Pnext )
  714. {
  715. if( (layer != -1) && (Zone->m_Layer != layer) )
  716. continue;
  717. if( Zone->HitTest( ref_pos ) )
  718. return Zone;
  719. }
  720. return NULL;
  721. }
  722. /************************************************************************************/
  723. TEXTE_PCB* Locate_Texte_Pcb( EDA_BaseStruct* PtStruct, int LayerSearch, int typeloc )
  724. /************************************************************************************/
  725. /* localisation des inscriptions sur le Pcb:
  726. * entree : EDA_BaseStruct pointeur sur le debut de la zone de recherche
  727. * retour : pointeur sur la description du texte localise
  728. */
  729. {
  730. wxPoint ref = RefPos( typeloc );
  731. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  732. {
  733. if( PtStruct->m_StructType != TYPETEXTE )
  734. continue;
  735. TEXTE_PCB* pt_txt_pcb = (TEXTE_PCB*) PtStruct;
  736. if( pt_txt_pcb->m_Layer == LayerSearch )
  737. {
  738. // because HitTest() is present in both base classes of TEXTE_PCB
  739. // use a clarifying cast to tell compiler which HitTest()
  740. // to call.
  741. if( static_cast<EDA_TextStruct*>(pt_txt_pcb)->HitTest( ref ) )
  742. {
  743. return pt_txt_pcb;
  744. }
  745. }
  746. }
  747. return NULL;
  748. }
  749. /*******************************************************************************/
  750. D_PAD* Fast_Locate_Pad_Connecte( BOARD* Pcb, const wxPoint& ref_pos, int masque_layer )
  751. /*******************************************************************************/
  752. /* Routine cherchant le pad de centre px,py,
  753. * sur la couche indiquee par masque_layer (bit a bit)
  754. * ( extremite de piste )
  755. * La liste des pads doit deja exister.
  756. *
  757. * retourne :
  758. * NULL si pas de pad localise.
  759. * pointeur sur la structure descr_pad correspondante si pad trouve
  760. * (bonne position ET bonne couche).
  761. */
  762. {
  763. D_PAD* pad;
  764. LISTE_PAD* ptr_pad, * lim;
  765. lim = (LISTE_PAD*) Pcb->m_Pads + Pcb->m_NbPads;
  766. for( ptr_pad = (LISTE_PAD*) Pcb->m_Pads; ptr_pad < lim; ptr_pad++ )
  767. {
  768. pad = *ptr_pad;
  769. if( pad->m_Pos != ref_pos )
  770. continue;
  771. /* Pad peut-etre trouve ici : il doit etre sur la bonne couche */
  772. if( pad->m_Masque_Layer & masque_layer )
  773. return pad;
  774. }
  775. return NULL;
  776. }
  777. /***********************************************************************************/
  778. TRACK* Fast_Locate_Piste( TRACK* start_adr, TRACK* end_adr,
  779. const wxPoint& ref_pos, int MaskLayer )
  780. /***********************************************************************************/
  781. /* Localiste le segment dont une extremite coincide avec le point x,y
  782. * sur les couches donnees par masklayer
  783. * la recherche se fait de l'adresse start_adr a end_adr
  784. * si end_adr = NULL, recherche jusqu'a la fin de la liste
  785. * Les segments de piste marques avec le flag DELETED ne sont pas
  786. * pris en compte
  787. */
  788. {
  789. TRACK* PtSegm;
  790. if( start_adr == NULL )
  791. return NULL;
  792. for( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext )
  793. {
  794. if( PtSegm->GetState( DELETED | BUSY ) == 0 )
  795. {
  796. if( ref_pos == PtSegm->m_Start )
  797. {
  798. /* Test des couches */
  799. if( MaskLayer & PtSegm->ReturnMaskLayer() )
  800. return PtSegm;
  801. }
  802. if( ref_pos == PtSegm->m_End )
  803. {
  804. /* Test des couches */
  805. if( MaskLayer & PtSegm->ReturnMaskLayer() )
  806. return PtSegm;
  807. }
  808. }
  809. if( PtSegm == end_adr )
  810. break;
  811. }
  812. return NULL;
  813. }
  814. /*******************************************************************/
  815. TRACK* Fast_Locate_Via( TRACK* start_adr, TRACK* end_adr,
  816. const wxPoint& pos, int MaskLayer )
  817. /*******************************************************************/
  818. /* Localise la via de centre le point x,y , sur les couches donnees
  819. * par masklayer
  820. * la recherche se fait de l'adresse start_adr a end_adr.
  821. * si end_adr = NULL, recherche jusqu'a la fin de la liste
  822. * les vias dont le parametre State a le bit DELETED ou BUSY = 1 sont ignorees
  823. */
  824. {
  825. TRACK* PtSegm;
  826. for( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext )
  827. {
  828. if( PtSegm->m_StructType == TYPEVIA )
  829. {
  830. if( pos == PtSegm->m_Start )
  831. {
  832. if( PtSegm->GetState( BUSY | DELETED ) == 0 )
  833. {
  834. /* Test des couches */
  835. if( MaskLayer & PtSegm->ReturnMaskLayer() )
  836. return PtSegm;
  837. }
  838. }
  839. }
  840. if( PtSegm == end_adr )
  841. break;
  842. }
  843. return NULL;
  844. }
  845. /***********************************************************************/
  846. EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch,
  847. int typeloc )
  848. /***********************************************************************/
  849. /* Search for a photo target
  850. */
  851. {
  852. wxPoint ref_pos;/* coord du point de localisation */
  853. if( PtStruct == NULL )
  854. return NULL;
  855. ref_pos = RefPos( typeloc );
  856. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  857. {
  858. MIREPCB* item;
  859. if( PtStruct->m_StructType != TYPEMIRE )
  860. continue;
  861. item = (MIREPCB*) PtStruct;
  862. if( LayerSearch != -1 && item->m_Layer != LayerSearch )
  863. continue;
  864. if( item->HitTest( ref_pos ) )
  865. break;
  866. }
  867. return PtStruct;
  868. }