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.

951 lines
33 KiB

8 years ago
8 years ago
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 board_design_settings.cpp
  25. * BOARD_DESIGN_SETTINGS class functions.
  26. */
  27. #include <fctsys.h>
  28. #include <common.h>
  29. #include <class_board.h>
  30. #include <layers_id_colors_and_visibility.h>
  31. #include <kiface_i.h>
  32. #include <pcbnew.h>
  33. #include <board_design_settings.h>
  34. #define CopperLayerCountKey wxT( "CopperLayerCount" )
  35. #define BoardThicknessKey wxT( "BoardThickness" )
  36. #define LayerKeyPrefix wxT( "Layer" )
  37. #define LayerNameKey wxT( "Name" )
  38. #define LayerTypeKey wxT( "Type" )
  39. #define NetclassNameKey wxT( "Name" )
  40. #define ClearanceKey wxT( "Clearance" )
  41. #define TrackWidthKey wxT( "TrackWidth" )
  42. #define ViaDiameterKey wxT( "ViaDiameter" )
  43. #define ViaDrillKey wxT( "ViaDrill" )
  44. #define uViaDiameterKey wxT( "uViaDiameter" )
  45. #define uViaDrillKey wxT( "uViaDrill" )
  46. #define dPairWidthKey wxT( "dPairWidth" )
  47. #define dPairGapKey wxT( "dPairGap" )
  48. #define dPairViaGapKey wxT( "dPairViaGap" )
  49. //
  50. // NOTE: layer configuration info is stored in both the BOARD and BOARD_DESIGN_SETTINGS so one
  51. // of the two needs to read/write the config so we don't end up with order dependency issues.
  52. //
  53. class PARAM_CFG_LAYERS : public PARAM_CFG_BASE
  54. {
  55. protected:
  56. BOARD* m_Pt_param; ///< Pointer to the parameter value
  57. public:
  58. PARAM_CFG_LAYERS( BOARD* ptparam, const wxChar* group = nullptr ) :
  59. PARAM_CFG_BASE( wxEmptyString, PARAM_LAYERS, group )
  60. {
  61. m_Pt_param = ptparam;
  62. }
  63. void ReadParam( wxConfigBase* aConfig ) const override
  64. {
  65. if( !m_Pt_param || !aConfig )
  66. return;
  67. BOARD* board = m_Pt_param;
  68. BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
  69. wxString oldPath = aConfig->GetPath();
  70. bds.SetCopperLayerCount( aConfig->Read( CopperLayerCountKey, 2 ) );
  71. double thickness = aConfig->ReadDouble( BoardThicknessKey, DEFAULT_BOARD_THICKNESS_MM );
  72. bds.SetBoardThickness( Millimeter2iu( thickness ) );
  73. for( LSEQ seq = LSET::AllCuMask().Seq(); seq; ++seq )
  74. {
  75. PCB_LAYER_ID layer = *seq;
  76. wxString layerName;
  77. int layerType;
  78. aConfig->SetPath( oldPath );
  79. aConfig->SetPath( LayerKeyPrefix + board->GetStandardLayerName( layer ) );
  80. if( aConfig->Read( LayerNameKey, &layerName ) )
  81. board->SetLayerName( layer, layerName );
  82. if( aConfig->Read( LayerTypeKey, &layerType ) )
  83. board->SetLayerType( layer, (LAYER_T) layerType );
  84. }
  85. aConfig->SetPath( oldPath );
  86. }
  87. void SaveParam( wxConfigBase* aConfig ) const override
  88. {
  89. if( !m_Pt_param || !aConfig )
  90. return;
  91. BOARD* board = m_Pt_param;
  92. BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
  93. wxString oldPath = aConfig->GetPath();
  94. wxString layerKeyPrefix = LayerKeyPrefix;
  95. aConfig->Write( CopperLayerCountKey, board->GetCopperLayerCount() );
  96. aConfig->Write( BoardThicknessKey, Iu2Millimeter( bds.GetBoardThickness() ) );
  97. for( LSEQ seq = LSET::AllCuMask().Seq(); seq; ++seq )
  98. {
  99. PCB_LAYER_ID layer = *seq;
  100. wxString stdName = board->GetStandardLayerName( layer );
  101. wxString layerName = board->GetLayerName( layer );
  102. LAYER_T layerType = board->GetLayerType( layer );
  103. aConfig->SetPath( oldPath );
  104. aConfig->SetPath( layerKeyPrefix + wxT( "." ) + stdName );
  105. if( layerName == stdName && layerType == LT_SIGNAL )
  106. {
  107. aConfig->DeleteGroup( aConfig->GetPath() );
  108. }
  109. else
  110. {
  111. aConfig->Write( LayerNameKey, layerName );
  112. aConfig->Write( LayerTypeKey, (int) layerType );
  113. }
  114. }
  115. aConfig->SetPath( oldPath );
  116. }
  117. };
  118. class PARAM_CFG_TRACKWIDTHS : public PARAM_CFG_BASE
  119. {
  120. protected:
  121. std::vector<int>* m_Pt_param; ///< Pointer to the parameter value
  122. public:
  123. PARAM_CFG_TRACKWIDTHS( std::vector<int>* ptparam, const wxChar* group = nullptr ) :
  124. PARAM_CFG_BASE( wxEmptyString, PARAM_TRACKWIDTHS, group )
  125. {
  126. m_Pt_param = ptparam;
  127. }
  128. void ReadParam( wxConfigBase* aConfig ) const override
  129. {
  130. if( !m_Pt_param || !aConfig )
  131. return;
  132. m_Pt_param->clear();
  133. for( int index = 1; ; ++index )
  134. {
  135. wxString key = TrackWidthKey;
  136. double width;
  137. if( !aConfig->Read( key << index, &width ) )
  138. break;
  139. m_Pt_param->push_back( Millimeter2iu( width ) );
  140. }
  141. }
  142. void SaveParam( wxConfigBase* aConfig ) const override
  143. {
  144. if( !m_Pt_param || !aConfig )
  145. return;
  146. for( size_t index = 1; index <= m_Pt_param->size(); ++index )
  147. {
  148. wxString key = TrackWidthKey;
  149. aConfig->Write( key << index, Iu2Millimeter( m_Pt_param->at( index - 1 ) ) );
  150. }
  151. }
  152. };
  153. class PARAM_CFG_VIADIMENSIONS : public PARAM_CFG_BASE
  154. {
  155. protected:
  156. std::vector<VIA_DIMENSION>* m_Pt_param; ///< Pointer to the parameter value
  157. public:
  158. PARAM_CFG_VIADIMENSIONS( std::vector<VIA_DIMENSION>* ptparam, const wxChar* group = nullptr ) :
  159. PARAM_CFG_BASE( wxEmptyString, PARAM_VIADIMENSIONS, group )
  160. {
  161. m_Pt_param = ptparam;
  162. }
  163. void ReadParam( wxConfigBase* aConfig ) const override
  164. {
  165. if( !m_Pt_param || !aConfig )
  166. return;
  167. m_Pt_param->clear();
  168. for( int index = 1; ; ++index )
  169. {
  170. double diameter = 0.0, drill = 0.0;
  171. wxString key = ViaDiameterKey;
  172. if( !aConfig->Read( key << index, &diameter ) )
  173. break;
  174. key = ViaDrillKey;
  175. drill = aConfig->ReadDouble( key << index, 0.0 );
  176. m_Pt_param->emplace_back( VIA_DIMENSION( Millimeter2iu( diameter ),
  177. Millimeter2iu( drill ) ) );
  178. }
  179. }
  180. void SaveParam( wxConfigBase* aConfig ) const override
  181. {
  182. if( !m_Pt_param || !aConfig )
  183. return;
  184. for( size_t index = 1; index <= m_Pt_param->size(); ++index )
  185. {
  186. wxString key = ViaDiameterKey;
  187. aConfig->Write( key << index, Iu2Millimeter( m_Pt_param->at( index - 1 ).m_Diameter ) );
  188. key = ViaDrillKey;
  189. aConfig->Write( key << index, Iu2Millimeter( m_Pt_param->at( index - 1 ).m_Drill ) );
  190. }
  191. }
  192. };
  193. class PARAM_CFG_DIFFPAIRDIMENSIONS : public PARAM_CFG_BASE
  194. {
  195. protected:
  196. std::vector<DIFF_PAIR_DIMENSION>* m_Pt_param; ///< Pointer to the parameter value
  197. public:
  198. PARAM_CFG_DIFFPAIRDIMENSIONS( std::vector<DIFF_PAIR_DIMENSION>* ptparam,
  199. const wxChar* group = nullptr ) :
  200. PARAM_CFG_BASE( wxEmptyString, PARAM_DIFFPAIRDIMENSIONS, group )
  201. {
  202. m_Pt_param = ptparam;
  203. }
  204. void ReadParam( wxConfigBase* aConfig ) const override
  205. {
  206. if( !m_Pt_param || !aConfig )
  207. return;
  208. m_Pt_param->clear();
  209. for( int index = 1; ; ++index )
  210. {
  211. double width, gap, viagap;
  212. wxString key = dPairWidthKey;
  213. if( !aConfig->Read( key << index, &width ) )
  214. break;
  215. key = dPairGapKey;
  216. gap = aConfig->ReadDouble( key << index, 0.0 );
  217. key = dPairViaGapKey;
  218. viagap = aConfig->ReadDouble( key << index, 0.0 );
  219. m_Pt_param->emplace_back( DIFF_PAIR_DIMENSION( Millimeter2iu( width ),
  220. Millimeter2iu( gap ),
  221. Millimeter2iu( viagap ) ) );
  222. }
  223. }
  224. void SaveParam( wxConfigBase* aConfig ) const override
  225. {
  226. if( !m_Pt_param || !aConfig )
  227. return;
  228. for( size_t index = 1; index <= m_Pt_param->size(); ++index )
  229. {
  230. wxString key = dPairWidthKey;
  231. aConfig->Write( key << index, Iu2Millimeter( m_Pt_param->at( index - 1 ).m_Width ) );
  232. key = dPairGapKey;
  233. aConfig->Write( key << index, Iu2Millimeter( m_Pt_param->at( index - 1 ).m_Gap ) );
  234. key = dPairViaGapKey;
  235. aConfig->Write( key << index, Iu2Millimeter( m_Pt_param->at( index - 1 ).m_ViaGap ) );
  236. }
  237. }
  238. };
  239. class PARAM_CFG_NETCLASSES : public PARAM_CFG_BASE
  240. {
  241. protected:
  242. NETCLASSES* m_Pt_param; ///< Pointer to the parameter value
  243. public:
  244. PARAM_CFG_NETCLASSES( const wxChar* ident, NETCLASSES* ptparam,
  245. const wxChar* group = nullptr ) :
  246. PARAM_CFG_BASE( ident, PARAM_NETCLASSES, group )
  247. {
  248. m_Pt_param = ptparam;
  249. }
  250. void ReadParam( wxConfigBase* aConfig ) const override
  251. {
  252. if( !m_Pt_param || !aConfig )
  253. return;
  254. wxString oldPath = aConfig->GetPath();
  255. m_Pt_param->Clear();
  256. for( int index = 1; ; ++index )
  257. {
  258. wxString pathIndex = wxString() << index;
  259. wxString netclassName;
  260. aConfig->SetPath( oldPath );
  261. aConfig->SetPath( m_Ident );
  262. aConfig->SetPath( pathIndex );
  263. if( !aConfig->Read( NetclassNameKey, &netclassName ) )
  264. break;
  265. NETCLASSPTR netclass = std::make_shared<NETCLASS>( netclassName );
  266. #define READ_MM( aKey, aDefault ) Millimeter2iu( aConfig->ReadDouble( aKey, aDefault ) )
  267. netclass->SetClearance( READ_MM( ClearanceKey, netclass->GetClearance() ) );
  268. netclass->SetTrackWidth( READ_MM( TrackWidthKey, netclass->GetTrackWidth() ) );
  269. netclass->SetViaDiameter( READ_MM( ViaDiameterKey, netclass->GetViaDiameter() ) );
  270. netclass->SetViaDrill( READ_MM( ViaDrillKey, netclass->GetViaDrill() ) );
  271. netclass->SetuViaDiameter( READ_MM( uViaDiameterKey, netclass->GetuViaDiameter() ) );
  272. netclass->SetuViaDrill( READ_MM( uViaDrillKey, netclass->GetuViaDrill() ) );
  273. netclass->SetDiffPairWidth( READ_MM( dPairWidthKey, netclass->GetDiffPairWidth() ) );
  274. netclass->SetDiffPairGap( READ_MM( dPairGapKey, netclass->GetDiffPairGap() ) );
  275. netclass->SetDiffPairViaGap( READ_MM( dPairViaGapKey, netclass->GetDiffPairViaGap() ) );
  276. m_Pt_param->Add( netclass );
  277. }
  278. aConfig->SetPath( oldPath );
  279. }
  280. void SaveParam( wxConfigBase* aConfig ) const override
  281. {
  282. if( !m_Pt_param || !aConfig )
  283. return;
  284. wxString oldPath = aConfig->GetPath();
  285. int index = 1;
  286. for( NETCLASSES::const_iterator nc = m_Pt_param->begin(); nc != m_Pt_param->end(); ++nc )
  287. {
  288. wxString pathIndex = wxString() << index++;
  289. NETCLASSPTR netclass = nc->second;
  290. aConfig->SetPath( oldPath );
  291. aConfig->SetPath( m_Ident );
  292. aConfig->SetPath( pathIndex );
  293. aConfig->Write( NetclassNameKey, netclass->GetName() );
  294. #define WRITE_MM( aKey, aValue ) aConfig->Write( aKey, Iu2Millimeter( aValue ) )
  295. WRITE_MM( ClearanceKey, netclass->GetClearance() );
  296. WRITE_MM( TrackWidthKey, netclass->GetTrackWidth() );
  297. WRITE_MM( ViaDiameterKey, netclass->GetViaDiameter() );
  298. WRITE_MM( ViaDrillKey, netclass->GetViaDrill() );
  299. WRITE_MM( uViaDiameterKey, netclass->GetuViaDiameter() );
  300. WRITE_MM( uViaDrillKey, netclass->GetuViaDrill() );
  301. WRITE_MM( dPairWidthKey, netclass->GetDiffPairWidth() );
  302. WRITE_MM( dPairGapKey, netclass->GetDiffPairGap() );
  303. WRITE_MM( dPairViaGapKey, netclass->GetDiffPairViaGap() );
  304. }
  305. aConfig->SetPath( oldPath );
  306. }
  307. };
  308. BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() :
  309. m_Pad_Master( NULL )
  310. {
  311. LSET all_set = LSET().set();
  312. m_enabledLayers = all_set; // All layers enabled at first.
  313. // SetCopperLayerCount() will adjust this.
  314. SetVisibleLayers( all_set );
  315. // set all but hidden text as visible.
  316. m_visibleElements = ~( 1 << GAL_LAYER_INDEX( LAYER_MOD_TEXT_INVISIBLE ) );
  317. SetCopperLayerCount( 2 ); // Default design is a double sided board
  318. m_CurrentViaType = VIA_THROUGH;
  319. // if true, when creating a new track starting on an existing track, use this track width
  320. m_UseConnectedTrackWidth = false;
  321. m_BlindBuriedViaAllowed = false;
  322. m_MicroViasAllowed = false;
  323. m_LineThickness[ LAYER_CLASS_SILK ] = Millimeter2iu( DEFAULT_SILK_LINE_WIDTH );
  324. m_TextSize[ LAYER_CLASS_SILK ] = wxSize( Millimeter2iu( DEFAULT_SILK_TEXT_SIZE ),
  325. Millimeter2iu( DEFAULT_SILK_TEXT_SIZE ) );
  326. m_TextThickness[ LAYER_CLASS_SILK ] = Millimeter2iu( DEFAULT_SILK_TEXT_WIDTH );
  327. m_TextItalic[ LAYER_CLASS_SILK ] = false;
  328. m_TextUpright[ LAYER_CLASS_SILK ] = true;
  329. m_LineThickness[ LAYER_CLASS_COPPER ] = Millimeter2iu( DEFAULT_COPPER_LINE_WIDTH );
  330. m_TextSize[ LAYER_CLASS_COPPER ] = wxSize( Millimeter2iu( DEFAULT_COPPER_TEXT_SIZE ),
  331. Millimeter2iu( DEFAULT_COPPER_TEXT_SIZE ) );
  332. m_TextThickness[ LAYER_CLASS_COPPER ] = Millimeter2iu( DEFAULT_COPPER_TEXT_WIDTH );
  333. m_TextItalic[ LAYER_CLASS_COPPER ] = false;
  334. m_TextUpright[ LAYER_CLASS_COPPER ] = true;
  335. // Edges & Courtyards; text properties aren't used but better to have them holding
  336. // reasonable values than not.
  337. m_LineThickness[ LAYER_CLASS_EDGES ] = Millimeter2iu( DEFAULT_EDGE_WIDTH );
  338. m_TextSize[ LAYER_CLASS_EDGES ] = wxSize( Millimeter2iu( DEFAULT_TEXT_SIZE ),
  339. Millimeter2iu( DEFAULT_TEXT_SIZE ) );
  340. m_TextThickness[ LAYER_CLASS_EDGES ] = Millimeter2iu( DEFAULT_TEXT_WIDTH );
  341. m_TextItalic[ LAYER_CLASS_EDGES ] = false;
  342. m_TextUpright[ LAYER_CLASS_EDGES ] = true;
  343. m_LineThickness[ LAYER_CLASS_COURTYARD ] = Millimeter2iu( DEFAULT_COURTYARD_WIDTH );
  344. m_TextSize[ LAYER_CLASS_COURTYARD ] = wxSize( Millimeter2iu( DEFAULT_TEXT_SIZE ),
  345. Millimeter2iu( DEFAULT_TEXT_SIZE ) );
  346. m_TextThickness[ LAYER_CLASS_COURTYARD ] = Millimeter2iu( DEFAULT_TEXT_WIDTH );
  347. m_TextItalic[ LAYER_CLASS_COURTYARD ] = false;
  348. m_TextUpright[ LAYER_CLASS_COURTYARD ] = true;
  349. m_LineThickness[ LAYER_CLASS_OTHERS ] = Millimeter2iu( DEFAULT_LINE_WIDTH );
  350. m_TextSize[ LAYER_CLASS_OTHERS ] = wxSize( Millimeter2iu( DEFAULT_TEXT_SIZE ),
  351. Millimeter2iu( DEFAULT_TEXT_SIZE ) );
  352. m_TextThickness[ LAYER_CLASS_OTHERS ] = Millimeter2iu( DEFAULT_TEXT_WIDTH );
  353. m_TextItalic[ LAYER_CLASS_OTHERS ] = false;
  354. m_TextUpright[ LAYER_CLASS_OTHERS ] = true;
  355. m_useCustomTrackVia = false;
  356. m_customTrackWidth = Millimeter2iu( DEFAULT_CUSTOMTRACKWIDTH );
  357. m_customViaSize.m_Diameter = Millimeter2iu( DEFAULT_VIASMINSIZE );
  358. m_customViaSize.m_Drill = Millimeter2iu( DEFAULT_VIASMINDRILL );
  359. m_useCustomDiffPair = false;
  360. m_customDiffPair.m_Width = Millimeter2iu( DEFAULT_CUSTOMDPAIRWIDTH );
  361. m_customDiffPair.m_Gap = Millimeter2iu( DEFAULT_CUSTOMDPAIRGAP );
  362. m_customDiffPair.m_ViaGap = Millimeter2iu( DEFAULT_CUSTOMDPAIRVIAGAP );
  363. m_TrackMinWidth = Millimeter2iu( DEFAULT_TRACKMINWIDTH );
  364. m_ViasMinSize = Millimeter2iu( DEFAULT_VIASMINSIZE );
  365. m_ViasMinDrill = Millimeter2iu( DEFAULT_VIASMINDRILL );
  366. m_MicroViasMinSize = Millimeter2iu( DEFAULT_MICROVIASMINSIZE );
  367. m_MicroViasMinDrill = Millimeter2iu( DEFAULT_MICROVIASMINDRILL );
  368. // Global mask margins:
  369. m_SolderMaskMargin = Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE );
  370. m_SolderMaskMinWidth = Millimeter2iu( DEFAULT_SOLDERMASK_MIN_WIDTH );
  371. m_SolderPasteMargin = 0; // Solder paste margin absolute value
  372. m_SolderPasteMarginRatio = 0.0; // Solder paste margin as a ratio of pad size
  373. // The final margin is the sum of these 2 values
  374. // Usually < 0 because the mask is smaller than pad
  375. // Layer thickness for 3D viewer
  376. m_boardThickness = Millimeter2iu( DEFAULT_BOARD_THICKNESS_MM );
  377. m_viaSizeIndex = 0;
  378. m_trackWidthIndex = 0;
  379. m_diffPairIndex = 0;
  380. // Default ref text on fp creation. If empty, use footprint name as default
  381. m_RefDefaultText = wxT( "REF**" );
  382. m_RefDefaultVisibility = true;
  383. m_RefDefaultlayer = int( F_SilkS );
  384. // Default value text on fp creation. If empty, use footprint name as default
  385. m_ValueDefaultText = wxEmptyString;
  386. m_ValueDefaultVisibility = true;
  387. m_ValueDefaultlayer = int( F_Fab );
  388. }
  389. // Add parameters to save in project config.
  390. // values are saved in mm
  391. void BOARD_DESIGN_SETTINGS::AppendConfigs( BOARD* aBoard, PARAM_CFG_ARRAY* aResult )
  392. {
  393. aResult->push_back( new PARAM_CFG_LAYERS( aBoard ) );
  394. aResult->push_back( new PARAM_CFG_BOOL( wxT( "AllowMicroVias" ),
  395. &m_MicroViasAllowed, false ) );
  396. aResult->push_back( new PARAM_CFG_BOOL( wxT( "AllowBlindVias" ),
  397. &m_BlindBuriedViaAllowed, false ) );
  398. aResult->push_back( new PARAM_CFG_BOOL( wxT( "RequireCourtyardDefinitions" ),
  399. &m_RequireCourtyards, false ) );
  400. aResult->push_back( new PARAM_CFG_BOOL( wxT( "ProhibitOverlappingCourtyards" ),
  401. &m_ProhibitOverlappingCourtyards, true ) );
  402. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "MinTrackWidth" ),
  403. &m_TrackMinWidth,
  404. Millimeter2iu( DEFAULT_TRACKMINWIDTH ), Millimeter2iu( 0.01 ), Millimeter2iu( 25.0 ),
  405. nullptr, MM_PER_IU ) );
  406. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "MinViaDiameter" ),
  407. &m_ViasMinSize,
  408. Millimeter2iu( DEFAULT_VIASMINSIZE ), Millimeter2iu( 0.01 ), Millimeter2iu( 25.0 ),
  409. nullptr, MM_PER_IU ) );
  410. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "MinViaDrill" ),
  411. &m_ViasMinDrill,
  412. Millimeter2iu( DEFAULT_VIASMINDRILL ), Millimeter2iu( 0.01 ), Millimeter2iu( 25.0 ),
  413. nullptr, MM_PER_IU ) );
  414. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "MinMicroViaDiameter" ),
  415. &m_MicroViasMinSize,
  416. Millimeter2iu( DEFAULT_MICROVIASMINSIZE ), Millimeter2iu( 0.01 ), Millimeter2iu( 10.0 ),
  417. nullptr, MM_PER_IU ) );
  418. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "MinMicroViaDrill" ),
  419. &m_MicroViasMinDrill,
  420. Millimeter2iu( DEFAULT_MICROVIASMINDRILL ), Millimeter2iu( 0.01 ), Millimeter2iu( 10.0 ),
  421. nullptr, MM_PER_IU ) );
  422. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "MinHoleToHole" ),
  423. &m_HoleToHoleMin,
  424. Millimeter2iu( DEFAULT_HOLETOHOLEMIN ), 0, Millimeter2iu( 10.0 ),
  425. nullptr, MM_PER_IU ) );
  426. aResult->push_back( new PARAM_CFG_TRACKWIDTHS( &m_TrackWidthList ) );
  427. aResult->push_back( new PARAM_CFG_VIADIMENSIONS( &m_ViasDimensionsList ) );
  428. aResult->push_back( new PARAM_CFG_DIFFPAIRDIMENSIONS( &m_DiffPairDimensionsList ) );
  429. aResult->push_back( new PARAM_CFG_NETCLASSES( wxT( "Netclasses" ), &m_NetClasses ) );
  430. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SilkLineWidth" ),
  431. &m_LineThickness[ LAYER_CLASS_SILK ],
  432. Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  433. nullptr, MM_PER_IU, wxT( "ModuleOutlineThickness" ) ) );
  434. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SilkTextSizeV" ),
  435. &m_TextSize[ LAYER_CLASS_SILK ].y,
  436. Millimeter2iu( DEFAULT_SILK_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  437. nullptr, MM_PER_IU, wxT( "ModuleTextSizeV" ) ) );
  438. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SilkTextSizeH" ),
  439. &m_TextSize[ LAYER_CLASS_SILK ].x,
  440. Millimeter2iu( DEFAULT_SILK_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  441. nullptr, MM_PER_IU, wxT( "ModuleTextSizeH" ) ) );
  442. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SilkTextSizeThickness" ),
  443. &m_TextThickness[ LAYER_CLASS_SILK ],
  444. Millimeter2iu( DEFAULT_SILK_TEXT_WIDTH ), 1, TEXTS_MAX_WIDTH,
  445. nullptr, MM_PER_IU, wxT( "ModuleTextSizeThickness" ) ) );
  446. aResult->push_back( new PARAM_CFG_BOOL( wxT( "SilkTextItalic" ),
  447. &m_TextItalic[ LAYER_CLASS_SILK ], false ) );
  448. aResult->push_back( new PARAM_CFG_BOOL( wxT( "SilkTextUpright" ),
  449. &m_TextUpright[ LAYER_CLASS_SILK ], true ) );
  450. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "CopperLineWidth" ),
  451. &m_LineThickness[ LAYER_CLASS_COPPER ],
  452. Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  453. nullptr, MM_PER_IU, wxT( "DrawSegmentWidth" ) ) );
  454. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "CopperTextSizeV" ),
  455. &m_TextSize[ LAYER_CLASS_COPPER ].y,
  456. Millimeter2iu( DEFAULT_COPPER_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  457. nullptr, MM_PER_IU, wxT( "PcbTextSizeV" ) ) );
  458. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "CopperTextSizeH" ),
  459. &m_TextSize[ LAYER_CLASS_COPPER ].x,
  460. Millimeter2iu( DEFAULT_COPPER_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  461. nullptr, MM_PER_IU, wxT( "PcbTextSizeH" ) ) );
  462. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "CopperTextThickness" ),
  463. &m_TextThickness[ LAYER_CLASS_COPPER ],
  464. Millimeter2iu( DEFAULT_COPPER_TEXT_WIDTH ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  465. nullptr, MM_PER_IU, wxT( "PcbTextThickness" ) ) );
  466. aResult->push_back( new PARAM_CFG_BOOL( wxT( "CopperTextItalic" ),
  467. &m_TextItalic[ LAYER_CLASS_COPPER ], false ) );
  468. aResult->push_back( new PARAM_CFG_BOOL( wxT( "CopperTextUpright" ),
  469. &m_TextUpright[ LAYER_CLASS_COPPER ], true ) );
  470. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "EdgeCutLineWidth" ),
  471. &m_LineThickness[ LAYER_CLASS_EDGES ],
  472. Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  473. nullptr, MM_PER_IU, wxT( "BoardOutlineThickness" ) ) );
  474. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "CourtyardLineWidth" ),
  475. &m_LineThickness[ LAYER_CLASS_COURTYARD ],
  476. Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  477. nullptr, MM_PER_IU ) );
  478. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "OthersLineWidth" ),
  479. &m_LineThickness[ LAYER_CLASS_OTHERS ],
  480. Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ), Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
  481. nullptr, MM_PER_IU, wxT( "ModuleOutlineThickness" ) ) );
  482. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "OthersTextSizeV" ),
  483. &m_TextSize[ LAYER_CLASS_OTHERS ].x,
  484. Millimeter2iu( DEFAULT_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  485. nullptr, MM_PER_IU ) );
  486. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "OthersTextSizeH" ),
  487. &m_TextSize[ LAYER_CLASS_OTHERS ].y,
  488. Millimeter2iu( DEFAULT_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
  489. nullptr, MM_PER_IU ) );
  490. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "OthersTextSizeThickness" ),
  491. &m_TextThickness[ LAYER_CLASS_OTHERS ],
  492. Millimeter2iu( DEFAULT_TEXT_WIDTH ), 1, TEXTS_MAX_WIDTH,
  493. nullptr, MM_PER_IU ) );
  494. aResult->push_back( new PARAM_CFG_BOOL( wxT( "OthersTextItalic" ),
  495. &m_TextItalic[ LAYER_CLASS_OTHERS ], false ) );
  496. aResult->push_back( new PARAM_CFG_BOOL( wxT( "OthersTextUpright" ),
  497. &m_TextUpright[ LAYER_CLASS_OTHERS ], true ) );
  498. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SolderMaskClearance" ),
  499. &m_SolderMaskMargin,
  500. Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE ), Millimeter2iu( -1.0 ), Millimeter2iu( 1.0 ),
  501. nullptr, MM_PER_IU ) );
  502. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SolderMaskMinWidth" ),
  503. &m_SolderMaskMinWidth,
  504. Millimeter2iu( DEFAULT_SOLDERMASK_MIN_WIDTH ), 0, Millimeter2iu( 1.0 ),
  505. nullptr, MM_PER_IU ) );
  506. aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SolderPasteClearance" ),
  507. &m_SolderPasteMargin,
  508. Millimeter2iu( DEFAULT_SOLDERPASTE_CLEARANCE ), Millimeter2iu( -1.0 ), Millimeter2iu( 1.0 ),
  509. nullptr, MM_PER_IU ) );
  510. aResult->push_back( new PARAM_CFG_DOUBLE( wxT( "SolderPasteRatio" ),
  511. &m_SolderPasteMarginRatio,
  512. DEFAULT_SOLDERPASTE_RATIO, 0, 10.0 ) );
  513. }
  514. bool BOARD_DESIGN_SETTINGS::SetCurrentNetClass( const wxString& aNetClassName )
  515. {
  516. NETCLASSPTR netClass = m_NetClasses.Find( aNetClassName );
  517. bool lists_sizes_modified = false;
  518. // if not found (should not happen) use the default
  519. if( !netClass )
  520. netClass = m_NetClasses.GetDefault();
  521. m_currentNetClassName = netClass->GetName();
  522. // Initialize others values:
  523. if( m_TrackWidthList.size() == 0 )
  524. {
  525. lists_sizes_modified = true;
  526. m_TrackWidthList.push_back( 0 );
  527. }
  528. if( m_ViasDimensionsList.size() == 0 )
  529. {
  530. lists_sizes_modified = true;
  531. m_ViasDimensionsList.emplace_back( VIA_DIMENSION() );
  532. }
  533. if( m_DiffPairDimensionsList.size() == 0 )
  534. {
  535. lists_sizes_modified = true;
  536. m_DiffPairDimensionsList.emplace_back( DIFF_PAIR_DIMENSION() );
  537. }
  538. /* note the m_ViasDimensionsList[0] and m_TrackWidthList[0] values
  539. * are always the Netclass values
  540. */
  541. if( m_TrackWidthList[0] != netClass->GetTrackWidth() )
  542. {
  543. lists_sizes_modified = true;
  544. m_TrackWidthList[0] = netClass->GetTrackWidth();
  545. }
  546. if( m_ViasDimensionsList[0].m_Diameter != netClass->GetViaDiameter() )
  547. {
  548. lists_sizes_modified = true;
  549. m_ViasDimensionsList[0].m_Diameter = netClass->GetViaDiameter();
  550. }
  551. if( m_ViasDimensionsList[0].m_Drill != netClass->GetViaDrill() )
  552. {
  553. lists_sizes_modified = true;
  554. m_ViasDimensionsList[0].m_Drill = netClass->GetViaDrill();
  555. }
  556. if( m_DiffPairDimensionsList[0].m_Width != netClass->GetDiffPairWidth() )
  557. {
  558. lists_sizes_modified = true;
  559. m_DiffPairDimensionsList[0].m_Width = netClass->GetDiffPairWidth();
  560. }
  561. if( m_DiffPairDimensionsList[0].m_Gap != netClass->GetDiffPairGap() )
  562. {
  563. lists_sizes_modified = true;
  564. m_DiffPairDimensionsList[0].m_Gap = netClass->GetDiffPairGap();
  565. }
  566. if( m_DiffPairDimensionsList[0].m_ViaGap != netClass->GetDiffPairViaGap() )
  567. {
  568. lists_sizes_modified = true;
  569. m_DiffPairDimensionsList[0].m_ViaGap = netClass->GetDiffPairViaGap();
  570. }
  571. if( GetViaSizeIndex() >= m_ViasDimensionsList.size() )
  572. SetViaSizeIndex( m_ViasDimensionsList.size() );
  573. if( GetTrackWidthIndex() >= m_TrackWidthList.size() )
  574. SetTrackWidthIndex( m_TrackWidthList.size() );
  575. if( GetDiffPairIndex() >= m_DiffPairDimensionsList.size() )
  576. SetDiffPairIndex( m_DiffPairDimensionsList.size() );
  577. return lists_sizes_modified;
  578. }
  579. int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue()
  580. {
  581. int clearance = m_NetClasses.GetDefault()->GetClearance();
  582. //Read list of Net Classes
  583. for( NETCLASSES::const_iterator nc = m_NetClasses.begin(); nc != m_NetClasses.end(); ++nc )
  584. {
  585. NETCLASSPTR netclass = nc->second;
  586. clearance = std::max( clearance, netclass->GetClearance() );
  587. }
  588. return clearance;
  589. }
  590. int BOARD_DESIGN_SETTINGS::GetSmallestClearanceValue()
  591. {
  592. int clearance = m_NetClasses.GetDefault()->GetClearance();
  593. //Read list of Net Classes
  594. for( NETCLASSES::const_iterator nc = m_NetClasses.begin(); nc != m_NetClasses.end(); ++nc )
  595. {
  596. NETCLASSPTR netclass = nc->second;
  597. clearance = std::min( clearance, netclass->GetClearance() );
  598. }
  599. return clearance;
  600. }
  601. int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaSize()
  602. {
  603. NETCLASSPTR netclass = m_NetClasses.Find( m_currentNetClassName );
  604. return netclass->GetuViaDiameter();
  605. }
  606. int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaDrill()
  607. {
  608. NETCLASSPTR netclass = m_NetClasses.Find( m_currentNetClassName );
  609. return netclass->GetuViaDrill();
  610. }
  611. void BOARD_DESIGN_SETTINGS::SetViaSizeIndex( unsigned aIndex )
  612. {
  613. m_viaSizeIndex = std::min( aIndex, (unsigned) m_ViasDimensionsList.size() );
  614. m_useCustomTrackVia = false;
  615. }
  616. int BOARD_DESIGN_SETTINGS::GetCurrentViaDrill() const
  617. {
  618. int drill;
  619. if( m_useCustomTrackVia )
  620. drill = m_customViaSize.m_Drill;
  621. else
  622. drill = m_ViasDimensionsList[m_viaSizeIndex].m_Drill;
  623. return drill > 0 ? drill : -1;
  624. }
  625. void BOARD_DESIGN_SETTINGS::SetTrackWidthIndex( unsigned aIndex )
  626. {
  627. m_trackWidthIndex = std::min( aIndex, (unsigned) m_TrackWidthList.size() );
  628. m_useCustomTrackVia = false;
  629. }
  630. void BOARD_DESIGN_SETTINGS::SetDiffPairIndex( unsigned aIndex )
  631. {
  632. m_diffPairIndex = std::min( aIndex, (unsigned) 8 );
  633. m_useCustomDiffPair = false;
  634. }
  635. void BOARD_DESIGN_SETTINGS::SetMinHoleSeparation( int aDistance )
  636. {
  637. m_HoleToHoleMin = aDistance;
  638. }
  639. void BOARD_DESIGN_SETTINGS::SetRequireCourtyardDefinitions( bool aRequire )
  640. {
  641. m_RequireCourtyards = aRequire;
  642. }
  643. void BOARD_DESIGN_SETTINGS::SetProhibitOverlappingCourtyards( bool aProhibit )
  644. {
  645. m_ProhibitOverlappingCourtyards = aProhibit;
  646. }
  647. void BOARD_DESIGN_SETTINGS::SetVisibleAlls()
  648. {
  649. SetVisibleLayers( LSET().set() );
  650. m_visibleElements = -1;
  651. }
  652. void BOARD_DESIGN_SETTINGS::SetLayerVisibility( PCB_LAYER_ID aLayer, bool aNewState )
  653. {
  654. m_visibleLayers.set( aLayer, aNewState && IsLayerEnabled( aLayer ));
  655. }
  656. void BOARD_DESIGN_SETTINGS::SetElementVisibility( GAL_LAYER_ID aElementCategory, bool aNewState )
  657. {
  658. if( aNewState )
  659. m_visibleElements |= 1 << GAL_LAYER_INDEX( aElementCategory );
  660. else
  661. m_visibleElements &= ~( 1 << GAL_LAYER_INDEX( aElementCategory ) );
  662. }
  663. void BOARD_DESIGN_SETTINGS::SetCopperLayerCount( int aNewLayerCount )
  664. {
  665. // if( aNewLayerCount < 2 ) aNewLayerCount = 2;
  666. m_copperLayerCount = aNewLayerCount;
  667. // ensure consistency with the m_EnabledLayers member
  668. #if 0
  669. // was:
  670. m_enabledLayers &= ~ALL_CU_LAYERS;
  671. m_enabledLayers |= LAYER_BACK;
  672. if( m_copperLayerCount > 1 )
  673. m_enabledLayers |= LAYER_FRONT;
  674. for( LAYER_NUM ii = LAYER_N_2; ii < aNewLayerCount - 1; ++ii )
  675. m_enabledLayers |= GetLayerSet( ii );
  676. #else
  677. // Update only enabled copper layers mask
  678. m_enabledLayers &= ~LSET::AllCuMask();
  679. m_enabledLayers |= LSET::AllCuMask( aNewLayerCount );
  680. #endif
  681. }
  682. void BOARD_DESIGN_SETTINGS::SetEnabledLayers( LSET aMask )
  683. {
  684. // Back and front layers are always enabled.
  685. aMask.set( B_Cu ).set( F_Cu );
  686. m_enabledLayers = aMask;
  687. // A disabled layer cannot be visible
  688. m_visibleLayers &= aMask;
  689. // update m_CopperLayerCount to ensure its consistency with m_EnabledLayers
  690. m_copperLayerCount = ( aMask & LSET::AllCuMask() ).count();
  691. }
  692. // Return the layer class index { silk, copper, edges & courtyards, others } of the
  693. // given layer.
  694. int BOARD_DESIGN_SETTINGS::GetLayerClass( PCB_LAYER_ID aLayer ) const
  695. {
  696. if( aLayer == F_SilkS || aLayer == B_SilkS )
  697. return 0;
  698. else if( IsCopperLayer( aLayer ) )
  699. return 1;
  700. else if( aLayer == Edge_Cuts || aLayer == F_CrtYd || aLayer == B_CrtYd )
  701. return 2;
  702. else
  703. return 3;
  704. }
  705. int BOARD_DESIGN_SETTINGS::GetLineThickness( PCB_LAYER_ID aLayer ) const
  706. {
  707. return m_LineThickness[ GetLayerClass( aLayer ) ];
  708. }
  709. wxSize BOARD_DESIGN_SETTINGS::GetTextSize( PCB_LAYER_ID aLayer ) const
  710. {
  711. return m_TextSize[ GetLayerClass( aLayer ) ];
  712. }
  713. int BOARD_DESIGN_SETTINGS::GetTextThickness( PCB_LAYER_ID aLayer ) const
  714. {
  715. return m_TextThickness[ GetLayerClass( aLayer ) ];
  716. }
  717. bool BOARD_DESIGN_SETTINGS::GetTextItalic( PCB_LAYER_ID aLayer ) const
  718. {
  719. return m_TextItalic[ GetLayerClass( aLayer ) ];
  720. }
  721. bool BOARD_DESIGN_SETTINGS::GetTextUpright( PCB_LAYER_ID aLayer ) const
  722. {
  723. return m_TextUpright[ GetLayerClass( aLayer ) ];
  724. }
  725. #ifndef NDEBUG
  726. struct list_size_check {
  727. list_size_check()
  728. {
  729. // Int (the type used for saving visibility settings) is only 32 bits guaranteed,
  730. // be sure that we do not cross the limit
  731. assert( GAL_LAYER_INDEX( GAL_LAYER_ID_BITMASK_END ) <= 32 );
  732. };
  733. };
  734. static list_size_check check;
  735. #endif