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.

469 lines
12 KiB

18 years ago
18 years ago
18 years ago
18 years ago
14 years ago
14 years ago
14 years ago
14 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
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2004-2007 KiCad Developers, see change_log.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #include <collectors.h>
  25. #include <class_board_item.h> // class BOARD_ITEM
  26. #include <class_module.h>
  27. #include <class_pad.h>
  28. #include <class_track.h>
  29. #include <class_marker_pcb.h>
  30. /* This module contains out of line member functions for classes given in
  31. * collectors.h. Those classes augment the functionality of class PCB_EDIT_FRAME.
  32. */
  33. // see collectors.h
  34. const KICAD_T GENERAL_COLLECTOR::AllBoardItems[] = {
  35. // there are some restrictions on the order of items in the general case.
  36. // all items in m_Drawings for instance should be contiguous.
  37. // *** all items in a same list (shown here) must be contiguous ****
  38. PCB_MARKER_T, // in m_markers
  39. PCB_TEXT_T, // in m_Drawings
  40. PCB_LINE_T, // in m_Drawings
  41. PCB_DIMENSION_T, // in m_Drawings
  42. PCB_TARGET_T, // in m_Drawings
  43. PCB_VIA_T, // in m_Tracks
  44. PCB_TRACE_T, // in m_Tracks
  45. PCB_PAD_T, // in modules
  46. PCB_MODULE_TEXT_T, // in modules
  47. PCB_MODULE_T, // in m_Modules
  48. PCB_ZONE_T, // in m_Zones
  49. PCB_ZONE_AREA_T, // in m_ZoneDescriptorList
  50. EOT
  51. };
  52. /*
  53. * const KICAD_T GENERAL_COLLECTOR::PrimaryItems[] = {
  54. * PCB_TEXT_T,
  55. * PCB_LINE_T,
  56. * PCB_DIMENSION_T,
  57. * PCB_VIA_T,
  58. * PCB_TRACE_T,
  59. * PCB_MODULE_T,
  60. * EOT
  61. * };
  62. */
  63. const KICAD_T GENERAL_COLLECTOR::AllButZones[] = {
  64. PCB_MARKER_T,
  65. PCB_TEXT_T,
  66. PCB_LINE_T,
  67. PCB_DIMENSION_T,
  68. PCB_TARGET_T,
  69. PCB_VIA_T,
  70. PCB_TRACE_T,
  71. PCB_PAD_T,
  72. PCB_MODULE_TEXT_T,
  73. PCB_MODULE_T,
  74. PCB_ZONE_AREA_T, // if it is visible on screen, it should be selectable
  75. EOT
  76. };
  77. const KICAD_T GENERAL_COLLECTOR::Modules[] = {
  78. PCB_MODULE_T,
  79. EOT
  80. };
  81. const KICAD_T GENERAL_COLLECTOR::PadsOrModules[] = {
  82. PCB_PAD_T,
  83. PCB_MODULE_T,
  84. EOT
  85. };
  86. const KICAD_T GENERAL_COLLECTOR::PadsTracksOrZones[] = {
  87. PCB_PAD_T,
  88. PCB_VIA_T,
  89. PCB_TRACE_T,
  90. PCB_ZONE_T,
  91. PCB_ZONE_AREA_T,
  92. EOT
  93. };
  94. const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = {
  95. PCB_MODULE_TEXT_T,
  96. PCB_MODULE_EDGE_T,
  97. PCB_PAD_T,
  98. PCB_MODULE_T,
  99. EOT
  100. };
  101. const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = {
  102. PCB_MODULE_TEXT_T,
  103. PCB_MODULE_EDGE_T,
  104. PCB_PAD_T,
  105. EOT
  106. };
  107. const KICAD_T GENERAL_COLLECTOR::Tracks[] = {
  108. PCB_TRACE_T,
  109. PCB_VIA_T,
  110. EOT
  111. };
  112. const KICAD_T GENERAL_COLLECTOR::Zones[] = {
  113. PCB_ZONE_AREA_T,
  114. EOT
  115. };
  116. /**
  117. * Function Inspect
  118. * is the examining function within the INSPECTOR which is passed to the
  119. * Iterate function. Searches and collects all the objects that the old
  120. * function PcbGeneralLocateAndDisplay() would find, except that it keeps all
  121. * that it finds and does not do any displaying.
  122. *
  123. * @param testItem An EDA_ITEM to examine.
  124. * @param testData The const void* testData, not used here.
  125. * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
  126. * else SCAN_CONTINUE;
  127. */
  128. SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testData )
  129. {
  130. BOARD_ITEM* item = (BOARD_ITEM*) testItem;
  131. MODULE* module = NULL;
  132. D_PAD* pad = NULL;
  133. bool pad_through = false;
  134. VIA* via = NULL;
  135. MARKER_PCB* marker = NULL;
  136. #if 0 // debugging
  137. static int breakhere = 0;
  138. switch( item->Type() )
  139. {
  140. case PCB_PAD_T:
  141. {
  142. MODULE* m = (MODULE*) item->GetParent();
  143. if( m->GetReference() == wxT( "Y2" ) )
  144. {
  145. breakhere++;
  146. }
  147. }
  148. break;
  149. case PCB_VIA_T:
  150. breakhere++;
  151. break;
  152. case PCB_TRACE_T:
  153. breakhere++;
  154. break;
  155. case PCB_ZONE_T:
  156. breakhere++;
  157. break;
  158. case PCB_TEXT_T:
  159. breakhere++;
  160. break;
  161. case PCB_LINE_T:
  162. breakhere++;
  163. break;
  164. case PCB_DIMENSION_T:
  165. breakhere++;
  166. break;
  167. case PCB_MODULE_TEXT_T:
  168. {
  169. TEXTE_MODULE* tm = (TEXTE_MODULE*) item;
  170. if( tm->GetText() == wxT( "10uH" ) )
  171. {
  172. breakhere++;
  173. }
  174. }
  175. break;
  176. case PCB_MODULE_T:
  177. {
  178. MODULE* m = (MODULE*) item;
  179. if( m->GetReference() == wxT( "C98" ) )
  180. {
  181. breakhere++;
  182. }
  183. }
  184. break;
  185. case PCB_MARKER_T:
  186. breakhere++;
  187. break;
  188. default:
  189. breakhere++;
  190. break;
  191. }
  192. #endif
  193. switch( item->Type() )
  194. {
  195. case PCB_PAD_T:
  196. // there are pad specific visibility controls.
  197. // Criterias to select a pad is:
  198. // for smd pads: the module parent must be seen, and pads on the corresponding
  199. // board side must be seen
  200. // if pad is a thru hole, then it can be visible when its parent module is not.
  201. // for through pads: pads on Front or Back board sides must be seen
  202. pad = (D_PAD*) item;
  203. if( (pad->GetAttribute() != PAD_SMD) &&
  204. (pad->GetAttribute() != PAD_CONN) ) // a hole is present, so multiple layers
  205. {
  206. // proceed to the common tests below, but without the parent module test,
  207. // by leaving module==NULL, but having pad != null
  208. pad_through = true;
  209. }
  210. else // smd, so use pads test after module test
  211. {
  212. module = (MODULE*) item->GetParent();
  213. }
  214. break;
  215. case PCB_VIA_T: // vias are on many layers, so layer test is specific
  216. via = (VIA*) item;
  217. break;
  218. case PCB_TRACE_T:
  219. break;
  220. case PCB_ZONE_T:
  221. break;
  222. case PCB_ZONE_AREA_T:
  223. break;
  224. case PCB_TEXT_T:
  225. break;
  226. case PCB_LINE_T:
  227. break;
  228. case PCB_DIMENSION_T:
  229. break;
  230. case PCB_TARGET_T:
  231. break;
  232. case PCB_MODULE_TEXT_T:
  233. module = (MODULE*) item->GetParent();
  234. if( m_Guide->IgnoreMTextsMarkedNoShow() && !( (TEXTE_MODULE*) item )->IsVisible() )
  235. goto exit;
  236. if( module )
  237. {
  238. if( m_Guide->IgnoreMTextsOnCopper() && module->GetLayer()==B_Cu )
  239. goto exit;
  240. if( m_Guide->IgnoreMTextsOnCmp() && module->GetLayer()==F_Cu )
  241. goto exit;
  242. if( m_Guide->IgnoreModulesVals() && item == &module->Value() )
  243. goto exit;
  244. if( m_Guide->IgnoreModulesRefs() && item == &module->Reference() )
  245. goto exit;
  246. }
  247. break;
  248. case PCB_MODULE_T:
  249. module = (MODULE*) item;
  250. break;
  251. case PCB_MARKER_T:
  252. marker = (MARKER_PCB*) item;
  253. break;
  254. default:
  255. break;
  256. }
  257. // common tests:
  258. if( module ) // true from case PCB_PAD_T, PCB_MODULE_TEXT_T, or PCB_MODULE_T
  259. {
  260. if( m_Guide->IgnoreModulesOnCu() && module->GetLayer()==B_Cu )
  261. goto exit;
  262. if( m_Guide->IgnoreModulesOnCmp() && module->GetLayer()==F_Cu )
  263. goto exit;
  264. }
  265. // Pads are not sensitive to the layer visibility controls.
  266. // They all have their own separate visibility controls
  267. // skip them if not visible
  268. if( pad )
  269. {
  270. if( m_Guide->IgnorePads() )
  271. goto exit;
  272. if( ! pad_through )
  273. {
  274. if( m_Guide->IgnorePadsOnFront() && pad->IsOnLayer(F_Cu ) )
  275. goto exit;
  276. if( m_Guide->IgnorePadsOnBack() && pad->IsOnLayer(B_Cu ) )
  277. goto exit;
  278. }
  279. }
  280. if( marker )
  281. {
  282. // Markers are not sensitive to the layer
  283. if( marker->HitTest( m_RefPos ) )
  284. Append( item );
  285. goto exit;
  286. }
  287. if( item->IsOnLayer( m_Guide->GetPreferredLayer() ) || m_Guide->IgnorePreferredLayer() )
  288. {
  289. LAYER_ID layer = item->GetLayer();
  290. // Modules and their subcomponents: text and pads are not sensitive to the layer
  291. // visibility controls. They all have their own separate visibility controls
  292. // for vias, GetLayer() has no meaning, but IsOnLayer() works fine
  293. if( via || module || pad || m_Guide->IsLayerVisible( layer ) || !m_Guide->IgnoreNonVisibleLayers() )
  294. {
  295. if( !m_Guide->IsLayerLocked( layer ) || !m_Guide->IgnoreLockedLayers() )
  296. {
  297. if( !item->IsLocked() || !m_Guide->IgnoreLockedItems() )
  298. {
  299. if( item->HitTest( m_RefPos ) )
  300. {
  301. Append( item );
  302. goto exit;
  303. }
  304. }
  305. }
  306. }
  307. }
  308. if( m_Guide->IncludeSecondary() )
  309. {
  310. // for now, "secondary" means "tolerate any layer". It has
  311. // no effect on other criteria, since there is a separate "ignore" control for
  312. // those in the COLLECTORS_GUIDE
  313. LAYER_ID layer = item->GetLayer();
  314. // Modules and their subcomponents: text and pads are not sensitive to the layer
  315. // visibility controls. They all have their own separate visibility controls
  316. if( via || module || pad || m_Guide->IsLayerVisible( layer ) || !m_Guide->IgnoreNonVisibleLayers() )
  317. {
  318. if( !m_Guide->IsLayerLocked( layer ) || !m_Guide->IgnoreLockedLayers() )
  319. {
  320. if( !item->IsLocked() || !m_Guide->IgnoreLockedItems() )
  321. {
  322. if( item->HitTest( m_RefPos ) )
  323. {
  324. Append2nd( item );
  325. goto exit;
  326. }
  327. }
  328. }
  329. }
  330. }
  331. exit:
  332. return SEARCH_CONTINUE; // always when collecting
  333. }
  334. // see collectors.h
  335. void GENERAL_COLLECTOR::Collect( BOARD_ITEM* aItem, const KICAD_T aScanList[],
  336. const wxPoint& aRefPos, const COLLECTORS_GUIDE& aGuide )
  337. {
  338. Empty(); // empty the collection, primary criteria list
  339. Empty2nd(); // empty the collection, secondary criteria list
  340. // remember guide, pass it to Inspect()
  341. SetGuide( &aGuide );
  342. SetScanTypes( aScanList );
  343. // remember where the snapshot was taken from and pass refPos to
  344. // the Inspect() function.
  345. SetRefPos( aRefPos );
  346. // visit the board or module with the INSPECTOR (me).
  347. aItem->Visit( this, // INSPECTOR* inspector
  348. NULL, // const void* testData, not used here
  349. m_ScanTypes );
  350. SetTimeNow(); // when snapshot was taken
  351. // record the length of the primary list before concatonating on to it.
  352. m_PrimaryLength = m_List.size();
  353. // append 2nd list onto end of the first list
  354. for( unsigned i = 0; i<m_List2nd.size(); ++i )
  355. Append( m_List2nd[i] );
  356. Empty2nd();
  357. }
  358. // see collectors.h
  359. SEARCH_RESULT TYPE_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testData )
  360. {
  361. // The Vist() function only visits the testItem if its type was in the
  362. // the scanList, so therefore we can collect anything given to us here.
  363. Append( testItem );
  364. return SEARCH_CONTINUE; // always when collecting
  365. }
  366. void TYPE_COLLECTOR::Collect( BOARD_ITEM* aBoard, const KICAD_T aScanList[] )
  367. {
  368. Empty(); // empty any existing collection
  369. // visit the board with the INSPECTOR (me).
  370. aBoard->Visit( this, // INSPECTOR* inspector
  371. NULL, // const void* testData,
  372. aScanList );
  373. }
  374. //EOF