1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> 5 * Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.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 25 #ifndef EAGLE_PLUGIN_H 26 #define EAGLE_PLUGIN_H 27 28 #include <convert_to_biu.h> 29 #include <io_mgr.h> 30 #include <layer_ids.h> 31 #include <netclass.h> 32 #include <plugins/eagle/eagle_parser.h> 33 #include <plugins/common/plugin_common_layer_mapping.h> 34 35 #include <map> 36 #include <tuple> 37 #include <wx/xml/xml.h> 38 39 class PAD; 40 class FP_TEXT; 41 class ZONE; 42 43 typedef std::map<wxString, FOOTPRINT*> FOOTPRINT_MAP; 44 typedef std::vector<ZONE*> ZONES; 45 typedef std::map<wxString, ENET> NET_MAP; 46 typedef NET_MAP::const_iterator NET_MAP_CITER; 47 48 49 /// subset of eagle.drawing.board.designrules in the XML document 50 struct ERULES 51 { ERULESERULES52 ERULES() : 53 psElongationLong ( 100 ), 54 psElongationOffset ( 0 ), 55 56 mvStopFrame ( 1.0 ), 57 mvCreamFrame ( 0.0 ), 58 mlMinStopFrame ( Mils2iu( 4.0 ) ), 59 mlMaxStopFrame ( Mils2iu( 4.0 ) ), 60 mlMinCreamFrame ( Mils2iu( 0.0 ) ), 61 mlMaxCreamFrame ( Mils2iu( 0.0 ) ), 62 63 psTop ( EPAD::UNDEF ), 64 psBottom ( EPAD::UNDEF ), 65 psFirst ( EPAD::UNDEF ), 66 67 srRoundness ( 0.0 ), 68 srMinRoundness ( Mils2iu( 0.0 ) ), 69 srMaxRoundness ( Mils2iu( 0.0 ) ), 70 71 rvPadTop ( 0.25 ), 72 // rvPadBottom ( 0.25 ), 73 rlMinPadTop ( Mils2iu( 10 ) ), 74 rlMaxPadTop ( Mils2iu( 20 ) ), 75 76 rvViaOuter ( 0.25 ), 77 rlMinViaOuter ( Mils2iu( 10 ) ), 78 rlMaxViaOuter ( Mils2iu( 20 ) ), 79 mdWireWire ( 0 ) 80 {} 81 82 void parse( wxXmlNode* aRules, std::function<void()> aCheckpoint ); 83 84 ///< percent over 100%. 0-> not elongated, 100->twice as wide as is tall 85 ///< Goes into making a scaling factor for "long" pads. 86 int psElongationLong; 87 88 int psElongationOffset; ///< the offset of the hole within the "long" pad. 89 90 ///< solder mask, expressed as percentage of the smaller pad/via dimension 91 double mvStopFrame; 92 93 ///< solderpaste mask, expressed as percentage of the smaller pad/via dimension 94 double mvCreamFrame; 95 int mlMinStopFrame; ///< solder mask, minimum size (Eagle mils, here nanometers) 96 int mlMaxStopFrame; ///< solder mask, maximum size (Eagle mils, here nanometers) 97 int mlMinCreamFrame; ///< solder paste mask, minimum size (Eagle mils, here nanometers) 98 int mlMaxCreamFrame; ///< solder paste mask, maximum size (Eagle mils, here nanometers) 99 100 int psTop; ///< Shape of the top pads 101 int psBottom; ///< Shape of the bottom pads 102 int psFirst; ///< Shape of the first pads 103 104 double srRoundness; ///< corner rounding ratio for SMD pads (percentage) 105 106 ///< corner rounding radius, minimum size (Eagle mils, here nanometers) 107 int srMinRoundness; 108 109 ///< corner rounding radius, maximum size (Eagle mils, here nanometers) 110 int srMaxRoundness; 111 112 double rvPadTop; ///< top pad size as percent of drill size 113 // double rvPadBottom; ///< bottom pad size as percent of drill size 114 115 double rlMinPadTop; ///< minimum copper annulus on through hole pads 116 double rlMaxPadTop; ///< maximum copper annulus on through hole pads 117 118 double rvViaOuter; ///< copper annulus is this percent of via hole 119 double rlMinViaOuter; ///< minimum copper annulus on via 120 double rlMaxViaOuter; ///< maximum copper annulus on via 121 double mdWireWire; ///< wire to wire spacing I presume. 122 }; 123 124 125 /** 126 * Works with Eagle 6.x XML board files and footprints to implement the Pcbnew #PLUGIN API 127 * or a portion of it. 128 */ 129 class EAGLE_PLUGIN : public PLUGIN, public LAYER_REMAPPABLE_PLUGIN 130 { 131 public: 132 const wxString PluginName() const override; 133 134 BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, 135 const PROPERTIES* aProperties = nullptr, PROJECT* aProject = nullptr, 136 PROGRESS_REPORTER* aProgressReporter = nullptr ) override; 137 138 std::vector<FOOTPRINT*> GetImportedCachedLibraryFootprints() override; 139 140 const wxString GetFileExtension() const override; 141 142 void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, 143 bool aBestEfforts, const PROPERTIES* aProperties = nullptr) override; 144 145 FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, 146 bool aKeepUUID = false, 147 const PROPERTIES* aProperties = nullptr ) override; 148 GetLibraryTimestamp(const wxString & aLibraryPath)149 long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override 150 { 151 return getModificationTime( aLibraryPath ).GetValue().GetValue(); 152 } 153 IsFootprintLibWritable(const wxString & aLibraryPath)154 bool IsFootprintLibWritable( const wxString& aLibraryPath ) override 155 { 156 return false; // until someone writes others like FootprintSave(), etc. 157 } 158 159 void FootprintLibOptions( PROPERTIES* aProperties ) const override; 160 161 typedef int BIU; 162 163 EAGLE_PLUGIN(); 164 ~EAGLE_PLUGIN(); 165 166 /** 167 * Return the automapped layers. 168 * 169 * The callback needs to have the context of the current board so it can 170 * correctly determine copper layer mapping. Thus, it is not static and is 171 * expected to be bind to an instance of EAGLE_PLUGIN. 172 * 173 * @param aInputLayerDescriptionVector 174 * @return Auto-mapped layers 175 */ 176 std::map<wxString, PCB_LAYER_ID> DefaultLayerMappingCallback( 177 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector ); 178 179 private: 180 /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed. 181 void init( const PROPERTIES* aProperties ); 182 183 void checkpoint(); 184 185 void clear_cu_map(); 186 187 /// Convert an Eagle distance to a KiCad distance. kicad_y(const ECOORD & y)188 int kicad_y( const ECOORD& y ) const { return -y.ToPcbUnits(); } kicad_x(const ECOORD & x)189 int kicad_x( const ECOORD& x ) const { return x.ToPcbUnits(); } 190 191 /// create a font size (fontz) from an eagle font size scalar and KiCad font thickness 192 wxSize kicad_fontz( const ECOORD& d, int aTextThickness ) const; 193 194 /// Generate mapping between Eagle na KiCad layers 195 void mapEagleLayersToKicad(); 196 197 /// Convert an Eagle layer to a KiCad layer. 198 PCB_LAYER_ID kicad_layer( int aLayer ) const; 199 200 /// Get default KiCad layer corresponding to an Eagle layer of the board, 201 /// a set of sensible layer mapping options and required flag 202 std::tuple<PCB_LAYER_ID, LSET, bool> defaultKicadLayer( int aEagleLayer ) const; 203 204 /// Get Eagle layer name by its number 205 const wxString& eagle_layer_name( int aLayer ) const; 206 207 /// Get Eagle layer number by its name 208 int eagle_layer_id( const wxString& aLayerName ) const; 209 210 /// This PLUGIN only caches one footprint library, this determines which one. 211 void cacheLib( const wxString& aLibraryPath ); 212 213 /// get a file's or dir's modification time. 214 static wxDateTime getModificationTime( const wxString& aPath ); 215 216 // all these loadXXX() throw IO_ERROR or ptree_error exceptions: 217 218 void loadAllSections( wxXmlNode* aDocument ); 219 void loadDesignRules( wxXmlNode* aDesignRules ); 220 void loadLayerDefs( wxXmlNode* aLayers ); 221 void loadPlain( wxXmlNode* aPlain ); 222 void loadClasses( wxXmlNode* aClasses ); 223 void loadSignals( wxXmlNode* aSignals ); 224 225 /** 226 * Load the Eagle "library" XML element, which can occur either under a "libraries" 227 * element (if a *.brd file) or under a "drawing" element if a *.lbr file. 228 * 229 * @param aLib is the portion of the loaded XML document tree that is the "library" 230 * element. 231 * @param aLibName is a pointer to the library name or NULL. If NULL this means 232 * we are loading a *.lbr not a *.brd file and the key used in m_templates 233 * is to exclude the library name. 234 */ 235 void loadLibrary( wxXmlNode* aLib, const wxString* aLibName ); 236 237 void loadLibraries( wxXmlNode* aLibs ); 238 void loadElements( wxXmlNode* aElements ); 239 240 /** 241 * Load a copper or keepout polygon and adds it to the board. 242 * 243 * @return The loaded zone or nullptr if was not processed. 244 */ 245 ZONE* loadPolygon( wxXmlNode* aPolyNode ); 246 247 void orientFootprintAndText( FOOTPRINT* aFootprint, const EELEMENT& e, const EATTR* aNameAttr, 248 const EATTR* aValueAttr ); 249 250 void orientFPText( FOOTPRINT* aFootprint, const EELEMENT& e, FP_TEXT* aFPText, 251 const EATTR* aAttr ); 252 253 254 /// move the BOARD into the center of the page 255 void centerBoard(); 256 257 /** 258 * Create a FOOTPRINT from an Eagle package. 259 */ 260 FOOTPRINT* makeFootprint( wxXmlNode* aPackage, const wxString& aPkgName ); 261 262 void packageWire( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const; 263 void packagePad( FOOTPRINT* aFootprint, wxXmlNode* aTree ); 264 void packageText( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const; 265 void packageRectangle( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const; 266 void packagePolygon( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const; 267 void packageCircle( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const; 268 269 /** 270 * @param aFootprint The KiCad footprint to which to assign the hole. 271 * @param aTree The Eagle XML node that is of type "hole". 272 * @param aCenter If true, center the hole in the footprint and offset the footprint position. 273 */ 274 void packageHole( FOOTPRINT* aFootprint, wxXmlNode* aTree, bool aCenter ) const; 275 void packageSMD( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const; 276 277 ///< Handles common pad properties 278 void transferPad( const EPAD_COMMON& aEaglePad, PAD* aPad ) const; 279 280 ///< Deletes the footprint templates list 281 void deleteTemplates(); 282 283 typedef std::vector<ELAYER> ELAYERS; 284 typedef ELAYERS::const_iterator EITER; 285 286 int m_cu_map[17]; ///< map eagle to KiCad, cu layers only. 287 std::map<int, ELAYER> m_eagleLayers; ///< Eagle layer data stored by layer number 288 std::map<wxString, int> m_eagleLayersIds; ///< Eagle layer ids stored by layer name 289 std::map<wxString, PCB_LAYER_ID> m_layer_map; ///< Map of Eagle layers to KiCad layers 290 291 std::map<wxString, NETCLASSPTR> m_classMap; ///< Eagle class number to KiCad netclass 292 wxString m_customRules; 293 294 ERULES* m_rules; ///< Eagle design rules. 295 XPATH* m_xpath; ///< keeps track of what we are working on within 296 ///< XML document during a Load(). 297 298 int m_hole_count; ///< generates unique footprint names from eagle "hole"s. 299 300 NET_MAP m_pads_to_nets; ///< net list 301 302 FOOTPRINT_MAP m_templates; ///< is part of a FOOTPRINT factory that operates using copy 303 ///< construction. 304 ///< lookup key is either libname.packagename or simply 305 ///< packagename if FootprintLoad() or FootprintEnumberate() 306 307 const PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL. 308 BOARD* m_board; ///< which BOARD is being worked on, no ownership here 309 310 PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr 311 unsigned m_doneCount; 312 unsigned m_lastProgressCount; 313 unsigned m_totalCount; ///< for progress reporting 314 315 int m_min_trace; ///< smallest trace we find on Load(), in BIU. 316 int m_min_hole; ///< smallest diameter hole we find on Load(), in BIU. 317 int m_min_via; ///< smallest via we find on Load(), in BIU. 318 int m_min_annulus; ///< smallest via annulus we find on Load(), in BIU. 319 320 wxString m_lib_path; 321 wxDateTime m_mod_time; 322 }; 323 324 #endif // EAGLE_PLUGIN_H 325