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.

353 lines
12 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2019 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. #include <advanced_config.h>
  24. #include <config_params.h>
  25. #include <settings/settings_manager.h>
  26. #include <wx/config.h>
  27. #include <wx/filename.h>
  28. #include <wx/log.h>
  29. /*
  30. * Flag to enable advanced config debugging
  31. *
  32. * Use "KICAD_ADVANCED_CONFIG" to enable.
  33. *
  34. * @ingroup trace_env_vars
  35. */
  36. static const wxChar AdvancedConfigMask[] = wxT( "KICAD_ADVANCED_CONFIG" );
  37. /**
  38. * Limits and default settings for the coroutine stack size allowed.
  39. * Warning! Setting the stack size below the default may lead to unexplained crashes
  40. * This configuration setting is intended for developers only.
  41. */
  42. namespace AC_STACK
  43. {
  44. static constexpr int min_stack = 32 * 4096;
  45. static constexpr int default_stack = 256 * 4096;
  46. static constexpr int max_stack = 4096 * 4096;
  47. }
  48. /**
  49. * List of known keys for advanced configuration options.
  50. *
  51. * Set these options in the file `kicad_advanced` in the
  52. * KiCad config directory.
  53. */
  54. namespace AC_KEYS
  55. {
  56. /**
  57. * When filling zones, we add an extra amount of clearance to each zone to ensure that rounding
  58. * errors do not overrun minimum clearance distances. This is the extra in mm.
  59. */
  60. static const wxChar ExtraFillMargin[] = wxT( "ExtraFillMargin" );
  61. /**
  62. * A fudge factor for DRC. Required to prevent false positives due to rounding errors, errors
  63. * in polygonalization, etc.
  64. * Previous versions hard-coded various values from 0.000005mm to 0.002mm.
  65. */
  66. static const wxChar DRCEpsilon[] = wxT( "DRCEpsilon" );
  67. /**
  68. * Used to calculate the actual hole size from the finish hole size.
  69. * IPC-6012 says 0.015-0.018mm; Cadence says at least 0.020mm for a Class 2 board and at least
  70. * 0.025mm for Class 3.
  71. */
  72. static const wxChar HoleWallThickness[] = wxT( "HoleWallPlatingThickness" );
  73. /**
  74. * Testing mode for new connectivity algorithm. Setting this to on will cause all modifications
  75. * to the netlist to be recalculated on the fly. This may be slower than the standard process
  76. * at the moment
  77. */
  78. static const wxChar RealtimeConnectivity[] = wxT( "RealtimeConnectivity" );
  79. /**
  80. * Configure the coroutine stack size in bytes. This should be allocated in multiples of
  81. * the system page size (n*4096 is generally safe)
  82. */
  83. static const wxChar CoroutineStackSize[] = wxT( "CoroutineStackSize" );
  84. /**
  85. * Show PNS router debug graphics while routing
  86. */
  87. static const wxChar ShowRouterDebugGraphics[] = wxT( "ShowRouterDebugGraphics" );
  88. /**
  89. * When set to true, this will wrap polygon point sets at 4 points per line rather
  90. * than a single point per line. Single point per line helps with version control systems
  91. */
  92. static const wxChar CompactFileSave[] = wxT( "CompactSave" );
  93. /**
  94. * For drawsegments - arcs.
  95. * Distance from an arc end point and the estimated end point,
  96. * when rotating from the start point to the end point.
  97. * 0 will not allow any approximate result, and the arc will not show.
  98. * Squared value for performances, in system unit.
  99. */
  100. static const wxChar DrawArcAccuracy[] = wxT( "DrawArcAccuracy" );
  101. /**
  102. * For drawsegments - arcs.
  103. * When drawing an arc, the angle ( center - start ) - ( start - end ),
  104. * can be limited to avoid extremely high radii.
  105. * The value is the tan( angle )
  106. */
  107. static const wxChar DrawArcCenterStartEndMaxAngle[] = wxT( "DrawArcCenterStartEndMaxAngle" );
  108. /**
  109. * When true, GAL will stroke the triangulations (only used in OpenGL) with a visible color
  110. */
  111. static const wxChar StrokeTriangulation[] = wxT( "StrokeTriangulation" );
  112. /**
  113. * When true, enable Altium Schematic import (*.SchDoc)
  114. */
  115. static const wxChar PluginAltiumSch[] = wxT( "PluginAltiumSch" );
  116. /**
  117. * Absolute minimum pen width to send to the plotter. PDF seems happy enough with 0.0212mm
  118. * (which equates to 1px @ 1200dpi).
  119. */
  120. static const wxChar MinPlotPenWidth[] = wxT( "MinPlotPenWidth" );
  121. static const wxChar DebugZoneFiller[] = wxT( "DebugZoneFiller" );
  122. static const wxChar DebugPDFWriter[] = wxT( "DebugPDFWriter" );
  123. /**
  124. * The diameter of the drill marks on print and plot outputs (in mm),
  125. * when the "Drill marks" option is set to "Small mark"
  126. */
  127. static const wxChar SmallDrillMarkSize[] = wxT( "SmallDrillMarkSize" );
  128. static const wxChar HotkeysDumper[] = wxT( "HotkeysDumper" );
  129. static const wxChar DrawBoundingBoxes[] = wxT( "DrawBoundingBoxes" );
  130. } // namespace KEYS
  131. /*
  132. * Get a simple string for common parameters.
  133. *
  134. * This isn't exhaustive, but it covers most common types that might be
  135. * used in the advance config
  136. */
  137. wxString dumpParamCfg( const PARAM_CFG& aParam )
  138. {
  139. wxString s = aParam.m_Ident + ": ";
  140. /*
  141. * This implementation is rather simplistic, but it is
  142. * effective enough for simple uses. A better implementation would be
  143. * some kind of visitor, but that's somewhat more work.
  144. */
  145. switch( aParam.m_Type )
  146. {
  147. case paramcfg_id::PARAM_INT:
  148. case paramcfg_id::PARAM_INT_WITH_SCALE:
  149. s << *static_cast<const PARAM_CFG_INT&>( aParam ).m_Pt_param;
  150. break;
  151. case paramcfg_id::PARAM_DOUBLE:
  152. s << *static_cast<const PARAM_CFG_DOUBLE&>( aParam ).m_Pt_param;
  153. break;
  154. case paramcfg_id::PARAM_WXSTRING:
  155. s << *static_cast<const PARAM_CFG_WXSTRING&>( aParam ).m_Pt_param;
  156. break;
  157. case paramcfg_id::PARAM_FILENAME:
  158. s << *static_cast<const PARAM_CFG_FILENAME&>( aParam ).m_Pt_param;
  159. break;
  160. case paramcfg_id::PARAM_BOOL:
  161. s << ( *static_cast<const PARAM_CFG_BOOL&>( aParam ).m_Pt_param ? "true" : "false" );
  162. break;
  163. default: s << "Unsupported PARAM_CFG variant: " << aParam.m_Type;
  164. }
  165. return s;
  166. }
  167. /**
  168. * Dump the configs in the given array to trace.
  169. */
  170. static void dumpCfg( const std::vector<PARAM_CFG*>& aArray )
  171. {
  172. // only dump if we need to
  173. if( !wxLog::IsAllowedTraceMask( AdvancedConfigMask ) )
  174. return;
  175. for( const PARAM_CFG* param : aArray )
  176. {
  177. wxLogTrace( AdvancedConfigMask, dumpParamCfg( *param ) );
  178. }
  179. }
  180. /**
  181. * Get the filename for the advanced config file
  182. *
  183. * The user must check the file exists if they care.
  184. */
  185. static wxFileName getAdvancedCfgFilename()
  186. {
  187. const static wxString cfg_filename{ "kicad_advanced" };
  188. return wxFileName( SETTINGS_MANAGER::GetUserSettingsPath(), cfg_filename );
  189. }
  190. ADVANCED_CFG::ADVANCED_CFG()
  191. {
  192. wxLogTrace( AdvancedConfigMask, "Init advanced config" );
  193. // Init defaults - this is done in case the config doesn't exist,
  194. // then the values will remain as set here.
  195. m_RealTimeConnectivity = true;
  196. m_CoroutineStackSize = AC_STACK::default_stack;
  197. m_ShowRouterDebugGraphics = false;
  198. m_DrawArcAccuracy = 10.0;
  199. m_DrawArcCenterMaxAngle = 50.0;
  200. m_DrawTriangulationOutlines = false;
  201. m_PluginAltiumSch = false;
  202. m_ExtraClearance = 0.0001;
  203. m_DRCEpsilon = 0.0001; // 0.1um is small enough not to materially violate
  204. // any constraints.
  205. m_HoleWallThickness = 0.020; // IPC-6012 says 15-18um; Cadence says at least
  206. // 0.020 for a Class 2 board and at least 0.025
  207. // for Class 3.
  208. m_MinPlotPenWidth = 0.0212; // 1 pixel at 1200dpi.
  209. m_DebugZoneFiller = false;
  210. m_DebugPDFWriter = false;
  211. m_SmallDrillMarkSize = 0.35;
  212. m_HotkeysDumper = false;
  213. m_DrawBoundingBoxes = false;
  214. loadFromConfigFile();
  215. }
  216. const ADVANCED_CFG& ADVANCED_CFG::GetCfg()
  217. {
  218. static ADVANCED_CFG instance;
  219. return instance;
  220. }
  221. void ADVANCED_CFG::loadFromConfigFile()
  222. {
  223. const wxFileName k_advanced = getAdvancedCfgFilename();
  224. if( !k_advanced.FileExists() )
  225. {
  226. wxLogTrace( AdvancedConfigMask, "File does not exist %s", k_advanced.GetFullPath() );
  227. // load the defaults
  228. wxConfig emptyConfig;
  229. loadSettings( emptyConfig );
  230. return;
  231. }
  232. wxLogTrace( AdvancedConfigMask, "Loading advanced config from: %s", k_advanced.GetFullPath() );
  233. wxFileConfig file_cfg( "", "", k_advanced.GetFullPath() );
  234. loadSettings( file_cfg );
  235. }
  236. void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
  237. {
  238. std::vector<PARAM_CFG*> configParams;
  239. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::RealtimeConnectivity,
  240. &m_RealTimeConnectivity, true ) );
  241. configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::ExtraFillMargin,
  242. &m_ExtraClearance, 0.0005, 0.0, 1.0 ) );
  243. configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::DRCEpsilon,
  244. &m_DRCEpsilon, 0.0005, 0.0, 1.0 ) );
  245. configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::HoleWallThickness,
  246. &m_HoleWallThickness, 0.020, 0.0, 1.0 ) );
  247. configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::CoroutineStackSize,
  248. &m_CoroutineStackSize, AC_STACK::default_stack,
  249. AC_STACK::min_stack, AC_STACK::max_stack ) );
  250. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::ShowRouterDebugGraphics,
  251. &m_ShowRouterDebugGraphics, false ) );
  252. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::CompactFileSave,
  253. &m_CompactSave, false ) );
  254. configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::DrawArcAccuracy,
  255. &m_DrawArcAccuracy, 10.0, 0.0, 100000.0 ) );
  256. configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::DrawArcCenterStartEndMaxAngle,
  257. &m_DrawArcCenterMaxAngle, 50.0, 0.0, 100000.0 ) );
  258. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::StrokeTriangulation,
  259. &m_DrawTriangulationOutlines, false ) );
  260. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::PluginAltiumSch,
  261. &m_PluginAltiumSch, false ) );
  262. configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::MinPlotPenWidth,
  263. &m_MinPlotPenWidth, 0.0212, 0.0, 1.0 ) );
  264. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::DebugZoneFiller,
  265. &m_DebugZoneFiller, false ) );
  266. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::DebugPDFWriter,
  267. &m_DebugPDFWriter, false ) );
  268. configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::SmallDrillMarkSize,
  269. &m_SmallDrillMarkSize, 0.35, 0.0, 3.0 ) );
  270. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::HotkeysDumper,
  271. &m_HotkeysDumper, false ) );
  272. configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::DrawBoundingBoxes,
  273. &m_DrawBoundingBoxes, false ) );
  274. wxConfigLoadSetups( &aCfg, configParams );
  275. for( PARAM_CFG* param : configParams )
  276. delete param;
  277. dumpCfg( configParams );
  278. }