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.

396 lines
14 KiB

14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. /**
  24. * @file class_board_design_settings.cpp
  25. * BOARD_DESIGN_SETTINGS class functions.
  26. */
  27. #include <fctsys.h>
  28. #include <common.h>
  29. #include <layers_id_colors_and_visibility.h>
  30. #include <pcbnew.h>
  31. #include <class_board_design_settings.h>
  32. #include <class_track.h>
  33. #include <convert_from_iu.h>
  34. BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() :
  35. m_Pad_Master( NULL )
  36. {
  37. LSET all_set = LSET().set();
  38. m_enabledLayers = all_set; // All layers enabled at first.
  39. // SetCopperLayerCount() will adjust this.
  40. SetVisibleLayers( all_set );
  41. // set all but hidden text as visible.
  42. m_visibleElements = ~( 1 << MOD_TEXT_INVISIBLE );
  43. SetCopperLayerCount( 2 ); // Default design is a double sided board
  44. // via type (VIA_BLIND_BURIED, VIA_THROUGH VIA_MICROVIA).
  45. m_CurrentViaType = VIA_THROUGH;
  46. // if true, when creating a new track starting on an existing track, use this track width
  47. m_UseConnectedTrackWidth = false;
  48. m_BlindBuriedViaAllowed = false; // true to allow blind/buried vias
  49. m_MicroViasAllowed = false; // true to allow micro vias
  50. m_DrawSegmentWidth = Millimeter2iu( DEFAULT_GRAPHIC_THICKNESS ); // current graphic line width (not EDGE layer)
  51. m_EdgeSegmentWidth = Millimeter2iu( DEFAULT_PCB_EDGE_THICKNESS ); // current graphic line width (EDGE layer only)
  52. m_PcbTextWidth = Millimeter2iu( DEFAULT_TEXT_PCB_THICKNESS ); // current Pcb (not module) Text width
  53. m_PcbTextSize = wxSize( Millimeter2iu( DEFAULT_TEXT_PCB_SIZE ),
  54. Millimeter2iu( DEFAULT_TEXT_PCB_SIZE ) ); // current Pcb (not module) Text size
  55. m_useCustomTrackVia = false;
  56. m_customTrackWidth = Millimeter2iu( DEFAULT_CUSTOMTRACKWIDTH );
  57. m_customViaSize.m_Diameter = Millimeter2iu( DEFAULT_VIASMINSIZE );
  58. m_customViaSize.m_Drill = Millimeter2iu( DEFAULT_VIASMINDRILL );
  59. m_TrackMinWidth = Millimeter2iu( DEFAULT_TRACKMINWIDTH ); // track min width
  60. m_ViasMinSize = Millimeter2iu( DEFAULT_VIASMINSIZE ); // via (not uvia) min diam
  61. m_ViasMinDrill = Millimeter2iu( DEFAULT_VIASMINDRILL ); // via (not uvia) min drill diam
  62. m_MicroViasMinSize = Millimeter2iu( DEFAULT_MICROVIASMINSIZE );// uvia (not via) min diam
  63. m_MicroViasMinDrill = Millimeter2iu( DEFAULT_MICROVIASMINDRILL );// uvia (not via) min drill diam
  64. // Global mask margins:
  65. m_SolderMaskMargin = Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE ); // Solder mask margin
  66. m_SolderMaskMinWidth = Millimeter2iu( DEFAULT_SOLDERMASK_MIN_WIDTH ); // Solder mask min width
  67. m_SolderPasteMargin = 0; // Solder paste margin absolute value
  68. m_SolderPasteMarginRatio = 0.0; // Solder pask margin ratio value of pad size
  69. // The final margin is the sum of these 2 values
  70. // Usually < 0 because the mask is smaller than pad
  71. // Layer thickness for 3D viewer
  72. m_boardThickness = Millimeter2iu( DEFAULT_BOARD_THICKNESS_MM );
  73. m_viaSizeIndex = 0;
  74. m_trackWidthIndex = 0;
  75. // Default values for the footprint editor and fp creation
  76. // (also covers footprints created on the fly by micor-waves tools)
  77. m_ModuleTextSize = wxSize( Millimeter2iu( DEFAULT_TEXT_MODULE_SIZE ),
  78. Millimeter2iu( DEFAULT_TEXT_MODULE_SIZE ) );
  79. m_ModuleTextWidth = Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS );
  80. m_ModuleSegmentWidth = Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS );
  81. // These values will be overriden by config values after reading the config
  82. // Default ref text on fp creation. if empty, use footprint name as default
  83. m_RefDefaultText = wxT( "REF**" );
  84. m_RefDefaultVisibility = true; // Default ref text visibility on fp creation
  85. m_RefDefaultlayer = int( F_SilkS ); // Default ref text layer on fp creation
  86. // Default value text on fp creation. if empty, use footprint name as default
  87. m_ValueDefaultText = wxEmptyString;
  88. m_ValueDefaultVisibility = true;
  89. m_ValueDefaultlayer = int( F_Fab );
  90. }
  91. // Add parameters to save in project config.
  92. // values are saved in mm
  93. void BOARD_DESIGN_SETTINGS::AppendConfigs( PARAM_CFG_ARRAY* aResult )
  94. {
  95. m_Pad_Master.AppendConfigs( aResult );
  96. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PcbTextSizeV" ),
  97. &m_PcbTextSize.y,
  98. Millimeter2iu( DEFAULT_TEXT_PCB_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  99. NULL, MM_PER_IU ) );
  100. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PcbTextSizeH" ),
  101. &m_PcbTextSize.x,
  102. Millimeter2iu( DEFAULT_TEXT_PCB_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  103. NULL, MM_PER_IU ) );
  104. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PcbTextThickness" ),
  105. &m_PcbTextWidth,
  106. Millimeter2iu(DEFAULT_TEXT_PCB_THICKNESS ),
  107. Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  108. NULL, MM_PER_IU ) );
  109. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "ModuleTextSizeV" ),
  110. &m_ModuleTextSize.y,
  111. DEFAULT_TEXT_MODULE_SIZE, TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  112. NULL, MM_PER_IU ) );
  113. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "ModuleTextSizeH" ),
  114. &m_ModuleTextSize.x,
  115. DEFAULT_TEXT_MODULE_SIZE, TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  116. NULL, MM_PER_IU ) );
  117. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "ModuleTextSizeThickness" ),
  118. &m_ModuleTextWidth,
  119. Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS ), 1, TEXTS_MAX_WIDTH,
  120. NULL, MM_PER_IU ) );
  121. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SolderMaskClearance" ),
  122. &m_SolderMaskMargin,
  123. Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE ), 0, Millimeter2iu( 1.0 ),
  124. NULL, MM_PER_IU ) );
  125. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SolderMaskMinWidth" ),
  126. &m_SolderMaskMinWidth,
  127. Millimeter2iu( DEFAULT_SOLDERMASK_MIN_WIDTH ), 0, Millimeter2iu( 0.5 ),
  128. NULL, MM_PER_IU ) );
  129. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "DrawSegmentWidth" ),
  130. &m_DrawSegmentWidth,
  131. Millimeter2iu( DEFAULT_GRAPHIC_THICKNESS ),
  132. Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  133. NULL, MM_PER_IU ) );
  134. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "BoardOutlineThickness" ),
  135. &m_EdgeSegmentWidth,
  136. Millimeter2iu( DEFAULT_PCB_EDGE_THICKNESS ),
  137. Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  138. NULL, MM_PER_IU ) );
  139. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "ModuleOutlineThickness" ),
  140. &m_ModuleSegmentWidth,
  141. Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS ),
  142. Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  143. NULL, MM_PER_IU ) );
  144. }
  145. bool BOARD_DESIGN_SETTINGS::SetCurrentNetClass( const wxString& aNetClassName )
  146. {
  147. NETCLASSPTR netClass = m_NetClasses.Find( aNetClassName );
  148. bool lists_sizes_modified = false;
  149. // if not found (should not happen) use the default
  150. if( netClass == NULL )
  151. netClass = m_NetClasses.GetDefault();
  152. m_currentNetClassName = netClass->GetName();
  153. // Initialize others values:
  154. if( m_ViasDimensionsList.size() == 0 )
  155. {
  156. VIA_DIMENSION viadim;
  157. lists_sizes_modified = true;
  158. m_ViasDimensionsList.push_back( viadim );
  159. }
  160. if( m_TrackWidthList.size() == 0 )
  161. {
  162. lists_sizes_modified = true;
  163. m_TrackWidthList.push_back( 0 );
  164. }
  165. /* note the m_ViasDimensionsList[0] and m_TrackWidthList[0] values
  166. * are always the Netclass values
  167. */
  168. if( m_ViasDimensionsList[0].m_Diameter != netClass->GetViaDiameter() )
  169. {
  170. lists_sizes_modified = true;
  171. m_ViasDimensionsList[0].m_Diameter = netClass->GetViaDiameter();
  172. }
  173. if( m_ViasDimensionsList[0].m_Drill != netClass->GetViaDrill() )
  174. {
  175. lists_sizes_modified = true;
  176. m_ViasDimensionsList[0].m_Drill = netClass->GetViaDrill();
  177. }
  178. if( m_TrackWidthList[0] != netClass->GetTrackWidth() )
  179. {
  180. lists_sizes_modified = true;
  181. m_TrackWidthList[0] = netClass->GetTrackWidth();
  182. }
  183. if( GetViaSizeIndex() >= m_ViasDimensionsList.size() )
  184. SetViaSizeIndex( m_ViasDimensionsList.size() );
  185. if( GetTrackWidthIndex() >= m_TrackWidthList.size() )
  186. SetTrackWidthIndex( m_TrackWidthList.size() );
  187. return lists_sizes_modified;
  188. }
  189. int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue()
  190. {
  191. int clearance = m_NetClasses.GetDefault()->GetClearance();
  192. //Read list of Net Classes
  193. for( NETCLASSES::const_iterator nc = m_NetClasses.begin(); nc != m_NetClasses.end(); ++nc )
  194. {
  195. NETCLASSPTR netclass = nc->second;
  196. clearance = std::max( clearance, netclass->GetClearance() );
  197. }
  198. return clearance;
  199. }
  200. int BOARD_DESIGN_SETTINGS::GetSmallestClearanceValue()
  201. {
  202. int clearance = m_NetClasses.GetDefault()->GetClearance();
  203. //Read list of Net Classes
  204. for( NETCLASSES::const_iterator nc = m_NetClasses.begin(); nc != m_NetClasses.end(); ++nc )
  205. {
  206. NETCLASSPTR netclass = nc->second;
  207. clearance = std::min( clearance, netclass->GetClearance() );
  208. }
  209. return clearance;
  210. }
  211. int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaSize()
  212. {
  213. NETCLASSPTR netclass = m_NetClasses.Find( m_currentNetClassName );
  214. return netclass->GetuViaDiameter();
  215. }
  216. int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaDrill()
  217. {
  218. NETCLASSPTR netclass = m_NetClasses.Find( m_currentNetClassName );
  219. return netclass->GetuViaDrill();
  220. }
  221. void BOARD_DESIGN_SETTINGS::SetViaSizeIndex( unsigned aIndex )
  222. {
  223. if( aIndex >= m_ViasDimensionsList.size() )
  224. m_viaSizeIndex = m_ViasDimensionsList.size();
  225. else
  226. m_viaSizeIndex = aIndex;
  227. m_useCustomTrackVia = false;
  228. }
  229. int BOARD_DESIGN_SETTINGS::GetCurrentViaDrill() const
  230. {
  231. int drill;
  232. if( m_useCustomTrackVia )
  233. drill = m_customViaSize.m_Drill;
  234. else
  235. drill = m_ViasDimensionsList[m_viaSizeIndex].m_Drill;
  236. return drill > 0 ? drill : -1;
  237. }
  238. void BOARD_DESIGN_SETTINGS::SetTrackWidthIndex( unsigned aIndex )
  239. {
  240. if( aIndex >= m_TrackWidthList.size() )
  241. m_trackWidthIndex = m_TrackWidthList.size();
  242. else
  243. m_trackWidthIndex = aIndex;
  244. m_useCustomTrackVia = false;
  245. }
  246. void BOARD_DESIGN_SETTINGS::SetVisibleAlls()
  247. {
  248. SetVisibleLayers( LSET().set() );
  249. m_visibleElements = -1;
  250. }
  251. void BOARD_DESIGN_SETTINGS::SetLayerVisibility( LAYER_ID aLayer, bool aNewState )
  252. {
  253. if( aNewState && IsLayerEnabled( aLayer ) )
  254. m_visibleLayers.set( aLayer, true );
  255. else
  256. m_visibleLayers.set( aLayer, false );
  257. }
  258. void BOARD_DESIGN_SETTINGS::SetElementVisibility( int aElementCategory, bool aNewState )
  259. {
  260. if( aElementCategory < 0 || aElementCategory >= END_PCB_VISIBLE_LIST )
  261. return;
  262. if( aNewState )
  263. m_visibleElements |= 1 << aElementCategory;
  264. else
  265. m_visibleElements &= ~( 1 << aElementCategory );
  266. }
  267. void BOARD_DESIGN_SETTINGS::SetCopperLayerCount( int aNewLayerCount )
  268. {
  269. // if( aNewLayerCount < 2 ) aNewLayerCount = 2;
  270. m_copperLayerCount = aNewLayerCount;
  271. // ensure consistency with the m_EnabledLayers member
  272. #if 0
  273. // was:
  274. m_enabledLayers &= ~ALL_CU_LAYERS;
  275. m_enabledLayers |= LAYER_BACK;
  276. if( m_copperLayerCount > 1 )
  277. m_enabledLayers |= LAYER_FRONT;
  278. for( LAYER_NUM ii = LAYER_N_2; ii < aNewLayerCount - 1; ++ii )
  279. m_enabledLayers |= GetLayerSet( ii );
  280. #else
  281. // Update only enabled copper layers mask
  282. m_enabledLayers &= ~LSET::AllCuMask();
  283. m_enabledLayers |= LSET::AllCuMask( aNewLayerCount );
  284. #endif
  285. }
  286. void BOARD_DESIGN_SETTINGS::SetEnabledLayers( LSET aMask )
  287. {
  288. // Back and front layers are always enabled.
  289. aMask.set( B_Cu ).set( F_Cu );
  290. m_enabledLayers = aMask;
  291. // A disabled layer cannot be visible
  292. m_visibleLayers &= aMask;
  293. // update m_CopperLayerCount to ensure its consistency with m_EnabledLayers
  294. m_copperLayerCount = ( aMask & LSET::AllCuMask() ).count();
  295. }
  296. #ifndef NDEBUG
  297. struct list_size_check {
  298. list_size_check()
  299. {
  300. // Int (the type used for saving visibility settings) is only 32 bits guaranteed,
  301. // be sure that we do not cross the limit
  302. assert( END_PCB_VISIBLE_LIST <= 32 );
  303. };
  304. };
  305. static list_size_check check;
  306. #endif