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.

308 lines
12 KiB

5 years ago
5 years ago
  1. #ifndef EAGLE_PLUGIN_H_
  2. #define EAGLE_PLUGIN_H_
  3. /*
  4. * This program source code file is part of KiCad, a free EDA CAD application.
  5. *
  6. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  7. * Copyright (C) 2012-2020 KiCad Developers, see AUTHORS.txt for contributors.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #include <io_mgr.h>
  27. #include <layers_id_colors_and_visibility.h>
  28. #include <plugins/eagle/eagle_parser.h>
  29. #include <plugins/common/plugin_common_layer_mapping.h>
  30. #include <map>
  31. #include <tuple>
  32. #include <wx/xml/xml.h>
  33. class PAD;
  34. class FP_TEXT;
  35. class ZONE;
  36. typedef std::map<wxString, FOOTPRINT*> FOOTPRINT_MAP;
  37. typedef std::vector<ZONE*> ZONES;
  38. typedef std::map<wxString, ENET> NET_MAP;
  39. typedef NET_MAP::const_iterator NET_MAP_CITER;
  40. /// subset of eagle.drawing.board.designrules in the XML document
  41. struct ERULES
  42. {
  43. ///< percent over 100%. 0-> not elongated, 100->twice as wide as is tall
  44. ///< Goes into making a scaling factor for "long" pads.
  45. int psElongationLong;
  46. int psElongationOffset; ///< the offset of the hole within the "long" pad.
  47. ///< solder mask, expressed as percentage of the smaller pad/via dimension
  48. double mvStopFrame;
  49. ///< solderpaste mask, expressed as percentage of the smaller pad/via dimension
  50. double mvCreamFrame;
  51. int mlMinStopFrame; ///< solder mask, minimum size (Eagle mils, here nanometers)
  52. int mlMaxStopFrame; ///< solder mask, maximum size (Eagle mils, here nanometers)
  53. int mlMinCreamFrame; ///< solder paste mask, minimum size (Eagle mils, here nanometers)
  54. int mlMaxCreamFrame; ///< solder paste mask, maximum size (Eagle mils, here nanometers)
  55. int psTop; ///< Shape of the top pads
  56. int psBottom; ///< Shape of the bottom pads
  57. int psFirst; ///< Shape of the first pads
  58. double srRoundness; ///< corner rounding ratio for SMD pads (percentage)
  59. ///< corner rounding radius, minimum size (Eagle mils, here nanometers)
  60. int srMinRoundness;
  61. ///< corner rounding radius, maximum size (Eagle mils, here nanometers)
  62. int srMaxRoundness;
  63. double rvPadTop; ///< top pad size as percent of drill size
  64. // double rvPadBottom; ///< bottom pad size as percent of drill size
  65. double rlMinPadTop; ///< minimum copper annulus on through hole pads
  66. double rlMaxPadTop; ///< maximum copper annulus on through hole pads
  67. double rvViaOuter; ///< copper annulus is this percent of via hole
  68. double rlMinViaOuter; ///< minimum copper annulus on via
  69. double rlMaxViaOuter; ///< maximum copper annulus on via
  70. double mdWireWire; ///< wire to wire spacing I presume.
  71. ERULES() :
  72. psElongationLong ( 100 ),
  73. psElongationOffset ( 0 ),
  74. mvStopFrame ( 1.0 ),
  75. mvCreamFrame ( 0.0 ),
  76. mlMinStopFrame ( Mils2iu( 4.0 ) ),
  77. mlMaxStopFrame ( Mils2iu( 4.0 ) ),
  78. mlMinCreamFrame ( Mils2iu( 0.0 ) ),
  79. mlMaxCreamFrame ( Mils2iu( 0.0 ) ),
  80. psTop ( EPAD::UNDEF ),
  81. psBottom ( EPAD::UNDEF ),
  82. psFirst ( EPAD::UNDEF ),
  83. srRoundness ( 0.0 ),
  84. srMinRoundness ( Mils2iu( 0.0 ) ),
  85. srMaxRoundness ( Mils2iu( 0.0 ) ),
  86. rvPadTop ( 0.25 ),
  87. // rvPadBottom ( 0.25 ),
  88. rlMinPadTop ( Mils2iu( 10 ) ),
  89. rlMaxPadTop ( Mils2iu( 20 ) ),
  90. rvViaOuter ( 0.25 ),
  91. rlMinViaOuter ( Mils2iu( 10 ) ),
  92. rlMaxViaOuter ( Mils2iu( 20 ) ),
  93. mdWireWire ( 0 )
  94. {}
  95. void parse( wxXmlNode* aRules );
  96. };
  97. /**
  98. * Works with Eagle 6.x XML board files and footprints to implement the Pcbnew #PLUGIN API
  99. * or a portion of it.
  100. */
  101. class EAGLE_PLUGIN : public PLUGIN, public LAYER_REMAPPABLE_PLUGIN
  102. {
  103. public:
  104. const wxString PluginName() const override;
  105. BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
  106. const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr ) override;
  107. const wxString GetFileExtension() const override;
  108. void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath,
  109. bool aBestEfforts, const PROPERTIES* aProperties = nullptr) override;
  110. FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
  111. const PROPERTIES* aProperties = nullptr ) override;
  112. long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override
  113. {
  114. return getModificationTime( aLibraryPath ).GetValue().GetValue();
  115. }
  116. bool IsFootprintLibWritable( const wxString& aLibraryPath ) override
  117. {
  118. return false; // until someone writes others like FootprintSave(), etc.
  119. }
  120. void FootprintLibOptions( PROPERTIES* aProperties ) const override;
  121. typedef int BIU;
  122. EAGLE_PLUGIN();
  123. ~EAGLE_PLUGIN();
  124. /**
  125. * Return the automapped layers.
  126. *
  127. * The callback needs to have the context of the current board so it can
  128. * correctly determine copper layer mapping. Thus, it is not static and is
  129. * expected to be bind to an instance of EAGLE_PLUGIN.
  130. *
  131. * @param aInputLayerDescriptionVector
  132. * @return Auto-mapped layers
  133. */
  134. std::map<wxString, PCB_LAYER_ID> DefaultLayerMappingCallback(
  135. const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector );
  136. private:
  137. typedef std::vector<ELAYER> ELAYERS;
  138. typedef ELAYERS::const_iterator EITER;
  139. int m_cu_map[17]; ///< map eagle to KiCad, cu layers only.
  140. std::map<int, ELAYER> m_eagleLayers; ///< Eagle layer data stored by layer number
  141. std::map<wxString, int> m_eagleLayersIds; ///< Eagle layer ids stored by layer name
  142. std::map<wxString, PCB_LAYER_ID> m_layer_map; ///< Map of Eagle layers to KiCad layers
  143. ERULES* m_rules; ///< Eagle design rules.
  144. XPATH* m_xpath; ///< keeps track of what we are working on within
  145. ///< XML document during a Load().
  146. int m_hole_count; ///< generates unique footprint names from eagle "hole"s.
  147. NET_MAP m_pads_to_nets; ///< net list
  148. FOOTPRINT_MAP m_templates; ///< is part of a FOOTPRINT factory that operates using copy
  149. ///< construction.
  150. ///< lookup key is either libname.packagename or simply
  151. ///< packagename if FootprintLoad() or FootprintEnumberate()
  152. const PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
  153. BOARD* m_board; ///< which BOARD is being worked on, no ownership here
  154. int m_min_trace; ///< smallest trace we find on Load(), in BIU.
  155. int m_min_hole; ///< smallest diameter hole we find on Load(), in BIU.
  156. int m_min_via; ///< smallest via we find on Load(), in BIU.
  157. int m_min_annulus; ///< smallest via annulus we find on Load(), in BIU.
  158. wxString m_lib_path;
  159. wxDateTime m_mod_time;
  160. /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
  161. void init( const PROPERTIES* aProperties );
  162. void clear_cu_map();
  163. /// Convert an Eagle distance to a KiCad distance.
  164. int kicad_y( const ECOORD& y ) const { return -y.ToPcbUnits(); }
  165. int kicad_x( const ECOORD& x ) const { return x.ToPcbUnits(); }
  166. /// create a font size (fontz) from an eagle font size scalar and KiCad font thickness
  167. wxSize kicad_fontz( const ECOORD& d, int aTextThickness ) const;
  168. /// Generate mapping between Eagle na KiCAD layers
  169. void mapEagleLayersToKicad();
  170. /// Convert an Eagle layer to a KiCad layer.
  171. PCB_LAYER_ID kicad_layer( int aLayer ) const;
  172. /// Get default KiCAD layer corresponding to an Eagle layer of the board,
  173. /// a set of sensible layer mapping options and required flag
  174. std::tuple<PCB_LAYER_ID, LSET, bool> defaultKicadLayer( int aEagleLayer ) const;
  175. /// Get Eagle layer name by its number
  176. const wxString& eagle_layer_name( int aLayer ) const;
  177. /// Get Eagle layer number by its name
  178. int eagle_layer_id( const wxString& aLayerName ) const;
  179. /// This PLUGIN only caches one footprint library, this determines which one.
  180. void cacheLib( const wxString& aLibraryPath );
  181. /// get a file's or dir's modification time.
  182. static wxDateTime getModificationTime( const wxString& aPath );
  183. // all these loadXXX() throw IO_ERROR or ptree_error exceptions:
  184. void loadAllSections( wxXmlNode* aDocument );
  185. void loadDesignRules( wxXmlNode* aDesignRules );
  186. void loadLayerDefs( wxXmlNode* aLayers );
  187. void loadPlain( wxXmlNode* aPlain );
  188. void loadSignals( wxXmlNode* aSignals );
  189. /**
  190. * Load the Eagle "library" XML element, which can occur either under a "libraries"
  191. * element (if a *.brd file) or under a "drawing" element if a *.lbr file.
  192. *
  193. * @param aLib is the portion of the loaded XML document tree that is the "library"
  194. * element.
  195. * @param aLibName is a pointer to the library name or NULL. If NULL this means
  196. * we are loading a *.lbr not a *.brd file and the key used in m_templates
  197. * is to exclude the library name.
  198. */
  199. void loadLibrary( wxXmlNode* aLib, const wxString* aLibName );
  200. void loadLibraries( wxXmlNode* aLibs );
  201. void loadElements( wxXmlNode* aElements );
  202. /**
  203. * Load a copper or keepout polygon and adds it to the board.
  204. *
  205. * @return The loaded zone or nullptr if was not processed.
  206. */
  207. ZONE* loadPolygon( wxXmlNode* aPolyNode );
  208. void orientFootprintAndText( FOOTPRINT* aFootprint, const EELEMENT& e, const EATTR* aNameAttr,
  209. const EATTR* aValueAttr );
  210. void orientFPText( FOOTPRINT* aFootprint, const EELEMENT& e, FP_TEXT* aFPText,
  211. const EATTR* aAttr );
  212. /// move the BOARD into the center of the page
  213. void centerBoard();
  214. /**
  215. * Create a FOOTPRINT from an Eagle package.
  216. */
  217. FOOTPRINT* makeFootprint( wxXmlNode* aPackage, const wxString& aPkgName );
  218. void packageWire( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const;
  219. void packagePad( FOOTPRINT* aFootprint, wxXmlNode* aTree );
  220. void packageText( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const;
  221. void packageRectangle( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const;
  222. void packagePolygon( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const;
  223. void packageCircle( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const;
  224. /**
  225. * @param aFootprint The KiCad footprint to which to assign the hole.
  226. * @param aTree The Eagle XML node that is of type "hole".
  227. * @param aCenter If true, center the hole in the footprint and offset the footprint position.
  228. */
  229. void packageHole( FOOTPRINT* aFootprint, wxXmlNode* aTree, bool aCenter ) const;
  230. void packageSMD( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const;
  231. ///> Handles common pad properties
  232. void transferPad( const EPAD_COMMON& aEaglePad, PAD* aPad ) const;
  233. ///> Deletes the footprint templates list
  234. void deleteTemplates();
  235. };
  236. #endif // EAGLE_PLUGIN_H_