KiCad PCB EDA Suite
EAGLE_PLUGIN Class Reference

Works with Eagle 6.x XML board files and footprints to implement the Pcbnew PLUGIN API or a portion of it. More...

#include <eagle_plugin.h>

Inheritance diagram for EAGLE_PLUGIN:
PLUGIN LAYER_REMAPPABLE_PLUGIN

Public Types

typedef int BIU
 

Public Member Functions

const wxString PluginName () const override
 Return a brief hard coded name for this PLUGIN. More...
 
BOARDLoad (const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr) override
 Load information from some input file format that this PLUGIN implementation knows about into either a new BOARD or an existing one. More...
 
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints () override
 Return a container with the cached library footprints generated in the last call to Load. More...
 
const wxString GetFileExtension () const override
 Returns the file extension for the PLUGIN. More...
 
void FootprintEnumerate (wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const PROPERTIES *aProperties=nullptr) override
 Return a list of footprint names contained within the library at aLibraryPath. More...
 
FOOTPRINTFootprintLoad (const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const PROPERTIES *aProperties=nullptr) override
 Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PLUGIN knows about. More...
 
long long GetLibraryTimestamp (const wxString &aLibraryPath) const override
 Generate a timestamp representing all the files in the library (including the library directory). More...
 
bool IsFootprintLibWritable (const wxString &aLibraryPath) override
 Return true if the library at aLibraryPath is writable. More...
 
void FootprintLibOptions (PROPERTIES *aProperties) const override
 Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions. More...
 
 EAGLE_PLUGIN ()
 
 ~EAGLE_PLUGIN ()
 
std::map< wxString, PCB_LAYER_IDDefaultLayerMappingCallback (const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
 Return the automapped layers. More...
 
virtual void Save (const wxString &aFileName, BOARD *aBoard, const PROPERTIES *aProperties=nullptr)
 Write aBoard to a storage file in a format that this PLUGIN implementation knows about or it can be used to write a portion of aBoard to a special kind of export file. More...
 
virtual void PrefetchLib (const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr)
 If possible, prefetches the specified library (e.g. More...
 
virtual const FOOTPRINTGetEnumeratedFootprint (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=nullptr)
 A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management. More...
 
virtual bool FootprintExists (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=nullptr)
 Check for the existence of a footprint. More...
 
virtual void FootprintSave (const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const PROPERTIES *aProperties=nullptr)
 Write aFootprint to an existing library located at aLibraryPath. More...
 
virtual void FootprintDelete (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=nullptr)
 Delete aFootprintName from the library at aLibraryPath. More...
 
virtual void FootprintLibCreate (const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr)
 Create a new empty footprint library at aLibraryPath empty. More...
 
virtual bool FootprintLibDelete (const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr)
 Delete an existing footprint library and returns true, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason. More...
 
virtual void RegisterLayerMappingCallback (LAYER_MAPPING_HANDLER aLayerMappingHandler)
 Register a different handler to be called when mapping of input layers to KiCad layers occurs. More...
 

Protected Attributes

LAYER_MAPPING_HANDLER m_layer_mapping_handler
 Callback to get layer mapping. More...
 

Private Types

typedef std::vector< ELAYERELAYERS
 
typedef ELAYERS::const_iterator EITER
 

Private Member Functions

void init (const PROPERTIES *aProperties)
 initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed. More...
 
void checkpoint ()
 
void clear_cu_map ()
 
int kicad_y (const ECOORD &y) const
 Convert an Eagle distance to a KiCad distance. More...
 
int kicad_x (const ECOORD &x) const
 
wxSize kicad_fontz (const ECOORD &d, int aTextThickness) const
 create a font size (fontz) from an eagle font size scalar and KiCad font thickness More...
 
void mapEagleLayersToKicad ()
 Generate mapping between Eagle na KiCad layers. More...
 
PCB_LAYER_ID kicad_layer (int aLayer) const
 Convert an Eagle layer to a KiCad layer. More...
 
std::tuple< PCB_LAYER_ID, LSET, bool > defaultKicadLayer (int aEagleLayer) const
 Get default KiCad layer corresponding to an Eagle layer of the board, a set of sensible layer mapping options and required flag. More...
 
const wxString & eagle_layer_name (int aLayer) const
 Get Eagle layer name by its number. More...
 
int eagle_layer_id (const wxString &aLayerName) const
 Get Eagle layer number by its name. More...
 
void cacheLib (const wxString &aLibraryPath)
 This PLUGIN only caches one footprint library, this determines which one. More...
 
void loadAllSections (wxXmlNode *aDocument)
 
void loadDesignRules (wxXmlNode *aDesignRules)
 
void loadLayerDefs (wxXmlNode *aLayers)
 
void loadPlain (wxXmlNode *aPlain)
 
void loadClasses (wxXmlNode *aClasses)
 
void loadSignals (wxXmlNode *aSignals)
 
void loadLibrary (wxXmlNode *aLib, const wxString *aLibName)
 Load the Eagle "library" XML element, which can occur either under a "libraries" element (if a *.brd file) or under a "drawing" element if a *.lbr file. More...
 
void loadLibraries (wxXmlNode *aLibs)
 
void loadElements (wxXmlNode *aElements)
 
ZONEloadPolygon (wxXmlNode *aPolyNode)
 Load a copper or keepout polygon and adds it to the board. More...
 
void orientFootprintAndText (FOOTPRINT *aFootprint, const EELEMENT &e, const EATTR *aNameAttr, const EATTR *aValueAttr)
 
void orientFPText (FOOTPRINT *aFootprint, const EELEMENT &e, FP_TEXT *aFPText, const EATTR *aAttr)
 
void centerBoard ()
 move the BOARD into the center of the page More...
 
FOOTPRINTmakeFootprint (wxXmlNode *aPackage, const wxString &aPkgName)
 Create a FOOTPRINT from an Eagle package. More...
 
void packageWire (FOOTPRINT *aFootprint, wxXmlNode *aTree) const
 
void packagePad (FOOTPRINT *aFootprint, wxXmlNode *aTree)
 
void packageText (FOOTPRINT *aFootprint, wxXmlNode *aTree) const
 
void packageRectangle (FOOTPRINT *aFootprint, wxXmlNode *aTree) const
 
void packagePolygon (FOOTPRINT *aFootprint, wxXmlNode *aTree) const
 
void packageCircle (FOOTPRINT *aFootprint, wxXmlNode *aTree) const
 
void packageHole (FOOTPRINT *aFootprint, wxXmlNode *aTree, bool aCenter) const
 
void packageSMD (FOOTPRINT *aFootprint, wxXmlNode *aTree) const
 Handles common pad properties. More...
 
void transferPad (const EPAD_COMMON &aEaglePad, PAD *aPad) const
 Deletes the footprint templates list. More...
 
void deleteTemplates ()
 

Static Private Member Functions

static wxDateTime getModificationTime (const wxString &aPath)
 get a file's or dir's modification time. More...
 

Private Attributes

int m_cu_map [17]
 map eagle to KiCad, cu layers only. More...
 
std::map< int, ELAYERm_eagleLayers
 Eagle layer data stored by layer number. More...
 
std::map< wxString, int > m_eagleLayersIds
 Eagle layer ids stored by layer name. More...
 
std::map< wxString, PCB_LAYER_IDm_layer_map
 Map of Eagle layers to KiCad layers. More...
 
std::map< wxString, NETCLASSPTR > m_classMap
 Eagle class number to KiCad netclass. More...
 
wxString m_customRules
 
ERULESm_rules
 Eagle design rules. More...
 
XPATHm_xpath
 keeps track of what we are working on within XML document during a Load(). More...
 
int m_hole_count
 generates unique footprint names from eagle "hole"s. More...
 
NET_MAP m_pads_to_nets
 net list More...
 
FOOTPRINT_MAP m_templates
 is part of a FOOTPRINT factory that operates using copy construction. More...
 
const PROPERTIESm_props
 passed via Save() or Load(), no ownership, may be NULL. More...
 
BOARDm_board
 which BOARD is being worked on, no ownership here More...
 
PROGRESS_REPORTERm_progressReporter
 optional; may be nullptr More...
 
unsigned m_doneCount
 
unsigned m_lastProgressCount
 
unsigned m_totalCount
 for progress reporting More...
 
int m_min_trace
 smallest trace we find on Load(), in BIU. More...
 
int m_min_hole
 smallest diameter hole we find on Load(), in BIU. More...
 
int m_min_via
 smallest via we find on Load(), in BIU. More...
 
int m_min_annulus
 smallest via annulus we find on Load(), in BIU. More...
 
wxString m_lib_path
 
wxDateTime m_mod_time
 

Detailed Description

Works with Eagle 6.x XML board files and footprints to implement the Pcbnew PLUGIN API or a portion of it.

Definition at line 129 of file eagle_plugin.h.

Member Typedef Documentation

◆ BIU

typedef int EAGLE_PLUGIN::BIU

Definition at line 161 of file eagle_plugin.h.

◆ EITER

typedef ELAYERS::const_iterator EAGLE_PLUGIN::EITER
private

Definition at line 284 of file eagle_plugin.h.

◆ ELAYERS

typedef std::vector<ELAYER> EAGLE_PLUGIN::ELAYERS
private

Definition at line 283 of file eagle_plugin.h.

Constructor & Destructor Documentation

◆ EAGLE_PLUGIN()

EAGLE_PLUGIN::EAGLE_PLUGIN ( )

Definition at line 274 of file eagle_plugin.cpp.

274  :
275  m_rules( new ERULES() ),
276  m_xpath( new XPATH() ),
277  m_progressReporter( nullptr ),
278  m_doneCount( 0 ),
279  m_lastProgressCount( 0 ),
280  m_totalCount( 0 ),
281  m_mod_time( wxDateTime::Now() )
282 {
283  using namespace std::placeholders;
284 
285  init( nullptr );
286  clear_cu_map();
288  this, _1 ) );
289 }
void clear_cu_map()
std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
Return the automapped layers.
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:294
unsigned m_lastProgressCount
Definition: eagle_plugin.h:312
Keep track of what we are working on within a PTREE.
Definition: eagle_parser.h:110
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
Definition: eagle_plugin.h:310
void init(const PROPERTIES *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
virtual void RegisterLayerMappingCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
unsigned m_doneCount
Definition: eagle_plugin.h:311
subset of eagle.drawing.board.designrules in the XML document
Definition: eagle_plugin.h:50
wxDateTime m_mod_time
Definition: eagle_plugin.h:321
unsigned m_totalCount
for progress reporting
Definition: eagle_plugin.h:313

References clear_cu_map(), DefaultLayerMappingCallback(), init(), and LAYER_REMAPPABLE_PLUGIN::RegisterLayerMappingCallback().

◆ ~EAGLE_PLUGIN()

EAGLE_PLUGIN::~EAGLE_PLUGIN ( )

Definition at line 292 of file eagle_plugin.cpp.

293 {
294  deleteTemplates();
295  delete m_rules;
296  delete m_xpath;
297 }
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:294
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
void deleteTemplates()

References deleteTemplates(), m_rules, and m_xpath.

Member Function Documentation

◆ cacheLib()

void EAGLE_PLUGIN::cacheLib ( const wxString &  aLibraryPath)
private

This PLUGIN only caches one footprint library, this determines which one.

Definition at line 3081 of file eagle_plugin.cpp.

3082 {
3083  try
3084  {
3085  wxDateTime modtime = getModificationTime( aLibPath );
3086 
3087  // Fixes assertions in wxWidgets debug builds for the wxDateTime object. Refresh the
3088  // cache if either of the wxDateTime objects are invalid or the last file modification
3089  // time differs from the current file modification time.
3090  bool load = !m_mod_time.IsValid() || !modtime.IsValid() || m_mod_time != modtime;
3091 
3092  if( aLibPath != m_lib_path || load )
3093  {
3094  wxXmlNode* doc;
3095  LOCALE_IO toggle; // toggles on, then off, the C locale.
3096 
3097  deleteTemplates();
3098 
3099  // Set this before completion of loading, since we rely on it for
3100  // text of an exception. Delay setting m_mod_time until after successful load
3101  // however.
3102  m_lib_path = aLibPath;
3103 
3104  // 8 bit "filename" should be encoded according to disk filename encoding,
3105  // (maybe this is current locale, maybe not, its a filesystem issue),
3106  // and is not necessarily utf8.
3107  string filename = (const char*) aLibPath.char_str( wxConvFile );
3108 
3109  // Load the document
3110  wxFileName fn( filename );
3111  wxFFileInputStream stream( fn.GetFullPath() );
3112  wxXmlDocument xmlDocument;
3113 
3114  if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3115  {
3116  THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'." ),
3117  fn.GetFullPath() ) );
3118  }
3119 
3120  doc = xmlDocument.GetRoot();
3121 
3122  wxXmlNode* drawing = MapChildren( doc )["drawing"];
3123  NODE_MAP drawingChildren = MapChildren( drawing );
3124 
3125  // clear the cu map and then rebuild it.
3126  clear_cu_map();
3127 
3128  m_xpath->push( "eagle.drawing.layers" );
3129  wxXmlNode* layers = drawingChildren["layers"];
3130  loadLayerDefs( layers );
3132  m_xpath->pop();
3133 
3134  m_xpath->push( "eagle.drawing.library" );
3135  wxXmlNode* library = drawingChildren["library"];
3136  loadLibrary( library, nullptr );
3137  m_xpath->pop();
3138 
3139  m_mod_time = modtime;
3140  }
3141  }
3142  catch(...){}
3143  // TODO: Handle exceptions
3144  // catch( file_parser_error fpe )
3145  // {
3146  // // for xml_parser_error, what() has the line number in it,
3147  // // but no byte offset. That should be an adequate error message.
3148  // THROW_IO_ERROR( fpe.what() );
3149  // }
3150  //
3151  // // Class ptree_error is a base class for xml_parser_error & file_parser_error,
3152  // // so one catch should be OK for all errors.
3153  // catch( ptree_error pte )
3154  // {
3155  // string errmsg = pte.what();
3156  //
3157  // errmsg += " @\n";
3158  // errmsg += m_xpath->Contents();
3159  //
3160  // THROW_IO_ERROR( errmsg );
3161  // }
3162 }
void clear_cu_map()
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
void loadLayerDefs(wxXmlNode *aLayers)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
wxString m_lib_path
Definition: eagle_plugin.h:320
#define _(s)
static wxDateTime getModificationTime(const wxString &aPath)
get a file's or dir's modification time.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxDateTime m_mod_time
Definition: eagle_plugin.h:321
void loadLibrary(wxXmlNode *aLib, const wxString *aLibName)
Load the Eagle "library" XML element, which can occur either under a "libraries" element (if a *....
void deleteTemplates()
void pop()
Definition: eagle_parser.h:122
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void mapEagleLayersToKicad()
Generate mapping between Eagle na KiCad layers.
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47

References _, clear_cu_map(), deleteTemplates(), Format(), getModificationTime(), library, loadLayerDefs(), loadLibrary(), m_lib_path, m_mod_time, m_xpath, MapChildren(), mapEagleLayersToKicad(), XPATH::pop(), XPATH::push(), and THROW_IO_ERROR.

Referenced by FootprintEnumerate(), and FootprintLoad().

◆ centerBoard()

void EAGLE_PLUGIN::centerBoard ( )
private

move the BOARD into the center of the page

Definition at line 3042 of file eagle_plugin.cpp.

3043 {
3044  if( m_props )
3045  {
3046  UTF8 page_width;
3047  UTF8 page_height;
3048 
3049  if( m_props->Value( "page_width", &page_width ) &&
3050  m_props->Value( "page_height", &page_height ) )
3051  {
3053 
3054  int w = atoi( page_width.c_str() );
3055  int h = atoi( page_height.c_str() );
3056 
3057  int desired_x = ( w - bbbox.GetWidth() ) / 2;
3058  int desired_y = ( h - bbbox.GetHeight() ) / 2;
3059 
3060  m_board->Move( wxPoint( desired_x - bbbox.GetX(), desired_y - bbbox.GetY() ) );
3061  }
3062  }
3063 }
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:70
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
int GetX() const
Definition: eda_rect.h:107
const EDA_RECT GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
Definition: board.h:738
int GetWidth() const
Definition: eda_rect.h:118
const char * c_str() const
Definition: utf8.h:102
const PROPERTIES * m_props
passed via Save() or Load(), no ownership, may be NULL.
Definition: eagle_plugin.h:307
bool Value(const char *aName, UTF8 *aFetchedValue=nullptr) const
Fetch a property by aName and returns true if that property was found, else false.
Definition: properties.cpp:24
int GetHeight() const
Definition: eda_rect.h:119
void Move(const wxPoint &aMoveVector) override
Move this object.
Definition: board.cpp:268
Handle the component boundary box.
Definition: eda_rect.h:42
int GetY() const
Definition: eda_rect.h:108

References UTF8::c_str(), BOARD::GetBoardEdgesBoundingBox(), EDA_RECT::GetHeight(), EDA_RECT::GetWidth(), EDA_RECT::GetX(), EDA_RECT::GetY(), m_board, m_props, BOARD::Move(), and PROPERTIES::Value().

Referenced by Load().

◆ checkpoint()

void EAGLE_PLUGIN::checkpoint ( )
private

Definition at line 312 of file eagle_plugin.cpp.

313 {
314  const unsigned PROGRESS_DELTA = 50;
315 
316  if( m_progressReporter )
317  {
318  if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA )
319  {
321  / std::max( 1U, m_totalCount ) );
322 
324  THROW_IO_ERROR( _( "Open cancelled by user." ) );
325 
327  }
328  }
329 }
unsigned m_lastProgressCount
Definition: eagle_plugin.h:312
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
Definition: eagle_plugin.h:310
unsigned m_doneCount
Definition: eagle_plugin.h:311
#define _(s)
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
unsigned m_totalCount
for progress reporting
Definition: eagle_plugin.h:313
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).

References _, PROGRESS_REPORTER::KeepRefreshing(), m_doneCount, m_lastProgressCount, m_progressReporter, m_totalCount, PROGRESS_REPORTER::SetCurrentProgress(), and THROW_IO_ERROR.

Referenced by loadClasses(), loadDesignRules(), loadElements(), loadLibrary(), loadPlain(), and loadSignals().

◆ clear_cu_map()

void EAGLE_PLUGIN::clear_cu_map ( )
private

Definition at line 501 of file eagle_plugin.cpp.

502 {
503  // All cu layers are invalid until we see them in the <layers> section while
504  // loading either a board or library. See loadLayerDefs().
505  for( unsigned i = 0; i < arrayDim(m_cu_map); ++i )
506  m_cu_map[i] = -1;
507 }
int m_cu_map[17]
map eagle to KiCad, cu layers only.
Definition: eagle_plugin.h:286
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31

References arrayDim(), and m_cu_map.

Referenced by cacheLib(), and EAGLE_PLUGIN().

◆ defaultKicadLayer()

std::tuple< PCB_LAYER_ID, LSET, bool > EAGLE_PLUGIN::defaultKicadLayer ( int  aEagleLayer) const
private

Get default KiCad layer corresponding to an Eagle layer of the board, a set of sensible layer mapping options and required flag.

Definition at line 2897 of file eagle_plugin.cpp.

2898 {
2899  // eagle copper layer:
2900  if( aEagleLayer >= 1 && aEagleLayer < int( arrayDim( m_cu_map ) ) )
2901  {
2902  LSET copperLayers;
2903 
2904  for( int copperLayer : m_cu_map )
2905  {
2906  if( copperLayer >= 0 )
2907  copperLayers[copperLayer] = true;
2908  }
2909 
2910  return { PCB_LAYER_ID( m_cu_map[aEagleLayer] ), copperLayers, true };
2911  }
2912 
2913  int kiLayer = UNSELECTED_LAYER;
2914  bool required = false;
2915  LSET permittedLayers;
2916 
2917  permittedLayers.set();
2918 
2919  // translate non-copper eagle layer to pcbnew layer
2920  switch( aEagleLayer )
2921  {
2922  // Eagle says "Dimension" layer, but it's for board perimeter
2924  kiLayer = Edge_Cuts;
2925  required = true;
2926  permittedLayers = LSET( 1, Edge_Cuts );
2927  break;
2928 
2929  case EAGLE_LAYER::TPLACE:
2930  kiLayer = F_SilkS;
2931  break;
2932  case EAGLE_LAYER::BPLACE:
2933  kiLayer = B_SilkS;
2934  break;
2935  case EAGLE_LAYER::TNAMES:
2936  kiLayer = F_SilkS;
2937  break;
2938  case EAGLE_LAYER::BNAMES:
2939  kiLayer = B_SilkS;
2940  break;
2941  case EAGLE_LAYER::TVALUES:
2942  kiLayer = F_Fab;
2943  break;
2944  case EAGLE_LAYER::BVALUES:
2945  kiLayer = B_Fab;
2946  break;
2947  case EAGLE_LAYER::TSTOP:
2948  kiLayer = F_Mask;
2949  break;
2950  case EAGLE_LAYER::BSTOP:
2951  kiLayer = B_Mask;
2952  break;
2953  case EAGLE_LAYER::TCREAM:
2954  kiLayer = F_Paste;
2955  break;
2956  case EAGLE_LAYER::BCREAM:
2957  kiLayer = B_Paste;
2958  break;
2959  case EAGLE_LAYER::TFINISH:
2960  kiLayer = F_Mask;
2961  break;
2962  case EAGLE_LAYER::BFINISH:
2963  kiLayer = B_Mask;
2964  break;
2965  case EAGLE_LAYER::TGLUE:
2966  kiLayer = F_Adhes;
2967  break;
2968  case EAGLE_LAYER::BGLUE:
2969  kiLayer = B_Adhes;
2970  break;
2971  case EAGLE_LAYER::DOCUMENT:
2972  kiLayer = Cmts_User;
2973  break;
2975  kiLayer = Cmts_User;
2976  break;
2978  kiLayer = Cmts_User;
2979  break;
2980 
2981  // Packages show the future chip pins on SMD parts using layer 51.
2982  // This is an area slightly smaller than the PAD/SMD copper area.
2983  // Carry those visual aids into the FOOTPRINT on the fabrication layer,
2984  // not silkscreen. This is perhaps not perfect, but there is not a lot
2985  // of other suitable paired layers
2986  case EAGLE_LAYER::TDOCU:
2987  kiLayer = F_Fab;
2988  break;
2989  case EAGLE_LAYER::BDOCU:
2990  kiLayer = B_Fab;
2991  break;
2992 
2993  // these layers are defined as user layers. put them on ECO layers
2995  kiLayer = Eco1_User;
2996  break;
2998  kiLayer = Eco2_User;
2999  break;
3000 
3001  // these will also appear in the ratsnest, so there's no need for a warning
3002  case EAGLE_LAYER::UNROUTED:
3003  kiLayer = Dwgs_User;
3004  break;
3005 
3006  case EAGLE_LAYER::TKEEPOUT:
3007  kiLayer = F_CrtYd;
3008  break;
3009  case EAGLE_LAYER::BKEEPOUT:
3010  kiLayer = B_CrtYd;
3011  break;
3012 
3013  case EAGLE_LAYER::MILLING:
3014  case EAGLE_LAYER::TTEST:
3015  case EAGLE_LAYER::BTEST:
3016  case EAGLE_LAYER::HOLES:
3017  default:
3018  kiLayer = UNDEFINED_LAYER;
3019  break;
3020  }
3021 
3022  return { PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3023 }
int m_cu_map[17]
map eagle to KiCad, cu layers only.
Definition: eagle_plugin.h:286
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:516
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65

References arrayDim(), B_Adhes, B_CrtYd, B_Fab, B_Mask, B_Paste, B_SilkS, EAGLE_LAYER::BCREAM, EAGLE_LAYER::BDOCU, EAGLE_LAYER::BFINISH, EAGLE_LAYER::BGLUE, EAGLE_LAYER::BKEEPOUT, EAGLE_LAYER::BNAMES, EAGLE_LAYER::BPLACE, EAGLE_LAYER::BSTOP, EAGLE_LAYER::BTEST, EAGLE_LAYER::BVALUES, Cmts_User, EAGLE_LAYER::DIMENSION, EAGLE_LAYER::DOCUMENT, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Fab, F_Mask, F_Paste, F_SilkS, EAGLE_LAYER::HOLES, m_cu_map, EAGLE_LAYER::MILLING, EAGLE_LAYER::REFERENCELC, EAGLE_LAYER::REFERENCELS, EAGLE_LAYER::TCREAM, EAGLE_LAYER::TDOCU, EAGLE_LAYER::TFINISH, EAGLE_LAYER::TGLUE, EAGLE_LAYER::TKEEPOUT, EAGLE_LAYER::TNAMES, EAGLE_LAYER::TPLACE, EAGLE_LAYER::TSTOP, EAGLE_LAYER::TTEST, EAGLE_LAYER::TVALUES, UNDEFINED_LAYER, EAGLE_LAYER::UNROUTED, UNSELECTED_LAYER, EAGLE_LAYER::USERLAYER1, and EAGLE_LAYER::USERLAYER2.

Referenced by DefaultLayerMappingCallback(), and mapEagleLayersToKicad().

◆ DefaultLayerMappingCallback()

std::map< wxString, PCB_LAYER_ID > EAGLE_PLUGIN::DefaultLayerMappingCallback ( const std::vector< INPUT_LAYER_DESC > &  aInputLayerDescriptionVector)

Return the automapped layers.

The callback needs to have the context of the current board so it can correctly determine copper layer mapping. Thus, it is not static and is expected to be bind to an instance of EAGLE_PLUGIN.

Parameters
aInputLayerDescriptionVector
Returns
Auto-mapped layers

Definition at line 2845 of file eagle_plugin.cpp.

2847 {
2848  std::map<wxString, PCB_LAYER_ID> layer_map;
2849 
2850  for ( const INPUT_LAYER_DESC& layer : aInputLayerDescriptionVector )
2851  {
2852  PCB_LAYER_ID layerId = std::get<0>( defaultKicadLayer( eagle_layer_id( layer.Name ) ) );
2853  layer_map.emplace( layer.Name, layerId );
2854  }
2855 
2856  return layer_map;
2857 }
int eagle_layer_id(const wxString &aLayerName) const
Get Eagle layer number by its name.
Describes an imported layer and how it could be mapped to KiCad Layers.
std::tuple< PCB_LAYER_ID, LSET, bool > defaultKicadLayer(int aEagleLayer) const
Get default KiCad layer corresponding to an Eagle layer of the board, a set of sensible layer mapping...
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65

References defaultKicadLayer(), and eagle_layer_id().

Referenced by EAGLE_PLUGIN().

◆ deleteTemplates()

void EAGLE_PLUGIN::deleteTemplates ( )
private

Definition at line 2504 of file eagle_plugin.cpp.

2505 {
2506  for( auto& t : m_templates )
2507  delete t.second;
2508 
2509  m_templates.clear();
2510 }
FOOTPRINT_MAP m_templates
is part of a FOOTPRINT factory that operates using copy construction.
Definition: eagle_plugin.h:302

References m_templates.

Referenced by cacheLib(), and ~EAGLE_PLUGIN().

◆ eagle_layer_id()

int EAGLE_PLUGIN::eagle_layer_id ( const wxString &  aLayerName) const
private

Get Eagle layer number by its name.

Definition at line 3034 of file eagle_plugin.cpp.

3035 {
3036  static const int unknown = -1;
3037  auto it = m_eagleLayersIds.find( aLayerName );
3038  return it == m_eagleLayersIds.end() ? unknown : it->second;
3039 }
std::map< wxString, int > m_eagleLayersIds
Eagle layer ids stored by layer name.
Definition: eagle_plugin.h:288

References m_eagleLayersIds, and unknown.

Referenced by DefaultLayerMappingCallback().

◆ eagle_layer_name()

const wxString & EAGLE_PLUGIN::eagle_layer_name ( int  aLayer) const
private

Get Eagle layer name by its number.

Definition at line 3026 of file eagle_plugin.cpp.

3027 {
3028  static const wxString unknown( "unknown" );
3029  auto it = m_eagleLayers.find( aLayer );
3030  return it == m_eagleLayers.end() ? unknown : it->second.name;
3031 }
std::map< int, ELAYER > m_eagleLayers
Eagle layer data stored by layer number.
Definition: eagle_plugin.h:287

References m_eagleLayers, and unknown.

Referenced by kicad_layer(), loadPolygon(), packageCircle(), packagePolygon(), packageRectangle(), packageText(), and packageWire().

◆ FootprintDelete()

void PLUGIN::FootprintDelete ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties = nullptr 
)
virtualinherited

Delete aFootprintName from the library at aLibraryPath.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintNameis the name of a footprint to delete from the specified library.
aPropertiesis an associative array that can be used to tell the library delete function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem finding the footprint or the library, or deleting it.

Reimplemented in PCB_PLUGIN, and GPCB_PLUGIN.

Definition at line 116 of file plugin.cpp.

118 {
119  // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
120  not_implemented( this, __FUNCTION__ );
121 }
static void not_implemented(PLUGIN *aPlugin, const char *aCaller)
Throw an IO_ERROR and complains of an API function not being implemented.
Definition: plugin.cpp:38

References not_implemented().

◆ FootprintEnumerate()

void EAGLE_PLUGIN::FootprintEnumerate ( wxArrayString &  aFootprintNames,
const wxString &  aLibraryPath,
bool  aBestEfforts,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Return a list of footprint names contained within the library at aLibraryPath.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the plugin anything needed about how to perform with respect to aLibraryPath. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
aFootprintNamesis the array of available footprint names inside a library.
aBestEffortsif true, don't throw on errors, just return an empty list.
Exceptions
IO_ERRORif the library cannot be found, or footprint cannot be loaded.

Reimplemented from PLUGIN.

Definition at line 3165 of file eagle_plugin.cpp.

3167 {
3168  wxString errorMsg;
3169 
3170  init( aProperties );
3171 
3172  try
3173  {
3174  cacheLib( aLibraryPath );
3175  }
3176  catch( const IO_ERROR& ioe )
3177  {
3178  errorMsg = ioe.What();
3179  }
3180 
3181  // Some of the files may have been parsed correctly so we want to add the valid files to
3182  // the library.
3183 
3184  for( FOOTPRINT_MAP::const_iterator it = m_templates.begin(); it != m_templates.end(); ++it )
3185  aFootprintNames.Add( FROM_UTF8( it->first.c_str() ) );
3186 
3187  if( !errorMsg.IsEmpty() && !aBestEfforts )
3188  THROW_IO_ERROR( errorMsg );
3189 }
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
void init(const PROPERTIES *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
FOOTPRINT_MAP m_templates
is part of a FOOTPRINT factory that operates using copy construction.
Definition: eagle_plugin.h:302
void cacheLib(const wxString &aLibraryPath)
This PLUGIN only caches one footprint library, this determines which one.
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References cacheLib(), FROM_UTF8(), init(), m_templates, THROW_IO_ERROR, and IO_ERROR::What().

◆ FootprintExists()

bool PLUGIN::FootprintExists ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties = nullptr 
)
virtualinherited

Check for the existence of a footprint.

Reimplemented in PCB_PLUGIN.

Definition at line 89 of file plugin.cpp.

91 {
92  // default implementation
93  return FootprintLoad( aLibraryPath, aFootprintName, true, aProperties ) != nullptr;
94 }
virtual FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const PROPERTIES *aProperties=nullptr)
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PL...
Definition: plugin.cpp:97

References PLUGIN::FootprintLoad().

◆ FootprintLibCreate()

void PLUGIN::FootprintLibCreate ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = nullptr 
)
virtualinherited

Create a new empty footprint library at aLibraryPath empty.

It is an error to attempt to create an existing library or to attempt to create on a "read only" location.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the library create function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem finding the library, or creating it.

Reimplemented in PCB_PLUGIN.

Definition at line 124 of file plugin.cpp.

125 {
126  // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
127  not_implemented( this, __FUNCTION__ );
128 }
static void not_implemented(PLUGIN *aPlugin, const char *aCaller)
Throw an IO_ERROR and complains of an API function not being implemented.
Definition: plugin.cpp:38

References not_implemented().

◆ FootprintLibDelete()

bool PLUGIN::FootprintLibDelete ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = nullptr 
)
virtualinherited

Delete an existing footprint library and returns true, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason.

Parameters
aLibraryPathis a locator for the "library", usually a directory or file which will contain footprints.
aPropertiesis an associative array that can be used to tell the library delete implementation function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
true if library deleted, false if library did not exist.
Exceptions
IO_ERRORif there is a problem deleting an existing library.

Reimplemented in PCB_PLUGIN, LEGACY_PLUGIN, and GPCB_PLUGIN.

Definition at line 131 of file plugin.cpp.

132 {
133  // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
134  not_implemented( this, __FUNCTION__ );
135  return false;
136 }
static void not_implemented(PLUGIN *aPlugin, const char *aCaller)
Throw an IO_ERROR and complains of an API function not being implemented.
Definition: plugin.cpp:38

References not_implemented().

◆ FootprintLibOptions()

void EAGLE_PLUGIN::FootprintLibOptions ( PROPERTIES aListToAppendTo) const
overridevirtual

Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions.

Options are typically appended so that a derived PLUGIN can call its base class function by the same name first, thus inheriting options declared there. Some base class options could pertain to all Footprint*() functions in all derived PLUGINs.

Note
Since aListToAppendTo is a PROPERTIES object, all options will be unique and last guy wins.
Parameters
aListToAppendToholds a tuple of
option
This eventually is what shows up into the fp-lib-table "options" field, possibly combined with others.
internationalized description
The internationalized description is displayed in DIALOG_FP_PLUGIN_OPTIONS. It may be multi-line and be quite explanatory of the option.

In the future perhaps aListToAppendTo evolves to something capable of also holding a wxValidator for the cells in said dialog: http://forums.wxwidgets.org/viewtopic.php?t=23277&p=104180. This would require a 3 column list, and introducing wx GUI knowledge to PLUGIN, which has been avoided to date.

Reimplemented from PLUGIN.

Definition at line 3210 of file eagle_plugin.cpp.

3211 {
3212  PLUGIN::FootprintLibOptions( aListToAppendTo );
3213 }
virtual void FootprintLibOptions(PROPERTIES *aListToAppendTo) const
Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions.
Definition: plugin.cpp:147

References PLUGIN::FootprintLibOptions().

◆ FootprintLoad()

FOOTPRINT * EAGLE_PLUGIN::FootprintLoad ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
bool  aKeepUUID = false,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PLUGIN knows about.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintNameis the name of the footprint to load.
aPropertiesis an associative array that can be used to tell the loader implementation to do something special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
aKeepUUID= true to keep initial items UUID, false to set new UUID normally true if loaded in the footprint editor, false if loaded in the board editor. Make sense only in kicad_plugin
Returns
the FOOTPRINT object if found caller owns it, else NULL if not found.
Exceptions
IO_ERRORif the library cannot be found or read. No exception is thrown in the case where aFootprintName cannot be found.

Reimplemented from PLUGIN.

Definition at line 3192 of file eagle_plugin.cpp.

3195 {
3196  init( aProperties );
3197  cacheLib( aLibraryPath );
3198  FOOTPRINT_MAP::const_iterator it = m_templates.find( aFootprintName );
3199 
3200  if( it == m_templates.end() )
3201  return nullptr;
3202 
3203  // Return a copy of the template
3204  FOOTPRINT* copy = (FOOTPRINT*) it->second->Duplicate();
3205  copy->SetParent( nullptr );
3206  return copy;
3207 }
void init(const PROPERTIES *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
FOOTPRINT_MAP m_templates
is part of a FOOTPRINT factory that operates using copy construction.
Definition: eagle_plugin.h:302
void cacheLib(const wxString &aLibraryPath)
This PLUGIN only caches one footprint library, this determines which one.

References cacheLib(), copy, init(), and m_templates.

◆ FootprintSave()

void PLUGIN::FootprintSave ( const wxString &  aLibraryPath,
const FOOTPRINT aFootprint,
const PROPERTIES aProperties = nullptr 
)
virtualinherited

Write aFootprint to an existing library located at aLibraryPath.

If a footprint by the same name already exists, it is replaced.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintis what to store in the library. The caller continues to own the footprint after this call.
aPropertiesis an associative array that can be used to tell the saver how to save the footprint, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem saving.

Reimplemented in PCB_PLUGIN.

Definition at line 108 of file plugin.cpp.

110 {
111  // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
112  not_implemented( this, __FUNCTION__ );
113 }
static void not_implemented(PLUGIN *aPlugin, const char *aCaller)
Throw an IO_ERROR and complains of an API function not being implemented.
Definition: plugin.cpp:38

References not_implemented().

◆ GetEnumeratedFootprint()

const FOOTPRINT * PLUGIN::GetEnumeratedFootprint ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties = nullptr 
)
virtualinherited

A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management.

Reimplemented in PCB_PLUGIN, and GPCB_PLUGIN.

Definition at line 80 of file plugin.cpp.

83 {
84  // default implementation
85  return FootprintLoad( aLibraryPath, aFootprintName, false, aProperties );
86 }
virtual FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const PROPERTIES *aProperties=nullptr)
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PL...
Definition: plugin.cpp:97

References PLUGIN::FootprintLoad().

◆ GetFileExtension()

const wxString EAGLE_PLUGIN::GetFileExtension ( ) const
overridevirtual

Returns the file extension for the PLUGIN.

Implements PLUGIN.

Definition at line 306 of file eagle_plugin.cpp.

307 {
308  return wxT( "brd" );
309 }

◆ GetImportedCachedLibraryFootprints()

std::vector< FOOTPRINT * > EAGLE_PLUGIN::GetImportedCachedLibraryFootprints ( )
overridevirtual

Return a container with the cached library footprints generated in the last call to Load.

This function is intended to be used ONLY by the non-KiCad board importers for the purpose of obtaining the footprint library of the design and creating a project-specific library.

Returns
Footprints (caller owns the objects)

Reimplemented from PLUGIN.

Definition at line 471 of file eagle_plugin.cpp.

472 {
473  std::vector<FOOTPRINT*> retval;
474 
475  for( std::pair<wxString, FOOTPRINT*> fp : m_templates )
476  retval.push_back( static_cast<FOOTPRINT*>( fp.second->Clone() ) );
477 
478  return retval;
479 }
FOOTPRINT_MAP m_templates
is part of a FOOTPRINT factory that operates using copy construction.
Definition: eagle_plugin.h:302

References m_templates.

◆ GetLibraryTimestamp()

long long EAGLE_PLUGIN::GetLibraryTimestamp ( const wxString &  aLibraryPath) const
inlineoverridevirtual

Generate a timestamp representing all the files in the library (including the library directory).

Timestamps should not be considered ordered, they either match or they don't.

Implements PLUGIN.

Definition at line 149 of file eagle_plugin.h.

150  {
151  return getModificationTime( aLibraryPath ).GetValue().GetValue();
152  }
static wxDateTime getModificationTime(const wxString &aPath)
get a file's or dir's modification time.

References getModificationTime().

◆ getModificationTime()

wxDateTime EAGLE_PLUGIN::getModificationTime ( const wxString &  aPath)
staticprivate

get a file's or dir's modification time.

Definition at line 3066 of file eagle_plugin.cpp.

3067 {
3068  // File hasn't been loaded yet.
3069  if( aPath.IsEmpty() )
3070  return wxDateTime::Now();
3071 
3072  wxFileName fn( aPath );
3073 
3074  if( fn.IsFileReadable() )
3075  return fn.GetModificationTime();
3076  else
3077  return wxDateTime( 0.0 );
3078 }

Referenced by cacheLib(), and GetLibraryTimestamp().

◆ init()

void EAGLE_PLUGIN::init ( const PROPERTIES aProperties)
private

initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.

Definition at line 482 of file eagle_plugin.cpp.

483 {
484  m_hole_count = 0;
485  m_min_trace = 0;
486  m_min_hole = 0;
487  m_min_via = 0;
488  m_min_annulus = 0;
489  m_xpath->clear();
490  m_pads_to_nets.clear();
491 
492  m_board = nullptr;
493  m_props = aProperties;
494 
495 
496  delete m_rules;
497  m_rules = new ERULES();
498 }
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
void clear()
Definition: eagle_parser.h:120
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:294
int m_min_via
smallest via we find on Load(), in BIU.
Definition: eagle_plugin.h:317
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
const PROPERTIES * m_props
passed via Save() or Load(), no ownership, may be NULL.
Definition: eagle_plugin.h:307
subset of eagle.drawing.board.designrules in the XML document
Definition: eagle_plugin.h:50
int m_min_trace
smallest trace we find on Load(), in BIU.
Definition: eagle_plugin.h:315
int m_hole_count
generates unique footprint names from eagle "hole"s.
Definition: eagle_plugin.h:298
int m_min_annulus
smallest via annulus we find on Load(), in BIU.
Definition: eagle_plugin.h:318
NET_MAP m_pads_to_nets
net list
Definition: eagle_plugin.h:300
int m_min_hole
smallest diameter hole we find on Load(), in BIU.
Definition: eagle_plugin.h:316

References XPATH::clear(), m_board, m_hole_count, m_min_annulus, m_min_hole, m_min_trace, m_min_via, m_pads_to_nets, m_props, m_rules, and m_xpath.

Referenced by EAGLE_PLUGIN(), FootprintEnumerate(), FootprintLoad(), and Load().

◆ IsFootprintLibWritable()

bool EAGLE_PLUGIN::IsFootprintLibWritable ( const wxString &  aLibraryPath)
inlineoverridevirtual

Return true if the library at aLibraryPath is writable.

The system libraries are typically read only because of where they are installed..

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
Exceptions
IO_ERRORif no library at aLibraryPath exists.

Reimplemented from PLUGIN.

Definition at line 154 of file eagle_plugin.h.

155  {
156  return false; // until someone writes others like FootprintSave(), etc.
157  }

◆ kicad_fontz()

wxSize EAGLE_PLUGIN::kicad_fontz ( const ECOORD d,
int  aTextThickness 
) const
inlineprivate

create a font size (fontz) from an eagle font size scalar and KiCad font thickness

Definition at line 332 of file eagle_plugin.cpp.

333 {
334  // Eagle includes stroke thickness in the text size, KiCAD does not
335  int kz = d.ToPcbUnits();
336  return wxSize( kz - aTextThickness, kz - aTextThickness );
337 }
int ToPcbUnits() const
Definition: eagle_parser.h:430

References ECOORD::ToPcbUnits().

Referenced by loadPlain(), orientFPText(), and packageText().

◆ kicad_layer()

PCB_LAYER_ID EAGLE_PLUGIN::kicad_layer ( int  aLayer) const
private

Convert an Eagle layer to a KiCad layer.

Definition at line 2890 of file eagle_plugin.cpp.

2891 {
2892  auto result = m_layer_map.find( eagle_layer_name( aEagleLayer ) );
2893  return result == m_layer_map.end() ? UNDEFINED_LAYER : result->second;
2894 }
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
std::map< wxString, PCB_LAYER_ID > m_layer_map
Map of Eagle layers to KiCad layers.
Definition: eagle_plugin.h:289

References eagle_layer_name(), m_layer_map, and UNDEFINED_LAYER.

Referenced by loadLayerDefs(), loadPlain(), loadPolygon(), loadSignals(), makeFootprint(), packageCircle(), packagePolygon(), packageRectangle(), packageSMD(), packageText(), and packageWire().

◆ kicad_x()

int EAGLE_PLUGIN::kicad_x ( const ECOORD x) const
inlineprivate

◆ kicad_y()

int EAGLE_PLUGIN::kicad_y ( const ECOORD y) const
inlineprivate

Convert an Eagle distance to a KiCad distance.

Definition at line 188 of file eagle_plugin.h.

188 { return -y.ToPcbUnits(); }
int ToPcbUnits() const
Definition: eagle_parser.h:430

References ECOORD::ToPcbUnits().

Referenced by loadElements(), loadPlain(), loadPolygon(), loadSignals(), orientFPText(), packageCircle(), packageHole(), packagePolygon(), packageRectangle(), packageText(), packageWire(), and transferPad().

◆ Load()

BOARD * EAGLE_PLUGIN::Load ( const wxString &  aFileName,
BOARD aAppendToMe,
const PROPERTIES aProperties = nullptr,
PROJECT aProject = nullptr,
PROGRESS_REPORTER aProgressReporter = nullptr 
)
overridevirtual

Load information from some input file format that this PLUGIN implementation knows about into either a new BOARD or an existing one.

This may be used to load an entire new BOARD, or to augment an existing one if aAppendToMe is not NULL.

Parameters
aFileNameis the name of the file to use as input and may be foreign in nature or native in nature.
aAppendToMeis an existing BOARD to append to, but if NULL then this means "do not append, rather load anew".
aPropertiesis an associative array that can be used to tell the loader how to load the file, because it can take any number of additional named arguments that the plugin is known to support. These are tuning parameters for the import or load. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
aProjectis the optional PROJECT object primarily used by third party importers.
aProgressReporteran optional progress reporter
aLineCounta line count (necessary if a progress reporter is supplied)
Returns
the successfully loaded board, or the same one as aAppendToMe if aAppendToMe was not NULL, and caller owns it.
Exceptions
IO_ERRORif there is a problem loading, and its contents should say what went wrong, using line number and character offsets of the input file if possible.

Reimplemented from PLUGIN.

Definition at line 340 of file eagle_plugin.cpp.

343 {
344  LOCALE_IO toggle; // toggles on, then off, the C locale.
345  wxXmlNode* doc;
346 
347  init( aProperties );
348 
349  m_board = aAppendToMe ? aAppendToMe : new BOARD();
350  m_progressReporter = aProgressReporter;
351 
352  // Give the filename to the board if it's new
353  if( !aAppendToMe )
354  m_board->SetFileName( aFileName );
355 
356  // delete on exception, if I own m_board, according to aAppendToMe
357  unique_ptr<BOARD> deleter( aAppendToMe ? nullptr : m_board );
358 
359  try
360  {
361  if( m_progressReporter )
362  {
363  m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
364 
366  THROW_IO_ERROR( _( "Open cancelled by user." ) );
367  }
368 
369  wxFileName fn = aFileName;
370 
371  // Load the document
372  wxFFileInputStream stream( fn.GetFullPath() );
373  wxXmlDocument xmlDocument;
374 
375  if( !stream.IsOk() || !xmlDocument.Load( stream ) )
376  {
377  THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'" ),
378  fn.GetFullPath() ) );
379  }
380 
381  doc = xmlDocument.GetRoot();
382 
383  m_min_trace = INT_MAX;
384  m_min_hole = INT_MAX;
385  m_min_via = INT_MAX;
386  m_min_annulus = INT_MAX;
387 
388  loadAllSections( doc );
389 
390  BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
391 
392  if( m_min_trace < designSettings.m_TrackMinWidth )
393  designSettings.m_TrackMinWidth = m_min_trace;
394 
395  if( m_min_via < designSettings.m_ViasMinSize )
396  designSettings.m_ViasMinSize = m_min_via;
397 
398  if( m_min_hole < designSettings.m_MinThroughDrill )
399  designSettings.m_MinThroughDrill = m_min_hole;
400 
401  if( m_min_annulus < designSettings.m_ViasMinAnnularWidth )
402  designSettings.m_ViasMinAnnularWidth = m_min_annulus;
403 
404  if( m_rules->mdWireWire )
405  designSettings.m_MinClearance = KiROUND( m_rules->mdWireWire );
406 
407  NETCLASS defaults( wxT( "dummy" ) );
408 
409  auto finishNetclass =
410  [&]( NETCLASSPTR netclass )
411  {
412  // If Eagle has a clearance matrix then we'll build custom rules from that.
413  // Netclasses should just be the board minimum clearance.
414  netclass->SetClearance( KiROUND( designSettings.m_MinClearance ) );
415 
416  if( netclass->GetTrackWidth() == INT_MAX )
417  netclass->SetTrackWidth( defaults.GetTrackWidth() );
418 
419  if( netclass->GetViaDiameter() == INT_MAX )
420  netclass->SetViaDiameter( defaults.GetViaDiameter() );
421 
422  if( netclass->GetViaDrill() == INT_MAX )
423  netclass->SetViaDrill( defaults.GetViaDrill() );
424  };
425 
426  finishNetclass( designSettings.GetNetClasses().GetDefault() );
427 
428  for( const std::pair<const wxString, NETCLASSPTR>& entry : designSettings.GetNetClasses() )
429  finishNetclass( entry.second );
430 
433 
434  fn.SetExt( wxT( "kicad_dru" ) );
435  wxFile rulesFile( fn.GetFullPath(), wxFile::write );
436  rulesFile.Write( m_customRules );
437 
438  // should be empty, else missing m_xpath->pop()
439  wxASSERT( m_xpath->Contents().size() == 0 );
440  }
441  catch( const XML_PARSER_ERROR &exc )
442  {
443  wxString errmsg = exc.what();
444 
445  errmsg += wxT( "\[email protected] " );
446  errmsg += m_xpath->Contents();
447 
448  THROW_IO_ERROR( errmsg );
449  }
450 
451  // IO_ERROR exceptions are left uncaught, they pass upwards from here.
452 
453  // Ensure the copper layers count is a multiple of 2
454  // Pcbnew does not like boards with odd layers count
455  // (these boards cannot exist. they actually have a even layers count)
456  int lyrcnt = m_board->GetCopperLayerCount();
457 
458  if( (lyrcnt % 2) != 0 )
459  {
460  lyrcnt++;
461  m_board->SetCopperLayerCount( lyrcnt );
462  }
463 
464  centerBoard();
465 
466  deleter.release();
467  return m_board;
468 }
wxString Contents()
return the contents of the XPATH as a single string
Definition: eagle_parser.h:137
void loadAllSections(wxXmlNode *aDocument)
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: board.h:269
void centerBoard()
move the BOARD into the center of the page
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
Definition: board.h:273
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:294
void SetCopperLayerCount(int aCount)
Definition: board.cpp:461
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
Definition: eagle_plugin.h:310
void init(const PROPERTIES *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
int m_min_via
smallest via we find on Load(), in BIU.
Definition: eagle_plugin.h:317
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
Definition: eagle_parser.h:68
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:46
#define _(s)
NETCLASSES & GetNetClasses() const
void SetFileName(const wxString &aFileName)
Definition: board.h:227
double mdWireWire
wire to wire spacing I presume.
Definition: eagle_plugin.h:121
int m_min_trace
smallest trace we find on Load(), in BIU.
Definition: eagle_plugin.h:315
wxString m_customRules
Definition: eagle_plugin.h:292
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:191
int GetCopperLayerCount() const
Definition: board.cpp:455
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
int m_min_annulus
smallest via annulus we find on Load(), in BIU.
Definition: eagle_plugin.h:318
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
int m_min_hole
smallest diameter hole we find on Load(), in BIU.
Definition: eagle_plugin.h:316
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
Container for design settings for a BOARD object.

References _, centerBoard(), XPATH::Contents(), Format(), BOARD::GetCopperLayerCount(), NETCLASSES::GetDefault(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetNetClasses(), NETCLASS::GetTrackWidth(), NETCLASS::GetViaDiameter(), NETCLASS::GetViaDrill(), init(), PROGRESS_REPORTER::KeepRefreshing(), KiROUND(), loadAllSections(), m_board, m_customRules, BOARD::m_LegacyDesignSettingsLoaded, BOARD::m_LegacyNetclassesLoaded, m_min_annulus, m_min_hole, m_min_trace, m_min_via, BOARD_DESIGN_SETTINGS::m_MinClearance, BOARD_DESIGN_SETTINGS::m_MinThroughDrill, m_progressReporter, m_rules, BOARD_DESIGN_SETTINGS::m_TrackMinWidth, BOARD_DESIGN_SETTINGS::m_ViasMinAnnularWidth, BOARD_DESIGN_SETTINGS::m_ViasMinSize, m_xpath, ERULES::mdWireWire, PROGRESS_REPORTER::Report(), BOARD::SetCopperLayerCount(), BOARD::SetFileName(), and THROW_IO_ERROR.

◆ loadAllSections()

void EAGLE_PLUGIN::loadAllSections ( wxXmlNode *  aDocument)
private

Definition at line 510 of file eagle_plugin.cpp.

511 {
512  wxXmlNode* drawing = MapChildren( aDoc )["drawing"];
513  NODE_MAP drawingChildren = MapChildren( drawing );
514 
515  wxXmlNode* board = drawingChildren["board"];
516  NODE_MAP boardChildren = MapChildren( board );
517 
518  auto count_children = [this]( wxXmlNode* aNode )
519  {
520  if( aNode )
521  {
522  wxXmlNode* child = aNode->GetChildren();
523 
524  while( child )
525  {
526  m_totalCount++;
527  child = child->GetNext();
528  }
529  }
530  };
531 
532  wxXmlNode* designrules = boardChildren["designrules"];
533  wxXmlNode* layers = drawingChildren["layers"];
534  wxXmlNode* plain = boardChildren["plain"];
535  wxXmlNode* classes = boardChildren["classes"];
536  wxXmlNode* signals = boardChildren["signals"];
537  wxXmlNode* libs = boardChildren["libraries"];
538  wxXmlNode* elems = boardChildren["elements"];
539 
540  if( m_progressReporter )
541  {
542  m_totalCount = 0;
543  m_doneCount = 0;
544 
545  count_children( designrules );
546  count_children( layers );
547  count_children( plain );
548  count_children( signals );
549  count_children( elems );
550 
551  while( libs )
552  {
553  count_children( MapChildren( libs )["packages"] );
554  libs = libs->GetNext();
555  }
556 
557  // Rewind
558  libs = boardChildren["libraries"];
559  }
560 
561  m_xpath->push( "eagle.drawing" );
562 
563  {
564  m_xpath->push( "board" );
565 
566  loadDesignRules( designrules );
567 
568  m_xpath->pop();
569  }
570 
571  {
572  m_xpath->push( "layers" );
573 
574  loadLayerDefs( layers );
576 
577  m_xpath->pop();
578  }
579 
580  {
581  m_xpath->push( "board" );
582 
583  loadPlain( plain );
584  loadClasses( classes );
585  loadSignals( signals );
586  loadLibraries( libs );
587  loadElements( elems );
588 
589  m_xpath->pop();
590  }
591 
592  m_xpath->pop(); // "eagle.drawing"
593 }
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
Definition: eagle_plugin.h:310
void loadLayerDefs(wxXmlNode *aLayers)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
unsigned m_doneCount
Definition: eagle_plugin.h:311
void loadLibraries(wxXmlNode *aLibs)
void loadPlain(wxXmlNode *aPlain)
void loadElements(wxXmlNode *aElements)
void pop()
Definition: eagle_parser.h:122
void loadDesignRules(wxXmlNode *aDesignRules)
unsigned m_totalCount
for progress reporting
Definition: eagle_plugin.h:313
void mapEagleLayersToKicad()
Generate mapping between Eagle na KiCad layers.
void loadSignals(wxXmlNode *aSignals)
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47
void loadClasses(wxXmlNode *aClasses)

References loadClasses(), loadDesignRules(), loadElements(), loadLayerDefs(), loadLibraries(), loadPlain(), loadSignals(), m_doneCount, m_progressReporter, m_totalCount, m_xpath, MapChildren(), mapEagleLayersToKicad(), XPATH::pop(), and XPATH::push().

Referenced by Load().

◆ loadClasses()

void EAGLE_PLUGIN::loadClasses ( wxXmlNode *  aClasses)
private

Definition at line 2513 of file eagle_plugin.cpp.

2514 {
2516 
2517  m_xpath->push( "classes.class", "number" );
2518 
2519  std::vector<ECLASS> eClasses;
2520  wxXmlNode* classNode = aClasses->GetChildren();
2521 
2522  while( classNode )
2523  {
2524  checkpoint();
2525 
2526  ECLASS eClass( classNode );
2527  NETCLASSPTR netclass;
2528 
2529  if( eClass.name.CmpNoCase( wxT( "default" ) ) == 0 )
2530  {
2531  netclass = bds.GetNetClasses().GetDefault();
2532  }
2533  else
2534  {
2535  netclass.reset( new NETCLASS( eClass.name ) );
2536  m_board->GetDesignSettings().GetNetClasses().Add( netclass );
2537  }
2538 
2539  netclass->SetTrackWidth( INT_MAX );
2540  netclass->SetViaDiameter( INT_MAX );
2541  netclass->SetViaDrill( INT_MAX );
2542 
2543  eClasses.emplace_back( eClass );
2544  m_classMap[ eClass.number ] = netclass;
2545 
2546  // Get next class
2547  classNode = classNode->GetNext();
2548  }
2549 
2550  m_customRules = wxT( "(version 1)" );
2551 
2552  for( ECLASS& eClass : eClasses )
2553  {
2554  for( std::pair<const wxString&, ECOORD> entry : eClass.clearanceMap )
2555  {
2556  if( m_classMap[ entry.first ] != nullptr )
2557  {
2558  wxString rule;
2559  rule.Printf( wxT( "(rule \"class %s:%s\"\n"
2560  " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2561  " (constraint clearance (min %smm)))\n" ),
2562  eClass.number,
2563  entry.first,
2564  eClass.name,
2565  m_classMap[ entry.first ]->GetName(),
2566  StringFromValue( EDA_UNITS::MILLIMETRES, entry.second.ToPcbUnits() ) );
2567 
2568  m_customRules += wxT( "\n" ) + rule;
2569  }
2570  }
2571  }
2572 
2573  m_xpath->pop(); // "classes.class"
2574 }
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:46
NETCLASSES & GetNetClasses() const
wxString m_customRules
Definition: eagle_plugin.h:292
bool Add(const NETCLASSPTR &aNetclass)
Add aNetclass and puts it into this NETCLASSES container.
Definition: netclass.cpp:90
wxString StringFromValue(EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:204
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
void pop()
Definition: eagle_parser.h:122
std::map< wxString, NETCLASSPTR > m_classMap
Eagle class number to KiCad netclass.
Definition: eagle_plugin.h:291
Container for design settings for a BOARD object.

References NETCLASSES::Add(), checkpoint(), NETCLASSES::GetDefault(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetNetClasses(), m_board, m_classMap, m_customRules, m_xpath, MILLIMETRES, ECLASS::name, ECLASS::number, XPATH::pop(), XPATH::push(), and StringFromValue().

Referenced by loadAllSections().

◆ loadDesignRules()

void EAGLE_PLUGIN::loadDesignRules ( wxXmlNode *  aDesignRules)
private

Definition at line 596 of file eagle_plugin.cpp.

597 {
598  if( aDesignRules )
599  {
600  m_xpath->push( "designrules" );
601  m_rules->parse( aDesignRules, [this](){ checkpoint(); } );
602  m_xpath->pop(); // "designrules"
603  }
604 }
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:294
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
void parse(wxXmlNode *aRules, std::function< void()> aCheckpoint)
percent over 100%.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
void pop()
Definition: eagle_parser.h:122

References checkpoint(), m_rules, m_xpath, ERULES::parse(), XPATH::pop(), and XPATH::push().

Referenced by loadAllSections().

◆ loadElements()

void EAGLE_PLUGIN::loadElements ( wxXmlNode *  aElements)
private

Definition at line 1186 of file eagle_plugin.cpp.

1187 {
1188  if( !aElements )
1189  return;
1190 
1191  m_xpath->push( "elements.element", "name" );
1192 
1193  EATTR name;
1194  EATTR value;
1195  bool refanceNamePresetInPackageLayout;
1196  bool valueNamePresetInPackageLayout;
1197 
1198  // Get the first element and iterate
1199  wxXmlNode* element = aElements->GetChildren();
1200 
1201  while( element )
1202  {
1203  checkpoint();
1204 
1205  if( element->GetName() != wxT( "element" ) )
1206  {
1207  // Get next item
1208  element = element->GetNext();
1209  continue;
1210  }
1211 
1212  EELEMENT e( element );
1213 
1214  // use "NULL-ness" as an indication of presence of the attribute:
1215  EATTR* nameAttr = nullptr;
1216  EATTR* valueAttr = nullptr;
1217 
1218  m_xpath->Value( e.name.c_str() );
1219 
1220  wxString pkg_key = makeKey( e.library, e.package );
1221 
1222  FOOTPRINT_MAP::const_iterator it = m_templates.find( pkg_key );
1223 
1224  if( it == m_templates.end() )
1225  {
1226  wxString emsg = wxString::Format( _( "No '%s' package in library '%s'." ),
1227  FROM_UTF8( e.package.c_str() ),
1228  FROM_UTF8( e.library.c_str() ) );
1229  THROW_IO_ERROR( emsg );
1230  }
1231 
1232  FOOTPRINT* footprint = static_cast<FOOTPRINT*>( it->second->Duplicate() );
1233 
1234  m_board->Add( footprint, ADD_MODE::APPEND );
1235 
1236  // update the nets within the pads of the clone
1237  for( PAD* pad : footprint->Pads() )
1238  {
1239  wxString pn_key = makeKey( e.name, pad->GetNumber() );
1240 
1241  NET_MAP_CITER ni = m_pads_to_nets.find( pn_key );
1242  if( ni != m_pads_to_nets.end() )
1243  {
1244  const ENET* enet = &ni->second;
1245  pad->SetNetCode( enet->netcode );
1246  }
1247  }
1248 
1249  refanceNamePresetInPackageLayout = true;
1250  valueNamePresetInPackageLayout = true;
1251  footprint->SetPosition( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
1252 
1253  // Is >NAME field set in package layout ?
1254  if( footprint->GetReference().size() == 0 )
1255  {
1256  footprint->Reference().SetVisible( false ); // No so no show
1257  refanceNamePresetInPackageLayout = false;
1258  }
1259 
1260  // Is >VALUE field set in package layout
1261  if( footprint->GetValue().size() == 0 )
1262  {
1263  footprint->Value().SetVisible( false ); // No so no show
1264  valueNamePresetInPackageLayout = false;
1265  }
1266 
1267  wxString reference = e.name;
1268 
1269  // EAGLE allows references to be single digits. This breaks KiCad
1270  // netlisting, which requires parts to have non-digit + digit
1271  // annotation. If the reference begins with a number, we prepend
1272  // 'UNK' (unknown) for the symbol designator.
1273  if( reference.find_first_not_of( "0123456789" ) != 0 )
1274  reference.Prepend( "UNK" );
1275 
1276  // EAGLE allows designator to start with # but that is used in KiCad
1277  // for symbols which do not have a footprint
1278  if( reference.find_first_not_of( "#" ) != 0 )
1279  reference.Prepend( "UNK" );
1280 
1281  // reference must end with a number but EAGLE does not enforce this
1282  if( reference.find_last_not_of( "0123456789" ) == (reference.Length()-1) )
1283  reference.Append( "0" );
1284 
1285  footprint->SetReference( reference );
1286  footprint->SetValue( FROM_UTF8( e.value.c_str() ) );
1287 
1288  if( !e.smashed )
1289  {
1290  // Not smashed so show NAME & VALUE
1291  if( valueNamePresetInPackageLayout )
1292  footprint->Value().SetVisible( true ); // Only if place holder in package layout
1293 
1294  if( refanceNamePresetInPackageLayout )
1295  footprint->Reference().SetVisible( true ); // Only if place holder in package layout
1296  }
1297  else if( *e.smashed == true )
1298  {
1299  // Smashed so set default to no show for NAME and VALUE
1300  footprint->Value().SetVisible( false );
1301  footprint->Reference().SetVisible( false );
1302 
1303  // initialize these to default values in case the <attribute> elements are not present.
1304  m_xpath->push( "attribute", "name" );
1305 
1306  // VALUE and NAME can have something like our text "effects" overrides
1307  // in SWEET and new schematic. Eagle calls these XML elements "attribute".
1308  // There can be one for NAME and/or VALUE both. Features present in the
1309  // EATTR override the ones established in the package only if they are
1310  // present here (except for rot, which if not present means angle zero).
1311  // So the logic is a bit different than in packageText() and in plain text.
1312 
1313  // Get the first attribute and iterate
1314  wxXmlNode* attribute = element->GetChildren();
1315 
1316  while( attribute )
1317  {
1318  if( attribute->GetName() != wxT( "attribute" ) )
1319  {
1320  attribute = attribute->GetNext();
1321  continue;
1322  }
1323 
1324  EATTR a( attribute );
1325 
1326  if( a.name == wxT( "NAME" ) )
1327  {
1328  name = a;
1329  nameAttr = &name;
1330 
1331  // do we have a display attribute ?
1332  if( a.display )
1333  {
1334  // Yes!
1335  switch( *a.display )
1336  {
1337  case EATTR::VALUE :
1338  {
1339  nameAttr->name = reference;
1340 
1341  if( refanceNamePresetInPackageLayout )
1342  footprint->Reference().SetVisible( true );
1343 
1344  break;
1345  }
1346 
1347  case EATTR::NAME :
1348  if( refanceNamePresetInPackageLayout )
1349  {
1350  footprint->SetReference( "NAME" );
1351  footprint->Reference().SetVisible( true );
1352  }
1353 
1354  break;
1355 
1356  case EATTR::BOTH :
1357  if( refanceNamePresetInPackageLayout )
1358  footprint->Reference().SetVisible( true );
1359 
1360  nameAttr->name = nameAttr->name + wxT( " = " ) + e.name;
1361  footprint->SetReference( wxT( "NAME = " ) + e.name );
1362  break;
1363 
1364  case EATTR::Off :
1365  footprint->Reference().SetVisible( false );
1366  break;
1367 
1368  default:
1369  nameAttr->name = e.name;
1370 
1371  if( refanceNamePresetInPackageLayout )
1372  footprint->Reference().SetVisible( true );
1373  }
1374  }
1375  else
1376  {
1377  // No display, so default is visible, and show value of NAME
1378  footprint->Reference().SetVisible( true );
1379  }
1380  }
1381  else if( a.name == wxT( "VALUE" ) )
1382  {
1383  value = a;
1384  valueAttr = &value;
1385 
1386  if( a.display )
1387  {
1388  // Yes!
1389  switch( *a.display )
1390  {
1391  case EATTR::VALUE :
1392  valueAttr->value = opt_wxString( e.value );
1393  footprint->SetValue( e.value );
1394 
1395  if( valueNamePresetInPackageLayout )
1396  footprint->Value().SetVisible( true );
1397 
1398  break;
1399 
1400  case EATTR::NAME :
1401  if( valueNamePresetInPackageLayout )
1402  footprint->Value().SetVisible( true );
1403 
1404  footprint->SetValue( wxT( "VALUE" ) );
1405  break;
1406 
1407  case EATTR::BOTH :
1408  if( valueNamePresetInPackageLayout )
1409  footprint->Value().SetVisible( true );
1410 
1411  valueAttr->value = opt_wxString( wxT( "VALUE = " ) + e.value );
1412  footprint->SetValue( wxT( "VALUE = " ) + e.value );
1413  break;
1414 
1415  case EATTR::Off :
1416  footprint->Value().SetVisible( false );
1417  break;
1418 
1419  default:
1420  valueAttr->value = opt_wxString( e.value );
1421 
1422  if( valueNamePresetInPackageLayout )
1423  footprint->Value().SetVisible( true );
1424  }
1425  }
1426  else
1427  {
1428  // No display, so default is visible, and show value of NAME
1429  footprint->Value().SetVisible( true );
1430  }
1431 
1432  }
1433 
1434  attribute = attribute->GetNext();
1435  }
1436 
1437  m_xpath->pop(); // "attribute"
1438  }
1439 
1440  orientFootprintAndText( footprint, e, nameAttr, valueAttr );
1441 
1442  // Set the local coordinates for the footprint text items
1443  footprint->Reference().SetLocalCoord();
1444  footprint->Value().SetLocalCoord();
1445 
1446  // Get next element
1447  element = element->GetNext();
1448  }
1449 
1450  m_xpath->pop(); // "elements.element"
1451 }
void SetReference(const wxString &aReference)
Definition: footprint.h:475
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
const wxString & GetValue() const
Definition: footprint.h:488
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
Eagle element element.
Definition: eagle_parser.h:810
NET_MAP::const_iterator NET_MAP_CITER
Definition: eagle_plugin.h:46
FOOTPRINT_MAP m_templates
is part of a FOOTPRINT factory that operates using copy construction.
Definition: eagle_plugin.h:302
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
PADS & Pads()
Definition: footprint.h:169
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:502
OPTIONAL_XML_ATTRIBUTE< wxString > opt_wxString
Definition: eagle_parser.h:365
FP_TEXT & Reference()
Definition: footprint.h:503
wxString name
Definition: eagle_parser.h:596
virtual void SetVisible(bool aVisible)
Definition: eda_text.h:206
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
static wxString makeKey(const wxString &aFirst, const wxString &aSecond)
Assemble a two part key as a simple concatenation of aFirst and aSecond parts, using a separator.
const wxString & GetReference() const
Definition: footprint.h:466
#define _(s)
void orientFootprintAndText(FOOTPRINT *aFootprint, const EELEMENT &e, const EATTR *aNameAttr, const EATTR *aValueAttr)
opt_wxString value
Definition: eagle_parser.h:597
void SetValue(const wxString &aValue)
Definition: footprint.h:496
Eagle net.
Definition: eagle_parser.h:453
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Parse an Eagle "attribute" XML element.
Definition: eagle_parser.h:594
int netcode
Definition: eagle_parser.h:455
const char * name
Definition: DXF_plotter.cpp:56
void SetLocalCoord()
Definition: fp_text.cpp:209
NET_MAP m_pads_to_nets
net list
Definition: eagle_plugin.h:300
void pop()
Definition: eagle_parser.h:122
Definition: pad.h:57
void SetPosition(const wxPoint &aPos) override
Definition: footprint.cpp:1562
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:125

References _, BOARD::Add(), APPEND, EATTR::BOTH, checkpoint(), EATTR::display, Format(), FROM_UTF8(), FOOTPRINT::GetReference(), FOOTPRINT::GetValue(), kicad_x(), kicad_y(), EELEMENT::library, m_board, m_pads_to_nets, m_templates, m_xpath, makeKey(), name, EATTR::name, EATTR::NAME, EELEMENT::name, ENET::netcode, EATTR::Off, orientFootprintAndText(), EELEMENT::package, pad, FOOTPRINT::Pads(), XPATH::pop(), XPATH::push(), FOOTPRINT::Reference(), FP_TEXT::SetLocalCoord(), FOOTPRINT::SetPosition(), FOOTPRINT::SetReference(), FOOTPRINT::SetValue(), EDA_TEXT::SetVisible(), EELEMENT::smashed, THROW_IO_ERROR, XPATH::Value(), FOOTPRINT::Value(), EATTR::value, EATTR::VALUE, EELEMENT::value, EELEMENT::x, and EELEMENT::y.

Referenced by loadAllSections().

◆ loadLayerDefs()

void EAGLE_PLUGIN::loadLayerDefs ( wxXmlNode *  aLayers)
private

Definition at line 607 of file eagle_plugin.cpp.

608 {
609  if( !aLayers )
610  return;
611 
612  ELAYERS cu; // copper layers
613 
614  // Get the first layer and iterate
615  wxXmlNode* layerNode = aLayers->GetChildren();
616 
617  m_eagleLayers.clear();
618  m_eagleLayersIds.clear();
619 
620  while( layerNode )
621  {
622  ELAYER elayer( layerNode );
623  m_eagleLayers.insert( std::make_pair( elayer.number, elayer ) );
624  m_eagleLayersIds.insert( std::make_pair( elayer.name, elayer.number ) );
625 
626  // find the subset of layers that are copper and active
627  if( elayer.number >= 1 && elayer.number <= 16 && ( !elayer.active || *elayer.active ) )
628  cu.push_back( elayer );
629 
630  layerNode = layerNode->GetNext();
631  }
632 
633  // establish cu layer map:
634  int ki_layer_count = 0;
635 
636  for( EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
637  {
638  if( ki_layer_count == 0 )
639  {
640  m_cu_map[it->number] = F_Cu;
641  }
642  else if( ki_layer_count == int( cu.size()-1 ) )
643  {
644  m_cu_map[it->number] = B_Cu;
645  }
646  else
647  {
648  // some eagle boards do not have contiguous layer number sequences.
649  m_cu_map[it->number] = ki_layer_count;
650  }
651  }
652 
653  // Set the layer names and cu count if we're loading a board.
654  if( m_board )
655  {
656  m_board->SetCopperLayerCount( cu.size() );
657 
658  for( EITER it = cu.begin(); it != cu.end(); ++it )
659  {
660  PCB_LAYER_ID layer = kicad_layer( it->number );
661 
662  // these function provide their own protection against non enabled layers:
663  if( layer >= 0 && layer < PCB_LAYER_ID_COUNT ) // layer should be valid
664  {
665  m_board->SetLayerName( layer, FROM_UTF8( it->name.c_str() ) );
666  m_board->SetLayerType( layer, LT_SIGNAL );
667  }
668 
669  // could map the colors here
670  }
671  }
672 }
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void SetCopperLayerCount(int aCount)
Definition: board.cpp:461
std::map< wxString, int > m_eagleLayersIds
Eagle layer ids stored by layer name.
Definition: eagle_plugin.h:288
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
Definition: board.cpp:410
int m_cu_map[17]
map eagle to KiCad, cu layers only.
Definition: eagle_plugin.h:286
std::map< int, ELAYER > m_eagleLayers
Eagle layer data stored by layer number.
Definition: eagle_plugin.h:287
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition: board.cpp:378
std::vector< ELAYER > ELAYERS
Definition: eagle_plugin.h:283
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
Definition: layer_ids.h:71
ELAYERS::const_iterator EITER
Definition: eagle_plugin.h:284

References ELAYER::active, B_Cu, F_Cu, FROM_UTF8(), kicad_layer(), LT_SIGNAL, m_board, m_cu_map, m_eagleLayers, m_eagleLayersIds, ELAYER::name, ELAYER::number, PCB_LAYER_ID_COUNT, BOARD::SetCopperLayerCount(), BOARD::SetLayerName(), and BOARD::SetLayerType().

Referenced by cacheLib(), and loadAllSections().

◆ loadLibraries()

void EAGLE_PLUGIN::loadLibraries ( wxXmlNode *  aLibs)
private

Definition at line 1163 of file eagle_plugin.cpp.

1164 {
1165  if( !aLibs )
1166  return;
1167 
1168  m_xpath->push( "libraries.library", "name" );
1169 
1170  // Get the first library and iterate
1171  wxXmlNode* library = aLibs->GetChildren();
1172 
1173  while( library )
1174  {
1175  const wxString& lib_name = library->GetAttribute( "name" );
1176 
1177  m_xpath->Value( lib_name.c_str() );
1178  loadLibrary( library, &lib_name );
1179  library = library->GetNext();
1180  }
1181 
1182  m_xpath->pop();
1183 }
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
void loadLibrary(wxXmlNode *aLib, const wxString *aLibName)
Load the Eagle "library" XML element, which can occur either under a "libraries" element (if a *....
void pop()
Definition: eagle_parser.h:122
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:125

References library, loadLibrary(), m_xpath, XPATH::pop(), XPATH::push(), and XPATH::Value().

Referenced by loadAllSections().

◆ loadLibrary()

void EAGLE_PLUGIN::loadLibrary ( wxXmlNode *  aLib,
const wxString *  aLibName 
)
private

Load the Eagle "library" XML element, which can occur either under a "libraries" element (if a *.brd file) or under a "drawing" element if a *.lbr file.

Parameters
aLibis the portion of the loaded XML document tree that is the "library" element.
aLibNameis a pointer to the library name or NULL. If NULL this means we are loading a *.lbr not a *.brd file and the key used in m_templates is to exclude the library name.

Definition at line 1105 of file eagle_plugin.cpp.

1106 {
1107  if( !aLib )
1108  return;
1109 
1110  // library will have <xmlattr> node, skip that and get the single packages node
1111  wxXmlNode* packages = MapChildren( aLib )["packages"];
1112 
1113  if( !packages )
1114  return;
1115 
1116  m_xpath->push( "packages" );
1117 
1118  // Create a FOOTPRINT for all the eagle packages, for use later via a copy constructor
1119  // to instantiate needed footprints in our BOARD. Save the FOOTPRINT templates in
1120  // a FOOTPRINT_MAP using a single lookup key consisting of libname+pkgname.
1121 
1122  // Get the first package and iterate
1123  wxXmlNode* package = packages->GetChildren();
1124 
1125  while( package )
1126  {
1127  checkpoint();
1128 
1129  m_xpath->push( "package", "name" );
1130 
1131  wxString pack_ref = package->GetAttribute( "name" );
1132  ReplaceIllegalFileNameChars( pack_ref, '_' );
1133 
1134  m_xpath->Value( pack_ref.ToUTF8() );
1135 
1136  wxString key = aLibName ? makeKey( *aLibName, pack_ref ) : pack_ref;
1137 
1138  FOOTPRINT* m = makeFootprint( package, pack_ref );
1139 
1140  // add the templating FOOTPRINT to the FOOTPRINT template factory "m_templates"
1141  std::pair<FOOTPRINT_MAP::iterator, bool> r = m_templates.insert( {key, m} );
1142 
1143  if( !r.second /* && !( m_props && m_props->Value( "ignore_duplicates" ) ) */ )
1144  {
1145  wxString lib = aLibName ? *aLibName : m_lib_path;
1146  const wxString& pkg = pack_ref;
1147 
1148  wxString emsg = wxString::Format( _( "<package> '%s' duplicated in <library> '%s'" ),
1149  pkg,
1150  lib );
1151  THROW_IO_ERROR( emsg );
1152  }
1153 
1154  m_xpath->pop();
1155 
1156  package = package->GetNext();
1157  }
1158 
1159  m_xpath->pop(); // "packages"
1160 }
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
FOOTPRINT_MAP m_templates
is part of a FOOTPRINT factory that operates using copy construction.
Definition: eagle_plugin.h:302
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
static wxString makeKey(const wxString &aFirst, const wxString &aSecond)
Assemble a two part key as a simple concatenation of aFirst and aSecond parts, using a separator.
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
wxString m_lib_path
Definition: eagle_plugin.h:320
FOOTPRINT * makeFootprint(wxXmlNode *aPackage, const wxString &aPkgName)
Create a FOOTPRINT from an Eagle package.
#define _(s)
E_SERIE r
Definition: eserie.cpp:41
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void pop()
Definition: eagle_parser.h:122
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:125

References _, checkpoint(), Format(), m_lib_path, m_templates, m_xpath, makeFootprint(), makeKey(), MapChildren(), XPATH::pop(), XPATH::push(), r, ReplaceIllegalFileNameChars(), THROW_IO_ERROR, and XPATH::Value().

Referenced by cacheLib(), and loadLibraries().

◆ loadPlain()

void EAGLE_PLUGIN::loadPlain ( wxXmlNode *  aPlain)
private

Definition at line 678 of file eagle_plugin.cpp.

679 {
680  if( !aGraphics )
681  return;
682 
683  m_xpath->push( "plain" );
684 
685  // Get the first graphic and iterate
686  wxXmlNode* gr = aGraphics->GetChildren();
687 
688  // (polygon | wire | text | circle | rectangle | frame | hole)*
689  while( gr )
690  {
691  checkpoint();
692 
693  wxString grName = gr->GetName();
694 
695  if( grName == wxT( "wire" ) )
696  {
697  m_xpath->push( "wire" );
698 
699  EWIRE w( gr );
700  PCB_LAYER_ID layer = kicad_layer( w.layer );
701 
702  wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
703  wxPoint end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
704 
705  if( layer != UNDEFINED_LAYER )
706  {
707  PCB_SHAPE* shape = new PCB_SHAPE( m_board );
708  int width = w.width.ToPcbUnits();
709 
710  // KiCad cannot handle zero or negative line widths
711  if( width <= 0 )
712  width = m_board->GetDesignSettings().GetLineThickness( layer );
713 
714  m_board->Add( shape, ADD_MODE::APPEND );
715 
716  if( !w.curve )
717  {
718  shape->SetShape( SHAPE_T::SEGMENT );
719  shape->SetStart( start );
720  shape->SetEnd( end );
721  }
722  else
723  {
724  wxPoint center = ConvertArcCenter( start, end, *w.curve );
725 
726  shape->SetShape( SHAPE_T::ARC );
727  shape->SetCenter( center );
728  shape->SetStart( start );
729  shape->SetArcAngleAndEnd( *w.curve * -10.0, true ); // KiCad rotates the other way
730  }
731 
732  shape->SetLayer( layer );
733  shape->SetWidth( width );
734  }
735 
736  m_xpath->pop();
737  }
738  else if( grName == wxT( "text" ) )
739  {
740  m_xpath->push( "text" );
741 
742  ETEXT t( gr );
743  PCB_LAYER_ID layer = kicad_layer( t.layer );
744 
745  if( layer != UNDEFINED_LAYER )
746  {
747  PCB_TEXT* pcbtxt = new PCB_TEXT( m_board );
748  m_board->Add( pcbtxt, ADD_MODE::APPEND );
749 
750  pcbtxt->SetLayer( layer );
751  wxString kicadText = interpret_text( t.text );
752  pcbtxt->SetText( FROM_UTF8( kicadText.c_str() ) );
753  pcbtxt->SetTextPos( wxPoint( kicad_x( t.x ), kicad_y( t.y ) ) );
754 
755  double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
756  int textThickness = KiROUND( t.size.ToPcbUnits() * ratio / 100 );
757  pcbtxt->SetTextThickness( textThickness );
758  pcbtxt->SetTextSize( kicad_fontz( t.size, textThickness ) );
759 
760  int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;
761 
762  if( t.rot )
763  {
764  int sign = t.rot->mirror ? -1 : 1;
765  pcbtxt->SetMirrored( t.rot->mirror );
766 
767  double degrees = t.rot->degrees;
768 
769  if( degrees == 90 || t.rot->spin )
770  {
771  pcbtxt->SetTextAngle( sign * t.rot->degrees * 10 );
772  }
773  else if( degrees == 180 )
774  {
775  align = -align;
776  }
777  else if( degrees == 270 )
778  {
779  pcbtxt->SetTextAngle( sign * 90 * 10 );
780  align = -align;
781  }
782  else
783  {
784  // Ok so text is not at 90,180 or 270 so do some funny stuff to get
785  // placement right.
786  if( ( degrees > 0 ) && ( degrees < 90 ) )
787  {
788  pcbtxt->SetTextAngle( sign * t.rot->degrees * 10 );
789  }
790  else if( ( degrees > 90 ) && ( degrees < 180 ) )
791  {
792  pcbtxt->SetTextAngle( sign * ( t.rot->degrees + 180 ) * 10 );
793  align = ETEXT::TOP_RIGHT;
794  }
795  else if( ( degrees > 180 ) && ( degrees < 270 ) )
796  {
797  pcbtxt->SetTextAngle( sign * ( t.rot->degrees - 180 ) * 10 );
798  align = ETEXT::TOP_RIGHT;
799  }
800  else if( ( degrees > 270 ) && ( degrees < 360 ) )
801  {
802  pcbtxt->SetTextAngle( sign * t.rot->degrees * 10 );
803  align = ETEXT::BOTTOM_LEFT;
804  }
805  }
806  }
807 
808  switch( align )
809  {
810  case ETEXT::CENTER:
813  break;
814 
815  case ETEXT::CENTER_LEFT:
818  break;
819 
820  case ETEXT::CENTER_RIGHT:
823  break;
824 
825  case ETEXT::TOP_CENTER:
828  break;
829 
830  case ETEXT::TOP_LEFT:
833  break;
834 
835  case ETEXT::TOP_RIGHT:
838  break;
839 
843  break;
844 
845  case ETEXT::BOTTOM_LEFT:
848  break;
849 
850  case ETEXT::BOTTOM_RIGHT:
853  break;
854  }
855  }
856 
857  m_xpath->pop();
858  }
859  else if( grName == wxT( "circle" ) )
860  {
861  m_xpath->push( "circle" );
862 
863  ECIRCLE c( gr );
864 
865  int width = c.width.ToPcbUnits();
866  int radius = c.radius.ToPcbUnits();
867 
868  if( c.layer == EAGLE_LAYER::TRESTRICT || c.layer == EAGLE_LAYER::BRESTRICT
869  || c.layer == EAGLE_LAYER::VRESTRICT )
870  {
871  ZONE* zone = new ZONE( m_board );
872  m_board->Add( zone, ADD_MODE::APPEND );
873 
874  setKeepoutSettingsToZone( zone, c.layer );
875 
876  // approximate circle as polygon with a edge every 10 degree
877  wxPoint center( kicad_x( c.x ), kicad_y( c.y ) );
878  int outlineRadius = radius + ( width / 2 );
879 
880  for( int angle = 0; angle < 360; angle += 10 )
881  {
882  wxPoint rotatedPoint( outlineRadius, 0 );
883  RotatePoint( &rotatedPoint, angle * 10. );
884  zone->AppendCorner( center + rotatedPoint, -1 );
885  }
886 
887  if( width > 0 )
888  {
889  zone->NewHole();
890  int innerRadius = radius - ( width / 2 );
891 
892  for( int angle = 0; angle < 360; angle += 10 )
893  {
894  wxPoint rotatedPoint( innerRadius, 0 );
895  RotatePoint( &rotatedPoint, angle * 10. );
896  zone->AppendCorner( center + rotatedPoint, 0 );
897  }
898  }
899 
901  ZONE::GetDefaultHatchPitch(), true );
902  }
903  else
904  {
905  PCB_LAYER_ID layer = kicad_layer( c.layer );
906 
907  if( layer != UNDEFINED_LAYER ) // unsupported layer
908  {
909  PCB_SHAPE* shape = new PCB_SHAPE( m_board, SHAPE_T::CIRCLE );
910  m_board->Add( shape, ADD_MODE::APPEND );
911  shape->SetFilled( false );
912  shape->SetLayer( layer );
913  shape->SetStart( wxPoint( kicad_x( c.x ), kicad_y( c.y ) ) );
914  shape->SetEnd( wxPoint( kicad_x( c.x ) + radius, kicad_y( c.y ) ) );
915  shape->SetWidth( width );
916  }
917  }
918 
919  m_xpath->pop();
920  }
921  else if( grName == wxT( "rectangle" ) )
922  {
923  // This seems to be a simplified rectangular [copper] zone, cannot find any
924  // net related info on it from the DTD.
925  m_xpath->push( "rectangle" );
926 
927  ERECT r( gr );
928  PCB_LAYER_ID layer = kicad_layer( r.layer );
929 
930  if( IsCopperLayer( layer ) )
931  {
932  // use a "netcode = 0" type ZONE:
933  ZONE* zone = new ZONE( m_board );
934  m_board->Add( zone, ADD_MODE::APPEND );
935 
936  zone->SetLayer( layer );
938 
940 
941  const int outlineIdx = -1; // this is the id of the copper zone main outline
942  zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ), outlineIdx );
943  zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ), outlineIdx );
944  zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ), outlineIdx );
945  zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ), outlineIdx );
946 
947  if( r.rot )
948  zone->Rotate( zone->GetPosition(), r.rot->degrees * 10 );
949 
950  // this is not my fault:
951  zone->SetBorderDisplayStyle( outline_hatch, ZONE::GetDefaultHatchPitch(),
952  true );
953  }
954 
955  m_xpath->pop();
956  }
957  else if( grName == wxT( "hole" ) )
958  {
959  m_xpath->push( "hole" );
960 
961  // Fabricate a FOOTPRINT with a single PAD_ATTRIB::NPTH pad.
962  // Use m_hole_count to gen up a unique name.
963 
964  FOOTPRINT* footprint = new FOOTPRINT( m_board );
965  m_board->Add( footprint, ADD_MODE::APPEND );
966  footprint->SetReference( wxString::Format( wxT( "@HOLE%d" ), m_hole_count++ ) );
967  footprint->Reference().SetVisible( false );
968 
969  packageHole( footprint, gr, true );
970 
971  m_xpath->pop();
972  }
973  else if( grName == wxT( "frame" ) )
974  {
975  // picture this
976  }
977  else if( grName == wxT( "polygon" ) )
978  {
979  m_xpath->push( "polygon" );
980  loadPolygon( gr );
981  m_xpath->pop(); // "polygon"
982  }
983  else if( grName == wxT( "dimension" ) )
984  {
985  const BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
986 
987  EDIMENSION d( gr );
988  PCB_LAYER_ID layer = kicad_layer( d.layer );
989  VECTOR2I pt1( kicad_x( d.x1 ), kicad_y( d.y1 ) );
990  VECTOR2I pt2( kicad_x( d.x2 ), kicad_y( d.y2 ) );
991  VECTOR2I pt3( kicad_x( d.x3 ), kicad_y( d.y3 ) );
992  wxSize textSize = designSettings.GetTextSize( layer );
993  int textThickness = designSettings.GetLineThickness( layer );
994 
995  if( d.textsize )
996  {
997  double ratio = 8; // DTD says 8 is default
998  textThickness = KiROUND( d.textsize->ToPcbUnits() * ratio / 100 );
999  textSize = kicad_fontz( *d.textsize, textThickness );
1000  }
1001 
1002  if( layer != UNDEFINED_LAYER )
1003  {
1004  if( d.dimensionType == wxT( "angle" ) )
1005  {
1006  // Kicad doesn't (at present) support angle dimensions
1007  }
1008  else if( d.dimensionType == wxT( "radius" ) )
1009  {
1010  // Radial dimensions added in 7.0....
1011  }
1012  else if( d.dimensionType == wxT( "leader" ) )
1013  {
1014  PCB_DIM_LEADER* leader = new PCB_DIM_LEADER( m_board );
1015  m_board->Add( leader, ADD_MODE::APPEND );
1016 
1017  leader->SetLayer( layer );
1018  leader->SetPrecision( DIMENSION_PRECISION );
1019 
1020  leader->SetStart( (wxPoint) pt1 );
1021  leader->SetEnd( (wxPoint) pt2 );
1022  leader->Text().SetPosition( (wxPoint) pt3 );
1023  leader->Text().SetTextSize( textSize );
1024  leader->Text().SetTextThickness( textThickness );
1025  leader->SetLineThickness( designSettings.GetLineThickness( layer ) );
1026  }
1027  else // horizontal, vertical, <default>, diameter
1028  {
1029  PCB_DIM_ALIGNED* dimension = new PCB_DIM_ALIGNED( m_board );
1030  m_board->Add( dimension, ADD_MODE::APPEND );
1031 
1032  if( d.dimensionType )
1033  {
1034  // Eagle dimension graphic arms may have different lengths, but they look
1035  // incorrect in KiCad (the graphic is tilted). Make them even length in
1036  // such case.
1037  if( *d.dimensionType == wxT( "horizontal" ) )
1038  {
1039  int newY = ( pt1.y + pt2.y ) / 2;
1040  pt1.y = newY;
1041  pt2.y = newY;
1042  }
1043  else if( *d.dimensionType == wxT( "vertical" ) )
1044  {
1045  int newX = ( pt1.x + pt2.x ) / 2;
1046  pt1.x = newX;
1047  pt2.x = newX;
1048  }
1049  }
1050 
1051  dimension->SetLayer( layer );
1052  dimension->SetPrecision( DIMENSION_PRECISION );
1053 
1054  // The origin and end are assumed to always be in this order from eagle
1055  dimension->SetStart( (wxPoint) pt1 );
1056  dimension->SetEnd( (wxPoint) pt2 );
1057  dimension->Text().SetTextSize( textSize );
1058  dimension->Text().SetTextThickness( textThickness );
1059  dimension->SetLineThickness( designSettings.GetLineThickness( layer ) );
1060  dimension->SetUnits( EDA_UNITS::MILLIMETRES );
1061 
1062  // check which axis the dimension runs in
1063  // because the "height" of the dimension is perpendicular to that axis
1064  // Note the check is just if two axes are close enough to each other
1065  // Eagle appears to have some rounding errors
1066  if( abs( pt1.x - pt2.x ) < 50000 ) // 50000 nm = 0.05 mm
1067  {
1068  int offset = pt3.x - pt1.x;
1069 
1070  if( pt1.y > pt2.y )
1071  dimension->SetHeight( offset );
1072  else
1073  dimension->SetHeight( -offset );
1074  }
1075  else if( abs( pt1.y - pt2.y ) < 50000 )
1076  {
1077  int offset = pt3.y - pt1.y;
1078 
1079  if( pt1.x > pt2.x )
1080  dimension->SetHeight( -offset );
1081  else
1082  dimension->SetHeight( offset );
1083  }
1084  else
1085  {
1086  int offset = GetLineLength( (wxPoint) pt3, (wxPoint) pt1 );
1087 
1088  if( pt1.y > pt2.y )
1089  dimension->SetHeight( offset );
1090  else
1091  dimension->SetHeight( -offset );
1092  }
1093  }
1094  }
1095  }
1096 
1097  // Get next graphic
1098  gr = gr->GetNext();
1099  }
1100 
1101  m_xpath->pop();
1102 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:209
void SetReference(const wxString &aReference)
Definition: footprint.h:475
int sign(T val)
Definition: util.h:104
void SetUnits(EDA_UNITS aUnits)
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:222
void packageHole(FOOTPRINT *aFootprint, wxXmlNode *aTree, bool aCenter) const
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void SetFilled(bool aFlag)
Definition: eda_shape.h:92
void SetEnd(const wxPoint &aEnd)
Definition: eda_shape.h:135
virtual void SetPosition(const wxPoint &aPos) override
Definition: pcb_text.h:81
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:875
void SetTextAngle(double aAngle) override
Definition: pcb_text.cpp:104
PCB_TEXT & Text()
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:267
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
void SetArcAngleAndEnd(double aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
Definition: eda_shape.cpp:547
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
Eagle text element.
Definition: eagle_parser.h:637
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
void SetLineThickness(int aWidth)
For better understanding of the points that make a dimension:
FP_TEXT & Reference()
Definition: footprint.h:503
void SetStart(const wxPoint &aStart)
Definition: eda_shape.h:110
void Rotate(const wxPoint &aCentre, double aAngle) override
Move the outlines.
Definition: zone.cpp:689
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
virtual void SetVisible(bool aVisible)
Definition: eda_text.h:206
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
void NewHole()
Create a new hole on the zone; i.e., a new contour on the zone's outline.
Definition: zone.h:599
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
static int GetDefaultHatchPitch()
Definition: zone.cpp:1038
virtual void SetEnd(const wxPoint &aPoint)
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:223
Eagle circle.
Definition: eagle_parser.h:562
void SetWidth(int aWidth)
Definition: eda_shape.h:97
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
void SetPrecision(int aPrecision)
void SetCenter(const wxPoint &aCenter)
Definition: eda_shape.cpp:419
E_SERIE r
Definition: eserie.cpp:41
int m_hole_count
generates unique footprint names from eagle "hole"s.
Definition: eagle_plugin.h:298
Eagle XML rectangle in binary.
Definition: eagle_parser.h:575
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:808
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
static wxString interpret_text(const wxString &aText)
interpret special characters in Eagle text and converts them to KiCAD notation
wxSize kicad_fontz(const ECOORD &d, int aTextThickness) const
create a font size (fontz) from an eagle font size scalar and KiCad font thickness
bool AppendCorner(wxPoint aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition: zone.cpp:815
wxPoint GetPosition() const override
Definition: zone.cpp:216
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:222
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define DIMENSION_PRECISION
virtual void SetStart(const wxPoint &aPoint)
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:100
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
static void setKeepoutSettingsToZone(ZONE *aZone, LAYER_NUM aLayer)
Eagle wire.
Definition: eagle_parser.h:491
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
Definition: zone_settings.h:46
A leader is a dimension-like object pointing to a specific point.
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:242
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:180
Eagle dimension element.
Definition: eagle_parser.h:620
void pop()
Definition: eagle_parser.h:122
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:372
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188
ZONE * loadPolygon(wxXmlNode *aPolyNode)
Load a copper or keepout polygon and adds it to the board.
Container for design settings for a BOARD object.

References BOARD::Add(), ETEXT::align, PNS::angle(), APPEND, ZONE::AppendCorner(), ARC, ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, EAGLE_LAYER::BRESTRICT, ETEXT::CENTER, ETEXT::CENTER_LEFT, ETEXT::CENTER_RIGHT, checkpoint(), CIRCLE, ConvertArcCenter(), EWIRE::curve, EROT::degrees, DIAGONAL_EDGE, DIMENSION_PRECISION, EDIMENSION::dimensionType, Format(), FROM_UTF8(), ZONE::GetDefaultHatchPitch(), BOARD::GetDesignSettings(), GetLineLength(), BOARD_DESIGN_SETTINGS::GetLineThickness(), ZONE::GetPosition(), BOARD_DESIGN_SETTINGS::GetTextSize(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP, interpret_text(), IsCopperLayer(), kicad_fontz(), kicad_layer(), kicad_x(), kicad_y(), KiROUND(), EWIRE::layer, ECIRCLE::layer, EDIMENSION::layer, ETEXT::layer, loadPolygon(), m_board, m_hole_count, m_xpath, MILLIMETRES, EROT::mirror, ZONE::NewHole(), packageHole(), XPATH::pop(), XPATH::push(), r, ECIRCLE::radius, ETEXT::ratio, FOOTPRINT::Reference(), ETEXT::rot, ZONE::Rotate(), RotatePoint(), SEGMENT, EDA_SHAPE::SetArcAngleAndEnd(), ZONE::SetBorderDisplayStyle(), EDA_SHAPE::SetCenter(), PCB_DIMENSION_BASE::SetEnd(), EDA_SHAPE::SetEnd(), EDA_SHAPE::SetFilled(), PCB_DIM_ALIGNED::SetHeight(), EDA_TEXT::SetHorizJustify(), setKeepoutSettingsToZone(), BOARD_ITEM::SetLayer(), ZONE::SetLayer(), PCB_DIMENSION_BASE::SetLayer(), PCB_DIMENSION_BASE::SetLineThickness(), EDA_TEXT::SetMirrored(), BOARD_CONNECTED_ITEM::SetNetCode(), PCB_TEXT::SetPosition(), PCB_DIMENSION_BASE::SetPrecision(), FOOTPRINT::SetReference(), EDA_SHAPE::SetShape(), EDA_SHAPE::SetStart(), PCB_DIMENSION_BASE::SetStart(), EDA_TEXT::SetText(), PCB_TEXT::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), PCB_DIMENSION_BASE::SetUnits(), EDA_TEXT::SetVertJustify(), EDA_TEXT::SetVisible(), EDA_SHAPE::SetWidth(), sign(), ETEXT::size, EROT::spin, PCB_DIMENSION_BASE::Text(), ETEXT::text, EDIMENSION::textsize, ETEXT::TOP_CENTER, ETEXT::TOP_LEFT, ETEXT::TOP_RIGHT, ECOORD::ToPcbUnits(), EAGLE_LAYER::TRESTRICT, NETINFO_LIST::UNCONNECTED, UNDEFINED_LAYER, EAGLE_LAYER::VRESTRICT, EWIRE::width, ECIRCLE::width, VECTOR2< T >::x, ECIRCLE::x, ETEXT::x, EWIRE::x1, EDIMENSION::x1, EWIRE::x2, EDIMENSION::x2, EDIMENSION::x3, VECTOR2< T >::y, ECIRCLE::y, ETEXT::y, EWIRE::y1, EDIMENSION::y1, EWIRE::y2, EDIMENSION::y2, and EDIMENSION::y3.

Referenced by loadAllSections().

◆ loadPolygon()

ZONE * EAGLE_PLUGIN::loadPolygon ( wxXmlNode *  aPolyNode)
private

Load a copper or keepout polygon and adds it to the board.

Returns
The loaded zone or nullptr if was not processed.

Definition at line 1454 of file eagle_plugin.cpp.

1455 {
1456  EPOLYGON p( aPolyNode );
1457  PCB_LAYER_ID layer = kicad_layer( p.layer );
1458  ZONE* zone = nullptr;
1459  bool keepout = ( p.layer == EAGLE_LAYER::TRESTRICT
1460  || p.layer == EAGLE_LAYER::BRESTRICT
1461  || p.layer == EAGLE_LAYER::VRESTRICT );
1462 
1463  if( layer == UNDEFINED_LAYER )
1464  {
1465  wxLogMessage( wxString::Format( _( "Ignoring a polygon since Eagle layer '%s' (%d) "
1466  "was not mapped" ),
1467  eagle_layer_name( p.layer ), p.layer ) );
1468  return nullptr;
1469  }
1470 
1471  if( !IsCopperLayer( layer ) && !keepout )
1472  return nullptr;
1473 
1474  // use a "netcode = 0" type ZONE:
1475  zone = new ZONE( m_board );
1476  m_board->Add( zone, ADD_MODE::APPEND );
1477 
1478  if( !keepout )
1479  zone->SetLayer( layer );
1480  else
1481  setKeepoutSettingsToZone( zone, p.layer );
1482 
1483  // Get the first vertex and iterate
1484  wxXmlNode* vertex = aPolyNode->GetChildren();
1485  std::vector<EVERTEX> vertices;
1486 
1487  // Create a circular vector of vertices
1488  // The "curve" parameter indicates a curve from the current
1489  // to the next vertex, so we keep the first at the end as well
1490  // to allow the curve to link back
1491  while( vertex )
1492  {
1493  if( vertex->GetName() == wxT( "vertex" ) )
1494  vertices.emplace_back( vertex );
1495 
1496  vertex = vertex->GetNext();
1497  }
1498 
1499  vertices.push_back( vertices[0] );
1500 
1501  SHAPE_POLY_SET polygon;
1502  polygon.NewOutline();
1503 
1504  for( size_t i = 0; i < vertices.size() - 1; i++ )
1505  {
1506  EVERTEX v1 = vertices[i];
1507 
1508  // Append the corner
1509  polygon.Append( kicad_x( v1.x ), kicad_y( v1.y ) );
1510 
1511  if( v1.curve )
1512  {
1513  EVERTEX v2 = vertices[i + 1];
1514  wxPoint center = ConvertArcCenter( wxPoint( kicad_x( v1.x ), kicad_y( v1.y ) ),
1515  wxPoint( kicad_x( v2.x ), kicad_y( v2.y ) ),
1516  *v1.curve );
1517  double angle = DEG2RAD( *v1.curve );
1518  double end_angle = atan2( kicad_y( v2.y ) - center.y, kicad_x( v2.x ) - center.x );
1519  double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
1520  + pow( center.y - kicad_y( v1.y ), 2 ) );
1521 
1522  int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, *v1.curve );
1523  double delta_angle = angle / segCount;
1524 
1525  for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle );
1526  a -= delta_angle )
1527  {
1528  polygon.Append( KiROUND( radius * cos( a ) ) + center.x,
1529  KiROUND( radius * sin( a ) ) + center.y );
1530  }
1531  }
1532  }
1533 
1534  // Eagle traces the zone such that half of the pen width is outside the polygon.
1535  // We trace the zone such that the copper is completely inside.
1536  if( p.width.ToPcbUnits() > 0 )
1537  {
1538  polygon.Inflate( p.width.ToPcbUnits() / 2, 32, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
1540  }
1541 
1542  zone->AddPolygon( polygon.COutline( 0 ) );
1543 
1544  // If the pour is a cutout it needs to be set to a keepout
1545  if( p.pour == EPOLYGON::CUTOUT )
1546  {
1547  zone->SetIsRuleArea( true );
1548  zone->SetDoNotAllowVias( false );
1549  zone->SetDoNotAllowTracks( false );
1550  zone->SetDoNotAllowPads( false );
1551  zone->SetDoNotAllowFootprints( false );
1552  zone->SetDoNotAllowCopperPour( true );
1554  }
1555  else if( p.pour == EPOLYGON::HATCH )
1556  {
1557  int spacing = p.spacing ? p.spacing->ToPcbUnits() : 50 * IU_PER_MILS;
1558 
1560  zone->SetHatchThickness( p.width.ToPcbUnits() );
1561  zone->SetHatchGap( spacing - p.width.ToPcbUnits() );
1562  zone->SetHatchOrientation( 0 );
1563  }
1564 
1565  // We divide the thickness by half because we are tracing _inside_ the zone outline
1566  // This means the radius of curvature will be twice the size for an equivalent EAGLE zone
1568  p.width.ToPcbUnits() / 2 ) );
1569 
1570  if( p.isolate )
1571  zone->SetLocalClearance( p.isolate->ToPcbUnits() );
1572  else
1573  zone->SetLocalClearance( 1 ); // @todo: set minimum clearance value based on board settings
1574 
1575  // missing == yes per DTD.
1576  bool thermals = !p.thermals || *p.thermals;
1578 
1579  if( thermals )
1580  {
1581  // FIXME: eagle calculates dimensions for thermal spokes
1582  // based on what the zone is connecting to.
1583  // (i.e. width of spoke is half of the smaller side of an smd pad)
1584  // This is a basic workaround
1585  zone->SetThermalReliefGap( p.width.ToPcbUnits() + 50000 ); // 50000nm == 0.05mm
1586  zone->SetThermalReliefSpokeWidth( p.width.ToPcbUnits() + 50000 );
1587  }
1588 
1589  int rank = p.rank ? (p.max_priority - *p.rank) : p.max_priority;
1590  zone->SetPriority( rank );
1591 
1592  return zone;
1593 }
Eagle vertex.
Definition: eagle_parser.h:759
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
void SetHatchThickness(int aThickness)
Definition: zone.h:254
VECTOR2I v2(1, 0)
Test suite for KiCad math code.
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
void SetDoNotAllowTracks(bool aEnable)
Definition: zone.h:747
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void SetHatchStyle(ZONE_BORDER_DISPLAY_STYLE aStyle)
Definition: zone.h:616
ECOORD y
Definition: eagle_parser.h:762
void SetPriority(unsigned aPriority)
Definition: zone.h:117
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
void SetFillMode(ZONE_FILL_MODE aFillMode)
Definition: zone.h:180
void SetIsRuleArea(bool aEnable)
Definition: zone.h:744
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
pads are covered by copper
void SetHatchGap(int aStep)
Definition: zone.h:257
void SetDoNotAllowPads(bool aEnable)
Definition: zone.h:748
Represent a set of closed polygons.
#define _(s)
void SetDoNotAllowVias(bool aEnable)
Definition: zone.h:746
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
void SetMinThickness(int aMinThickness)
Definition: zone.h:245
int NewOutline()
Creates a new hole in a given outline.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:808
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:763
void Inflate(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Use thermal relief for pads.
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition: zone.h:242
#define ZONE_THICKNESS_MIN_VALUE_MIL
Definition: zones.h:32
ECOORD x
Definition: eagle_parser.h:761
double DEG2RAD(double deg)
Definition: trigo.h:229
void SetDoNotAllowCopperPour(bool aEnable)
Definition: zone.h:745
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define IU_PER_MILS
Definition: plotter.cpp:130
void SetHatchOrientation(double aStep)
Definition: zone.h:260
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
static void setKeepoutSettingsToZone(ZONE *aZone, LAYER_NUM aLayer)
void SetThermalReliefGap(int aThermalReliefGap)
Definition: zone.h:183
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:242
void SetLocalClearance(int aClearance)
Definition: zone.h:158
void AddPolygon(std::vector< wxPoint > &aPolygon)
Add a polygon to the zone outline.
Definition: zone.cpp:798
Eagle polygon, without vertices which are parsed as needed.
Definition: eagle_parser.h:770
just inflate the polygon. Acute angles create spikes
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188
void SetDoNotAllowFootprints(bool aEnable)
Definition: zone.h:749
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
Definition: zone.h:194

References _, BOARD::Add(), ZONE::AddPolygon(), SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS, PNS::angle(), APPEND, SHAPE_POLY_SET::Append(), EAGLE_LAYER::BRESTRICT, ConvertArcCenter(), SHAPE_POLY_SET::COutline(), EVERTEX::curve, EPOLYGON::CUTOUT, DEG2RAD(), eagle_layer_name(), Format(), SHAPE_POLY_SET::Fracture(), FULL, GetArcToSegmentCount(), EPOLYGON::HATCH, HATCH_PATTERN, SHAPE_POLY_SET::Inflate(), IsCopperLayer(), EPOLYGON::isolate, IU_PER_MILS, kicad_layer(), kicad_x(), kicad_y(), KiROUND(), EPOLYGON::layer, m_board, EPOLYGON::max_priority, SHAPE_POLY_SET::NewOutline(), NO_HATCH, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE, EPOLYGON::pour, EPOLYGON::rank, ZONE::SetDoNotAllowCopperPour(), ZONE::SetDoNotAllowFootprints(), ZONE::SetDoNotAllowPads(), ZONE::SetDoNotAllowTracks(), ZONE::SetDoNotAllowVias(), ZONE::SetFillMode(), ZONE::SetHatchGap(), ZONE::SetHatchOrientation(), ZONE::SetHatchStyle(), ZONE::SetHatchThickness(), ZONE::SetIsRuleArea(), setKeepoutSettingsToZone(), ZONE::SetLayer(), ZONE::SetLocalClearance(), ZONE::SetMinThickness(), ZONE::SetPadConnection(), ZONE::SetPriority(), ZONE::SetThermalReliefGap(), ZONE::SetThermalReliefSpokeWidth(), EPOLYGON::spacing, THERMAL, EPOLYGON::thermals, ECOORD::ToPcbUnits(), EAGLE_LAYER::TRESTRICT, UNDEFINED_LAYER, v2, EAGLE_LAYER::VRESTRICT, EPOLYGON::width, VECTOR2< T >::x, EVERTEX::x, VECTOR2< T >::y, EVERTEX::y, and ZONE_THICKNESS_MIN_VALUE_MIL.

Referenced by loadPlain(), and loadSignals().

◆ loadSignals()

void EAGLE_PLUGIN::loadSignals ( wxXmlNode *  aSignals)
private

This is, at best, a guess. Eagle doesn't seem to differentiate between blind/buried vias that only go one layer and micro vias so the user will need to clean up a bit

Definition at line 2577 of file eagle_plugin.cpp.

2578 {
2579  ZONES zones; // per net
2580  int netCode = 1;
2581 
2582  m_xpath->push( "signals.signal", "name" );
2583 
2584  // Get the first signal and iterate
2585  wxXmlNode* net = aSignals->GetChildren();
2586 
2587  while( net )
2588  {
2589  checkpoint();
2590 
2591  bool sawPad = false;
2592 
2593  zones.clear();
2594 
2595  const wxString& netName = escapeName( net->GetAttribute( "name" ) );
2596  NETINFO_ITEM* netInfo = new NETINFO_ITEM( m_board, netName, netCode );
2597  NETCLASSPTR netclass;
2598 
2599  if( net->HasAttribute( "class" ) )
2600  {
2601  netclass = m_classMap[ net->GetAttribute( "class" ) ];
2602 
2603  netclass->Add( netName );
2604  netInfo->SetNetClass( netclass );
2605  }
2606 
2607  m_board->Add( netInfo );
2608 
2609  m_xpath->Value( netName.c_str() );
2610 
2611  // Get the first net item and iterate
2612  wxXmlNode* netItem = net->GetChildren();
2613 
2614  // (contactref | polygon | wire | via)*
2615  while( netItem )
2616  {
2617  const wxString& itemName = netItem->GetName();
2618 
2619  if( itemName == wxT( "wire" ) )
2620  {
2621  m_xpath->push( "wire" );
2622 
2623  EWIRE w( netItem );
2624  PCB_LAYER_ID layer = kicad_layer( w.layer );
2625 
2626  if( IsCopperLayer( layer ) )
2627  {
2628  wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
2629  double angle = 0.0;
2630  double end_angle = 0.0;
2631  double radius = 0.0;
2632  double delta_angle = 0.0;
2633  wxPoint center;
2634 
2635  int width = w.width.ToPcbUnits();
2636 
2637  if( width < m_min_trace )
2638  m_min_trace = width;
2639 
2640  if( netclass && width < netclass->GetTrackWidth() )
2641  netclass->SetTrackWidth( width );
2642 
2643  if( w.curve )
2644  {
2645  center = ConvertArcCenter( wxPoint( kicad_x( w.x1 ), kicad_y( w.y1 ) ),
2646  wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ),
2647  *w.curve );
2648 
2649  angle = DEG2RAD( *w.curve );
2650 
2651  end_angle = atan2( kicad_y( w.y2 ) - center.y,
2652  kicad_x( w.x2 ) - center.x );
2653 
2654  radius = sqrt( pow( center.x - kicad_x( w.x1 ), 2 ) +
2655  pow( center.y - kicad_y( w.y1 ), 2 ) );
2656 
2657  int segs = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
2658  *w.curve );
2659  delta_angle = angle / segs;
2660  }
2661 
2662  while( fabs( angle ) > fabs( delta_angle ) )
2663  {
2664  wxASSERT( radius > 0.0 );
2665  wxPoint end( KiROUND( radius * cos( end_angle + angle ) + center.x ),
2666  KiROUND( radius * sin( end_angle + angle ) + center.y ) );
2667 
2668  PCB_TRACK* t = new PCB_TRACK( m_board );
2669 
2670  t->SetPosition( start );
2671  t->SetEnd( end );
2672  t->SetWidth( width );
2673  t->SetLayer( layer );
2674  t->SetNetCode( netCode );
2675 
2676  m_board->Add( t );
2677 
2678  start = end;
2679  angle -= delta_angle;
2680  }
2681 
2682  PCB_TRACK* t = new PCB_TRACK( m_board );
2683 
2684  t->SetPosition( start );
2685  t->SetEnd( wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ) );
2686  t->SetWidth( width );
2687  t->SetLayer( layer );
2688  t->SetNetCode( netCode );
2689 
2690  m_board->Add( t );
2691  }
2692  else
2693  {
2694  // put non copper wires where the sun don't shine.
2695  }
2696 
2697  m_xpath->pop();
2698  }
2699  else if( itemName == wxT( "via" ) )
2700  {
2701  m_xpath->push( "via" );
2702  EVIA v( netItem );
2703 
2704  if( v.layer_front_most > v.layer_back_most )
2705  std::swap( v.layer_front_most, v.layer_back_most );
2706 
2707  PCB_LAYER_ID layer_front_most = kicad_layer( v.layer_front_most );
2708  PCB_LAYER_ID layer_back_most = kicad_layer( v.layer_back_most );
2709 
2710  if( IsCopperLayer( layer_front_most ) && IsCopperLayer( layer_back_most )
2711  && layer_front_most != layer_back_most )
2712  {
2713  int kidiam;
2714  int drillz = v.drill.ToPcbUnits();
2715  PCB_VIA* via = new PCB_VIA( m_board );
2716  m_board->Add( via );
2717 
2718  if( v.diam )
2719  {
2720  kidiam = v.diam->ToPcbUnits();
2721  via->SetWidth( kidiam );
2722  }
2723  else
2724  {
2725  double annulus = drillz * m_rules->rvViaOuter; // eagle "restring"
2726  annulus = eagleClamp( m_rules->rlMinViaOuter, annulus,
2728  kidiam = KiROUND( drillz + 2 * annulus );
2729  via->SetWidth( kidiam );
2730  }
2731 
2732  via->SetDrill( drillz );
2733 
2734  // make sure the via diameter respects the restring rules
2735 
2736  if( !v.diam || via->GetWidth() <= via->GetDrill() )
2737  {
2738  double annulus =
2740  (double) ( via->GetWidth() / 2 - via->GetDrill() ),
2742  via->SetWidth( drillz + 2 * annulus );
2743  }
2744 
2745  if( kidiam < m_min_via )
2746  m_min_via = kidiam;
2747 
2748  if( netclass && kidiam < netclass->GetViaDiameter() )
2749  netclass->SetViaDiameter( kidiam );
2750 
2751  if( drillz < m_min_hole )
2752  m_min_hole = drillz;
2753 
2754  if( netclass && drillz < netclass->GetViaDrill() )
2755  netclass->SetViaDrill( drillz );
2756 
2757  if( ( kidiam - drillz ) / 2 < m_min_annulus )
2758  m_min_annulus = ( kidiam - drillz ) / 2;
2759 
2760  if( layer_front_most == F_Cu && layer_back_most == B_Cu )
2761  {
2762  via->SetViaType( VIATYPE::THROUGH );
2763  }
2767  else if( v.layer_back_most - v.layer_front_most == 1 )
2768  {
2769  via->SetViaType( VIATYPE::MICROVIA );
2770  }
2771  else
2772  {
2773  via->SetViaType( VIATYPE::BLIND_BURIED );
2774  }
2775 
2776  wxPoint pos( kicad_x( v.x ), kicad_y( v.y ) );
2777 
2778  via->SetLayerPair( layer_front_most, layer_back_most );
2779  via->SetPosition( pos );
2780  via->SetEnd( pos );
2781 
2782  via->SetNetCode( netCode );
2783  }
2784 
2785  m_xpath->pop();
2786  }
2787 
2788  else if( itemName == wxT( "contactref" ) )
2789  {
2790  m_xpath->push( "contactref" );
2791  // <contactref element="RN1" pad="7"/>
2792 
2793  const wxString& reference = netItem->GetAttribute( "element" );
2794  const wxString& pad = netItem->GetAttribute( "pad" );
2795  wxString key = makeKey( reference, pad ) ;
2796 
2797  m_pads_to_nets[ key ] = ENET( netCode, netName );
2798 
2799  m_xpath->pop();
2800 
2801  sawPad = true;
2802  }
2803 
2804  else if( itemName == wxT( "polygon" ) )
2805  {
2806  m_xpath->push( "polygon" );
2807  auto* zone = loadPolygon( netItem );
2808 
2809  if( zone )
2810  {
2811  zones.push_back( zone );
2812 
2813  if( !zone->GetIsRuleArea() )
2814  zone->SetNetCode( netCode );
2815  }
2816 
2817  m_xpath->pop(); // "polygon"
2818  }
2819 
2820  netItem = netItem->GetNext();
2821  }
2822 
2823  if( zones.size() && !sawPad )
2824  {
2825  // KiCad does not support an unconnected zone with its own non-zero netcode,
2826  // but only when assigned netcode = 0 w/o a name...
2827  for( ZONE* zone : zones )
2828  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
2829 
2830  // therefore omit this signal/net.
2831  }
2832  else
2833  {
2834  netCode++;
2835  }
2836 
2837  // Get next signal
2838  net = net->GetNext();
2839  }
2840 
2841  m_xpath->pop(); // "signals.signal"
2842 }
std::vector< ZONE * > ZONES
Definition: eagle_plugin.h:44
double rlMaxViaOuter
maximum copper annulus on via
Definition: eagle_plugin.h:120
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
static T eagleClamp(T aMin, T aValue, T aMax)
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetEnd(const wxPoint &aEnd)
Definition: pcb_track.h:104
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:294
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:115
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
int m_min_via
smallest via we find on Load(), in BIU.
Definition: eagle_plugin.h:317
double rvViaOuter
copper annulus is this percent of via hole
Definition: eagle_plugin.h:118
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:295
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
static wxString makeKey(const wxString &aFirst, const wxString &aSecond)
Assemble a two part key as a simple concatenation of aFirst and aSecond parts, using a separator.
wxString escapeName(const wxString &aNetName)
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
int m_min_trace
smallest trace we find on Load(), in BIU.
Definition: eagle_plugin.h:315
Eagle net.
Definition: eagle_parser.h:453
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:808
void SetPosition(const wxPoint &aPos) override
Definition: pcb_track.h:97
void SetWidth(int aWidth)
Definition: pcb_track.h:101
Eagle via.
Definition: eagle_parser.h:547
Handle the data for a net.
Definition: netinfo.h:66
double DEG2RAD(double deg)
Definition: trigo.h:229
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Definition: layer_ids.h:71
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
int m_min_annulus
smallest via annulus we find on Load(), in BIU.
Definition: eagle_plugin.h:318
NET_MAP m_pads_to_nets
net list
Definition: eagle_plugin.h:300
Eagle wire.
Definition: eagle_parser.h:491
int m_min_hole
smallest diameter hole we find on Load(), in BIU.
Definition: eagle_plugin.h:316
void pop()
Definition: eagle_parser.h:122
double rlMinViaOuter
minimum copper annulus on via
Definition: eagle_plugin.h:119
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:372
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
std::map< wxString, NETCLASSPTR > m_classMap
Eagle class number to KiCad netclass.
Definition: eagle_plugin.h:291
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188
ZONE * loadPolygon(wxXmlNode *aPolyNode)
Load a copper or keepout polygon and adds it to the board.
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:125

References BOARD::Add(), PNS::angle(), B_Cu, BLIND_BURIED, checkpoint(), ConvertArcCenter(), EWIRE::curve, DEG2RAD(), EVIA::diam, EVIA::drill, eagleClamp(), escapeName(), F_Cu, GetArcToSegmentCount(), IsCopperLayer(), kicad_layer(), kicad_x(), kicad_y(), KiROUND(), EWIRE::layer, EVIA::layer_back_most, EVIA::layer_front_most, loadPolygon(), m_board, m_classMap, m_min_annulus, m_min_hole, m_min_trace, m_min_via, m_pads_to_nets, m_rules, m_xpath, makeKey(), MICROVIA, pad, XPATH::pop(), XPATH::push(), ERULES::rlMaxViaOuter, ERULES::rlMinViaOuter, ERULES::rvViaOuter, PCB_TRACK::SetEnd(), BOARD_ITEM::SetLayer(), BOARD_CONNECTED_ITEM::SetNetCode(), PCB_TRACK::SetPosition(), PCB_TRACK::SetWidth(), THROUGH, ECOORD::ToPcbUnits(), NETINFO_LIST::UNCONNECTED, XPATH::Value(), via, EWIRE::width, EVIA::x, EWIRE::x1, EWIRE::x2, EVIA::y, EWIRE::y1, and EWIRE::y2.

Referenced by loadAllSections().

◆ makeFootprint()

FOOTPRINT * EAGLE_PLUGIN::makeFootprint ( wxXmlNode *  aPackage,
const wxString &  aPkgName 
)
private

Create a FOOTPRINT from an Eagle package.

Definition at line 1770 of file eagle_plugin.cpp.

1771 {
1772  std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>( m_board );
1773 
1774  LIB_ID fpID;
1775  fpID.Parse( aPkgName, true );
1776  m->SetFPID( fpID );
1777 
1778  // Get the first package item and iterate
1779  wxXmlNode* packageItem = aPackage->GetChildren();
1780 
1781  // layer 27 is default layer for tValues
1782  // set default layer for created footprint
1783  PCB_LAYER_ID layer = kicad_layer( 27 );
1784  m.get()->Value().SetLayer( layer );
1785 
1786  while( packageItem )
1787  {
1788  const wxString& itemName = packageItem->GetName();
1789 
1790  if( itemName == wxT( "description" ) )
1791  m->SetDescription( FROM_UTF8( packageItem->GetNodeContent().c_str() ) );
1792  else if( itemName == wxT( "wire" ) )
1793  packageWire( m.get(), packageItem );
1794  else if( itemName == wxT( "pad" ) )
1795  packagePad( m.get(), packageItem );
1796  else if( itemName == wxT( "text" ) )
1797  packageText( m.get(), packageItem );
1798  else if( itemName == wxT( "rectangle" ) )
1799  packageRectangle( m.get(), packageItem );
1800  else if( itemName == wxT( "polygon" ) )
1801  packagePolygon( m.get(), packageItem );
1802  else if( itemName == wxT( "circle" ) )
1803  packageCircle( m.get(), packageItem );
1804  else if( itemName == wxT( "hole" ) )
1805  packageHole( m.get(), packageItem, false );
1806  else if( itemName == wxT( "smd" ) )
1807  packageSMD( m.get(), packageItem );
1808 
1809  packageItem = packageItem->GetNext();
1810  }
1811 
1812  return m.release();
1813 }
void packageHole(FOOTPRINT *aFootprint, wxXmlNode *aTree, bool aCenter) const
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:308
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void packageWire(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void packageRectangle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void packagePad(FOOTPRINT *aFootprint, wxXmlNode *aTree)
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:49
void packageCircle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void packagePolygon(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void packageText(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
void packageSMD(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
Handles common pad properties.

References FROM_UTF8(), kicad_layer(), m_board, packageCircle(), packageHole(), packagePad(), packagePolygon(), packageRectangle(), packageSMD(), packageText(), packageWire(), and LIB_ID::Parse().

Referenced by loadLibrary().

◆ mapEagleLayersToKicad()

void EAGLE_PLUGIN::mapEagleLayersToKicad ( )
private

Generate mapping between Eagle na KiCad layers.

Definition at line 2860 of file eagle_plugin.cpp.

2861 {
2862  std::vector<INPUT_LAYER_DESC> inputDescs;
2863 
2864  for ( const std::pair<const int, ELAYER>& layerPair : m_eagleLayers )
2865  {
2866  const ELAYER& eLayer = layerPair.second;
2867 
2868  INPUT_LAYER_DESC layerDesc;
2869  std::tie( layerDesc.AutoMapLayer, layerDesc.PermittedLayers, layerDesc.Required ) =
2870  defaultKicadLayer( eLayer.number );
2871 
2872  if( layerDesc.AutoMapLayer == UNDEFINED_LAYER )
2873  continue; // Ignore unused copper layers
2874 
2875  layerDesc.Name = eLayer.name;
2876 
2877  inputDescs.push_back( layerDesc );
2878  }
2879 
2880  if( m_progressReporter && dynamic_cast<wxWindow*>( m_progressReporter ) )
2881  dynamic_cast<wxWindow*>( m_progressReporter )->Hide();
2882 
2883  m_layer_map = m_layer_mapping_handler( inputDescs );
2884 
2885  if( m_progressReporter && dynamic_cast<wxWindow*>( m_progressReporter ))
2886  dynamic_cast<wxWindow*>( m_progressReporter )->Show();
2887 }
int number
Definition: eagle_parser.h:828
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
Definition: eagle_plugin.h:310
Describes an imported layer and how it could be mapped to KiCad Layers.
wxString name
Definition: eagle_parser.h:829
std::map< int, ELAYER > m_eagleLayers
Eagle layer data stored by layer number.
Definition: eagle_plugin.h:287
LSET PermittedLayers
KiCad layers that the imported layer can be mapped onto.
bool Required
Should we require the layer to be assigned?
LAYER_MAPPING_HANDLER m_layer_mapping_handler
Callback to get layer mapping.
std::tuple< PCB_LAYER_ID, LSET, bool > defaultKicadLayer(int aEagleLayer) const
Get default KiCad layer corresponding to an Eagle layer of the board, a set of sensible layer mapping...
std::map< wxString, PCB_LAYER_ID > m_layer_map
Map of Eagle layers to KiCad layers.
Definition: eagle_plugin.h:289
wxString Name
Imported layer name as displayed in original application.
PCB_LAYER_ID AutoMapLayer
Best guess as to what the equivalent KiCad layer might be.

References INPUT_LAYER_DESC::AutoMapLayer, defaultKicadLayer(), m_eagleLayers, m_layer_map, LAYER_REMAPPABLE_PLUGIN::m_layer_mapping_handler, m_progressReporter, INPUT_LAYER_DESC::Name, ELAYER::name, ELAYER::number, INPUT_LAYER_DESC::PermittedLayers, INPUT_LAYER_DESC::Required, and UNDEFINED_LAYER.

Referenced by cacheLib(), and loadAllSections().

◆ orientFootprintAndText()

void EAGLE_PLUGIN::orientFootprintAndText ( FOOTPRINT aFootprint,
const EELEMENT e,
const EATTR aNameAttr,
const EATTR aValueAttr 
)
private

Definition at line 1596 of file eagle_plugin.cpp.

1598 {
1599  if( e.rot )
1600  {
1601  if( e.rot->mirror )
1602  {
1603  double orientation = e.rot->degrees + 180.0;
1604  aFootprint->SetOrientation( orientation * 10 );
1605  aFootprint->Flip( aFootprint->GetPosition(), false );
1606  }
1607  else
1608  {
1609  aFootprint->SetOrientation( e.rot->degrees * 10 );
1610  }
1611  }
1612 
1613  orientFPText( aFootprint, e, &aFootprint->Reference(), aNameAttr );
1614  orientFPText( aFootprint, e, &aFootprint->Value(), aValueAttr );
1615 }
bool mirror
Definition: eagle_parser.h:472
opt_erot rot
Definition: eagle_parser.h:820
double degrees
Definition: eagle_parser.h:474
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:502
FP_TEXT & Reference()
Definition: footprint.h:503
void SetOrientation(double aNewAngle)
Definition: footprint.cpp:1681
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: footprint.cpp:1491
wxPoint GetPosition() const override
Definition: footprint.h:187
void orientFPText(FOOTPRINT *aFootprint, const EELEMENT &e, FP_TEXT *aFPText, const EATTR *aAttr)

References EROT::degrees, FOOTPRINT::Flip(), FOOTPRINT::GetPosition(), EROT::mirror, orientFPText(), FOOTPRINT::Reference(), EELEMENT::rot, FOOTPRINT::SetOrientation(), and FOOTPRINT::Value().

Referenced by loadElements().

◆ orientFPText()

void EAGLE_PLUGIN::orientFPText ( FOOTPRINT aFootprint,
const EELEMENT e,
FP_TEXT aFPText,
const EATTR aAttr 
)
private

Definition at line 1618 of file eagle_plugin.cpp.

1620 {
1621  // Smashed part ?
1622  if( aAttr )
1623  {
1624  // Yes
1625  const EATTR& a = *aAttr;
1626 
1627  if( a.value )
1628  {
1629  aFPText->SetText( FROM_UTF8( a.value->c_str() ) );
1630  }
1631 
1632  if( a.x && a.y ) // OPT
1633  {
1634  wxPoint pos( kicad_x( *a.x ), kicad_y( *a.y ) );
1635  aFPText->SetTextPos( pos );
1636  }
1637 
1638  // Even though size and ratio are both optional, I am not seeing
1639  // a case where ratio is present but size is not.
1640  double ratio = 8;
1641 
1642  if( a.ratio )
1643  ratio = *a.ratio;
1644 
1645  wxSize fontz = aFPText->GetTextSize();
1646  int textThickness = KiROUND( fontz.y * ratio / 100 );
1647 
1648  aFPText->SetTextThickness( textThickness );
1649  if( a.size )
1650  {
1651  fontz = kicad_fontz( *a.size, textThickness );
1652  aFPText->SetTextSize( fontz );
1653  }
1654 
1655 
1656  int align = ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
1657 
1658  if( a.align )
1659  align = a.align;
1660 
1661  // The "rot" in a EATTR seems to be assumed to be zero if it is not
1662  // present, and this zero rotation becomes an override to the
1663  // package's text field. If they did not want zero, they specify
1664  // what they want explicitly.
1665  double degrees = a.rot ? a.rot->degrees : 0;
1666  double orient; // relative to parent
1667 
1668  int sign = 1;
1669  bool spin = false;
1670 
1671  if( a.rot )
1672  {
1673  spin = a.rot->spin;
1674  sign = a.rot->mirror ? -1 : 1;
1675  aFPText->SetMirrored( a.rot->mirror );
1676  }
1677 
1678  if( degrees == 90 || degrees == 0 || spin )
1679  {
1680  orient = degrees - aFootprint->GetOrientation() / 10;
1681  aFPText->SetTextAngle( sign * orient * 10 );
1682  }
1683  else if( degrees == 180 )
1684  {
1685  orient = 0 - aFootprint->GetOrientation() / 10;
1686  aFPText->SetTextAngle( sign * orient * 10 );
1687  align = -align;
1688  }
1689  else if( degrees == 270 )
1690  {
1691  orient = 90 - aFootprint->GetOrientation() / 10;
1692  align = -align;
1693  aFPText->SetTextAngle( sign * orient * 10 );
1694  }
1695  else
1696  {
1697  orient = 90 - degrees - aFootprint->GetOrientation() / 10;
1698  aFPText->SetTextAngle( sign * orient * 10 );
1699  }
1700 
1701  switch( align )
1702  {
1703  case ETEXT::TOP_RIGHT:
1706  break;
1707 
1708  case ETEXT::BOTTOM_LEFT:
1711  break;
1712 
1713  case ETEXT::TOP_LEFT:
1716  break;
1717 
1718  case ETEXT::BOTTOM_RIGHT:
1721  break;
1722 
1723  case ETEXT::TOP_CENTER:
1726  break;
1727 
1728  case ETEXT::BOTTOM_CENTER:
1731  break;
1732 
1733  case ETEXT::CENTER:
1736  break;
1737 
1738  case ETEXT::CENTER_LEFT:
1741  break;
1742 
1743  case ETEXT::CENTER_RIGHT:
1746  break;
1747 
1748  default:
1749  ;
1750  }
1751  }
1752  else
1753  {
1754  // Part is not smash so use Lib default for NAME/VALUE // the text is per the original
1755  // package, sans <attribute>.
1756  double degrees = ( aFPText->GetTextAngle() + aFootprint->GetOrientation() ) / 10;
1757 
1758  // @todo there are a few more cases than these to contend with:
1759  if( ( !aFPText->IsMirrored() && ( abs( degrees ) == 180 || abs( degrees ) == 270 ) )
1760  || ( aFPText->IsMirrored() && ( degrees == 360 ) ) )
1761  {
1762  // ETEXT::TOP_RIGHT:
1765  }
1766  }
1767 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:209
int sign(T val)
Definition: util.h:104
bool mirror
Definition: eagle_parser.h:472
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
bool IsMirrored() const
Definition: eda_text.h:210
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
void SetTextAngle(double aAngle) override
Definition: fp_text.cpp:73
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:267
double GetOrientation() const
Definition: footprint.h:191
double GetTextAngle() const
Definition: eda_text.h:195
double degrees
Definition: eagle_parser.h:474
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
opt_erot rot
Definition: eagle_parser.h:603
opt_int align
Definition: eagle_parser.h:612
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
opt_ecoord y
Definition: eagle_parser.h:599
const wxSize & GetTextSize() const
Definition: eda_text.h:259
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:223
opt_wxString value
Definition: eagle_parser.h:597
Parse an Eagle "attribute" XML element.
Definition: eagle_parser.h:594
opt_ecoord x
Definition: eagle_parser.h:598
wxSize kicad_fontz(const ECOORD &d, int aTextThickness) const
create a font size (fontz) from an eagle font size scalar and KiCad font thickness
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:222
opt_double ratio
Definition: eagle_parser.h:602
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:180
bool spin
Definition: eagle_parser.h:473
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188
opt_ecoord size
Definition: eagle_parser.h:600

References EATTR::align, ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, ETEXT::CENTER, ETEXT::CENTER_LEFT, ETEXT::CENTER_RIGHT, EROT::degrees, FROM_UTF8(), FOOTPRINT::GetOrientation(), EDA_TEXT::GetTextAngle(), EDA_TEXT::GetTextSize(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP, EDA_TEXT::IsMirrored(), kicad_fontz(), kicad_x(), kicad_y(), KiROUND(), EROT::mirror, EATTR::ratio, EATTR::rot, EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetMirrored(), EDA_TEXT::SetText(), FP_TEXT::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetVertJustify(), sign(), EATTR::size, EROT::spin, ETEXT::TOP_CENTER, ETEXT::TOP_LEFT, ETEXT::TOP_RIGHT, EATTR::value, EATTR::x, and EATTR::y.

Referenced by orientFootprintAndText().

◆ packageCircle()

void EAGLE_PLUGIN::packageCircle ( FOOTPRINT aFootprint,
wxXmlNode *  aTree 
) const
private

Definition at line 2276 of file eagle_plugin.cpp.

2277 {
2278  ECIRCLE e( aTree );
2279 
2280  int width = e.width.ToPcbUnits();
2281  int radius = e.radius.ToPcbUnits();
2282 
2283  if( e.layer == EAGLE_LAYER::TRESTRICT
2284  || e.layer == EAGLE_LAYER::BRESTRICT
2285  || e.layer == EAGLE_LAYER::VRESTRICT )
2286  {
2287  FP_ZONE* zone = new FP_ZONE( aFootprint );
2288  aFootprint->Add( zone, ADD_MODE::APPEND );
2289 
2290  setKeepoutSettingsToZone( zone, e.layer );
2291 
2292  // approximate circle as polygon with a edge every 10 degree
2293  wxPoint center( kicad_x( e.x ), kicad_y( e.y ) );
2294  int outlineRadius = radius + ( width / 2 );
2295 
2296  for( int angle = 0; angle < 360; angle += 10 )
2297  {
2298  wxPoint rotatedPoint( outlineRadius, 0 );
2299  RotatePoint( &rotatedPoint, angle * 10. );
2300  zone->AppendCorner( center + rotatedPoint, -1 );
2301  }
2302 
2303  if( width > 0 )
2304  {
2305  zone->NewHole();
2306  int innerRadius = radius - ( width / 2 );
2307 
2308  for( int angle = 0; angle < 360; angle += 10 )
2309  {
2310  wxPoint rotatedPoint( innerRadius, 0 );
2311  RotatePoint( &rotatedPoint, angle * 10. );
2312  zone->AppendCorner( center + rotatedPoint, 0 );
2313  }
2314  }
2315 
2317  ZONE::GetDefaultHatchPitch(), true );
2318  }
2319  else
2320  {
2321  PCB_LAYER_ID layer = kicad_layer( e.layer );
2322 
2323  if( layer == UNDEFINED_LAYER )
2324  {
2325  wxLogMessage( wxString::Format( _( "Ignoring a circle since Eagle layer '%s' (%d) "
2326  "was not mapped" ),
2327  eagle_layer_name( e.layer ), e.layer ) );
2328  return;
2329  }
2330 
2331  FP_SHAPE* gr = new FP_SHAPE( aFootprint, SHAPE_T::CIRCLE );
2332 
2333  // width == 0 means filled circle
2334  if( width <= 0 )
2335  {
2336  width = radius;
2337  radius = radius / 2;
2338  gr->SetFilled( true );
2339  }
2340 
2341  aFootprint->Add( gr );
2342  gr->SetWidth( width );
2343 
2344  switch( (int) layer )
2345  {
2346  case UNDEFINED_LAYER:
2347  layer = Cmts_User;
2348  break;
2349  default:
2350  break;
2351  }
2352 
2353  gr->SetLayer( layer );
2354  gr->SetStart0( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
2355  gr->SetEnd0( wxPoint( kicad_x( e.x ) + radius, kicad_y( e.y ) ) );
2356  gr->SetDrawCoord();
2357  }
2358 }
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
void SetEnd0(const wxPoint &aPoint)
Definition: fp_shape.h:114
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void SetFilled(bool aFlag)
Definition: eda_shape.h:92
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:875
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
void NewHole()
Create a new hole on the zone; i.e., a new contour on the zone's outline.
Definition: zone.h:599
static int GetDefaultHatchPitch()
Definition: zone.cpp:1038
Eagle circle.
Definition: eagle_parser.h:562
#define _(s)
void SetWidth(int aWidth)
Definition: eda_shape.h:97
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:81
void SetStart0(const wxPoint &aPoint)
Definition: fp_shape.h:111
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
bool AppendCorner(wxPoint aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition: zone.cpp:815
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
static void setKeepoutSettingsToZone(ZONE *aZone, LAYER_NUM aLayer)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
A specialization of ZONE for use in footprints.
Definition: zone.h:947
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188

References _, FOOTPRINT::Add(), PNS::angle(), APPEND, ZONE::AppendCorner(), EAGLE_LAYER::BRESTRICT, CIRCLE, Cmts_User, DIAGONAL_EDGE, eagle_layer_name(), Format(), ZONE::GetDefaultHatchPitch(), kicad_layer(), kicad_x(), kicad_y(), ECIRCLE::layer, ZONE::NewHole(), ECIRCLE::radius, RotatePoint(), ZONE::SetBorderDisplayStyle(), FP_SHAPE::SetDrawCoord(), FP_SHAPE::SetEnd0(), EDA_SHAPE::SetFilled(), setKeepoutSettingsToZone(), BOARD_ITEM::SetLayer(), FP_SHAPE::SetStart0(), EDA_SHAPE::SetWidth(), ECOORD::ToPcbUnits(), EAGLE_LAYER::TRESTRICT, UNDEFINED_LAYER, EAGLE_LAYER::VRESTRICT, ECIRCLE::width, ECIRCLE::x, and ECIRCLE::y.

Referenced by makeFootprint().

◆ packageHole()

void EAGLE_PLUGIN::packageHole ( FOOTPRINT aFootprint,
wxXmlNode *  aTree,
bool  aCenter 
) const
private
Parameters
aFootprintThe KiCad footprint to which to assign the hole.
aTreeThe Eagle XML node that is of type "hole".
aCenterIf true, center the hole in the footprint and offset the footprint position.

Definition at line 2361 of file eagle_plugin.cpp.

2362 {
2363  EHOLE e( aTree );
2364 
2365  if( e.drill.value == 0 )
2366  return;
2367 
2368  // we add a PAD_ATTRIB::NPTH pad to this footprint.
2369  PAD* pad = new PAD( aFootprint );
2370  aFootprint->Add( pad );
2371 
2372  pad->SetShape( PAD_SHAPE::CIRCLE );
2373  pad->SetAttribute( PAD_ATTRIB::NPTH );
2374 
2375  // Mechanical purpose only:
2376  // no offset, no net name, no pad name allowed
2377  // pad->SetOffset( wxPoint( 0, 0 ) );
2378  // pad->SetNumber( wxEmptyString );
2379 
2380  wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) );
2381 
2382  if( aCenter )
2383  {
2384  pad->SetPos0( wxPoint( 0, 0 ) );
2385  aFootprint->SetPosition( padpos );
2386  pad->SetPosition( padpos );
2387  }
2388  else
2389  {
2390  pad->SetPos0( padpos );
2391  pad->SetPosition( padpos + aFootprint->GetPosition() );
2392  }
2393 
2394  wxSize sz( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() );
2395 
2396  pad->SetDrillSize( sz );
2397  pad->SetSize( sz );
2398 
2399  pad->SetLayerSet( LSET::AllCuMask().set( B_Mask ).set( F_Mask ) );
2400 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:759
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
Eagle hole element.
Definition: eagle_parser.h:799
like PAD_PTH, but not plated
wxPoint GetPosition() const override
Definition: footprint.h:187
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
Definition: pad.h:57
void SetPosition(const wxPoint &aPos) override
Definition: footprint.cpp:1562
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188

References FOOTPRINT::Add(), LSET::AllCuMask(), B_Mask, CIRCLE, EHOLE::drill, F_Mask, FOOTPRINT::GetPosition(), kicad_x(), kicad_y(), NPTH, PAD, pad, FOOTPRINT::SetPosition(), ECOORD::ToPcbUnits(), ECOORD::value, EHOLE::x, and EHOLE::y.

Referenced by loadPlain(), and makeFootprint().

◆ packagePad()

void EAGLE_PLUGIN::packagePad ( FOOTPRINT aFootprint,
wxXmlNode *  aTree 
)
private

Definition at line 1888 of file eagle_plugin.cpp.

1889 {
1890  // this is thru hole technology here, no SMDs
1891  EPAD e( aTree );
1892  int shape = EPAD::UNDEF;
1893  int eagleDrillz = e.drill.ToPcbUnits();
1894 
1895  PAD* pad = new PAD( aFootprint );
1896  aFootprint->Add( pad );
1897  transferPad( e, pad );
1898 
1899  if( e.first && *e.first && m_rules->psFirst != EPAD::UNDEF )
1900  shape = m_rules->psFirst;
1901  else if( aFootprint->GetLayer() == F_Cu && m_rules->psTop != EPAD::UNDEF )
1902  shape = m_rules->psTop;
1903  else if( aFootprint->GetLayer() == B_Cu && m_rules->psBottom != EPAD::UNDEF )
1904  shape = m_rules->psBottom;
1905 
1906  pad->SetDrillSize( wxSize( eagleDrillz, eagleDrillz ) );
1907  pad->SetLayerSet( LSET::AllCuMask() );
1908 
1909  if( eagleDrillz < m_min_hole )
1910  m_min_hole = eagleDrillz;
1911 
1912  // Solder mask
1913  if( !e.stop || *e.stop == true ) // enabled by default
1914  pad->SetLayerSet( pad->GetLayerSet().set( B_Mask ).set( F_Mask ) );
1915 
1916  if( shape == EPAD::ROUND || shape == EPAD::SQUARE || shape == EPAD::OCTAGON )
1917  e.shape = shape;
1918 
1919  if( e.shape )
1920  {
1921  switch( *e.shape )
1922  {
1923  case EPAD::ROUND:
1924  pad->SetShape( PAD_SHAPE::CIRCLE );
1925  break;
1926 
1927  case EPAD::OCTAGON:
1928  pad->SetShape( PAD_SHAPE::CHAMFERED_RECT );
1929  pad->SetChamferPositions( RECT_CHAMFER_ALL );
1930  pad->SetChamferRectRatio( 1 - M_SQRT1_2 ); // Regular polygon
1931  break;
1932 
1933  case EPAD::LONG:
1934  pad->SetShape( PAD_SHAPE::OVAL );
1935  break;
1936 
1937  case EPAD::SQUARE:
1938  pad->SetShape( PAD_SHAPE::RECT );
1939  break;
1940 
1941  case EPAD::OFFSET:
1942  pad->SetShape( PAD_SHAPE::OVAL );
1943  break;
1944  }
1945  }
1946  else
1947  {
1948  // if shape is not present, our default is circle and that matches their default "round"
1949  }
1950 
1951  if( e.diameter && e.diameter->value > 0 )
1952  {
1953  int diameter = e.diameter->ToPcbUnits();
1954  pad->SetSize( wxSize( diameter, diameter ) );
1955  }
1956  else
1957  {
1958  double drillz = pad->GetDrillSize().x;
1959  double annulus = drillz * m_rules->rvPadTop; // copper annulus, eagle "restring"
1960  annulus = eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
1961  int diameter = KiROUND( drillz + 2 * annulus );
1962  pad->SetSize( wxSize( KiROUND( diameter ), KiROUND( diameter ) ) );
1963  }
1964 
1965  if( pad->GetShape() == PAD_SHAPE::OVAL )
1966  {
1967  // The Eagle "long" pad is wider than it is tall; m_elongation is percent elongation
1968  wxSize sz = pad->GetSize();
1969  sz.x = ( sz.x * ( 100 + m_rules->psElongationLong ) ) / 100;
1970  pad->SetSize( sz );
1971 
1972  if( e.shape && *e.shape == EPAD::OFFSET )
1973  {
1974  int offset = KiROUND( ( sz.x - sz.y ) / 2.0 );
1975  pad->SetOffset( wxPoint( offset, 0 ) );
1976  }
1977  }
1978 
1979  if( e.rot )
1980  {
1981  pad->SetOrientation( e.rot->degrees * 10 );
1982  }
1983 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:759
static T eagleClamp(T aMin, T aValue, T aMax)
int psTop
Shape of the top pads.
Definition: eagle_plugin.h:100
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:294
double rlMaxPadTop
maximum copper annulus on through hole pads
Definition: eagle_plugin.h:116
Eagle thru hole pad.
Definition: eagle_parser.h:706
int psElongationLong
Definition: eagle_plugin.h:86
int psFirst
Shape of the first pads.
Definition: eagle_plugin.h:102
void transferPad(const EPAD_COMMON &aEaglePad, PAD *aPad) const
Deletes the footprint templates list.
Definition: layer_ids.h:71
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
int m_min_hole
smallest diameter hole we find on Load(), in BIU.
Definition: eagle_plugin.h:316
double rvPadTop
top pad size as percent of drill size
Definition: eagle_plugin.h:112
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
Definition: pad.h:57
int psBottom
Shape of the bottom pads.
Definition: eagle_plugin.h:101
double rlMinPadTop
minimum copper annulus on through hole pads
Definition: eagle_plugin.h:115
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:143

References FOOTPRINT::Add(), LSET::AllCuMask(), B_Cu, B_Mask, CHAMFERED_RECT, CIRCLE, EROT::degrees, EPAD::diameter, EPAD::drill, eagleClamp(), F_Cu, F_Mask, EPAD::first, BOARD_ITEM::GetLayer(), KiROUND(), EPAD::LONG, m_min_hole, m_rules, EPAD::OCTAGON, EPAD::OFFSET, OVAL, PAD, pad, ERULES::psBottom, ERULES::psElongationLong, ERULES::psFirst, ERULES::psTop, RECT, RECT_CHAMFER_ALL, ERULES::rlMaxPadTop, ERULES::rlMinPadTop, EPAD_COMMON::rot, EPAD::ROUND, ERULES::rvPadTop, EPAD::shape, EPAD::SQUARE, EPAD_COMMON::stop, ECOORD::ToPcbUnits(), transferPad(), EPAD::UNDEF, and ECOORD::value.

Referenced by makeFootprint().

◆ packagePolygon()

void EAGLE_PLUGIN::packagePolygon ( FOOTPRINT aFootprint,
wxXmlNode *  aTree 
) const
private

Definition at line 2173 of file eagle_plugin.cpp.

2174 {
2175  EPOLYGON p( aTree );
2176 
2177  std::vector<wxPoint> pts;
2178 
2179  // Get the first vertex and iterate
2180  wxXmlNode* vertex = aTree->GetChildren();
2181  std::vector<EVERTEX> vertices;
2182 
2183  // Create a circular vector of vertices
2184  // The "curve" parameter indicates a curve from the current
2185  // to the next vertex, so we keep the first at the end as well
2186  // to allow the curve to link back
2187  while( vertex )
2188  {
2189  if( vertex->GetName() == wxT( "vertex" ) )
2190  vertices.emplace_back( vertex );
2191 
2192  vertex = vertex->GetNext();
2193  }
2194 
2195  vertices.push_back( vertices[0] );
2196 
2197  for( size_t i = 0; i < vertices.size() - 1; i++ )
2198  {
2199  EVERTEX v1 = vertices[i];
2200 
2201  // Append the corner
2202  pts.emplace_back( kicad_x( v1.x ), kicad_y( v1.y ) );
2203 
2204  if( v1.curve )
2205  {
2206  EVERTEX v2 = vertices[i + 1];
2207  wxPoint center =
2208  ConvertArcCenter( wxPoint( kicad_x( v1.x ), kicad_y( v1.y ) ),
2209  wxPoint( kicad_x( v2.x ), kicad_y( v2.y ) ), *v1.curve );
2210  double angle = DEG2RAD( *v1.curve );
2211  double end_angle = atan2( kicad_y( v2.y ) - center.y, kicad_x( v2.x ) - center.x );
2212  double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
2213  + pow( center.y - kicad_y( v1.y ), 2 ) );
2214 
2215  // Don't allow a zero-radius curve
2216  if( KiROUND( radius ) == 0 )
2217  radius = 1.0;
2218 
2219  int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, *v1.curve );
2220  double delta = angle / segCount;
2221 
2222  for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta ); a -= delta )
2223  {
2224  pts.push_back( wxPoint( KiROUND( radius * cos( a ) ),
2225  KiROUND( radius * sin( a ) ) ) + center );
2226  }
2227  }
2228  }
2229 
2230  if( p.layer == EAGLE_LAYER::TRESTRICT
2231  || p.layer == EAGLE_LAYER::BRESTRICT
2232  || p.layer == EAGLE_LAYER::VRESTRICT )
2233  {
2234  FP_ZONE* zone = new FP_ZONE( aFootprint );
2235  aFootprint->Add( zone, ADD_MODE::APPEND );
2236 
2237  setKeepoutSettingsToZone( zone, p.layer );
2238 
2239  SHAPE_LINE_CHAIN outline( pts );
2240  outline.SetClosed( true );
2241  zone->Outline()->AddOutline( outline );
2242 
2244  ZONE::GetDefaultHatchPitch(), true );
2245  }
2246  else
2247  {
2248  PCB_LAYER_ID layer = kicad_layer( p.layer );
2249 
2250  if( layer == UNDEFINED_LAYER )
2251  {
2252  wxLogMessage( wxString::Format( _( "Ignoring a polygon since Eagle layer '%s' (%d) "
2253  "was not mapped" ),
2254  eagle_layer_name( p.layer ), p.layer ) );
2255  return;
2256  }
2257 
2258  FP_SHAPE* dwg = new FP_SHAPE( aFootprint, SHAPE_T::POLY );
2259 
2260  aFootprint->Add( dwg );
2261 
2262  dwg->SetWidth( 0 ); // it's filled, no need for boundary width
2263  dwg->SetFilled( true );
2264  dwg->SetLayer( layer );
2265 
2266  dwg->SetPolyPoints( pts );
2267  dwg->SetStart0( *pts.begin() );
2268  dwg->SetEnd0( pts.back() );
2269  dwg->SetDrawCoord();
2270  dwg->GetPolyShape().Inflate( p.width.ToPcbUnits() / 2, 32,
2272  }
2273 }
Eagle vertex.
Definition: eagle_parser.h:759
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
VECTOR2I v2(1, 0)
Test suite for KiCad math code.
void SetEnd0(const wxPoint &aPoint)
Definition: fp_shape.h:114
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void SetFilled(bool aFlag)
Definition: eda_shape.h:92
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:875
SHAPE_POLY_SET * Outline()
Definition: zone.h:320
ECOORD y
Definition: eagle_parser.h:762
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
static int GetDefaultHatchPitch()
Definition: zone.cpp:1038
#define _(s)
void SetWidth(int aWidth)
Definition: eda_shape.h:97
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:81
void SetStart0(const wxPoint &aPoint)
Definition: fp_shape.h:111
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:227
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:763
void Inflate(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
void SetPolyPoints(const std::vector< wxPoint > &aPoints)
Definition: eda_shape.cpp:1085
ECOORD x
Definition: eagle_parser.h:761
double DEG2RAD(double deg)
Definition: trigo.h:229
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
static void setKeepoutSettingsToZone(ZONE *aZone, LAYER_NUM aLayer)
constexpr int delta
Eagle polygon, without vertices which are parsed as needed.
Definition: eagle_parser.h:770
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
just inflate the polygon. Acute angles create spikes
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
A specialization of ZONE for use in footprints.
Definition: zone.h:947
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188

References _, FOOTPRINT::Add(), SHAPE_POLY_SET::AddOutline(), SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS, PNS::angle(), APPEND, EAGLE_LAYER::BRESTRICT, ConvertArcCenter(), EVERTEX::curve, DEG2RAD(), delta, DIAGONAL_EDGE, eagle_layer_name(), Format(), GetArcToSegmentCount(), ZONE::GetDefaultHatchPitch(), EDA_SHAPE::GetPolyShape(), SHAPE_POLY_SET::Inflate(), kicad_layer(), kicad_x(), kicad_y(), KiROUND(), EPOLYGON::layer, ZONE::Outline(), POLY, ZONE::SetBorderDisplayStyle(), SHAPE_LINE_CHAIN::SetClosed(), FP_SHAPE::SetDrawCoord(), FP_SHAPE::SetEnd0(), EDA_SHAPE::SetFilled(), setKeepoutSettingsToZone(), BOARD_ITEM::SetLayer(), EDA_SHAPE::SetPolyPoints(), FP_SHAPE::SetStart0(), EDA_SHAPE::SetWidth(), ECOORD::ToPcbUnits(), EAGLE_LAYER::TRESTRICT, UNDEFINED_LAYER, v2, EAGLE_LAYER::VRESTRICT, EPOLYGON::width, VECTOR2< T >::x, EVERTEX::x, VECTOR2< T >::y, and EVERTEX::y.

Referenced by makeFootprint().

◆ packageRectangle()

void EAGLE_PLUGIN::packageRectangle ( FOOTPRINT aFootprint,
wxXmlNode *  aTree 
) const
private

Definition at line 2104 of file eagle_plugin.cpp.

2105 {
2106  ERECT r( aTree );
2107 
2108  if( r.layer == EAGLE_LAYER::TRESTRICT || r.layer == EAGLE_LAYER::BRESTRICT
2109  || r.layer == EAGLE_LAYER::VRESTRICT )
2110  {
2111  FP_ZONE* zone = new FP_ZONE( aFootprint );
2112  aFootprint->Add( zone, ADD_MODE::APPEND );
2113 
2114  setKeepoutSettingsToZone( zone, r.layer );
2115 
2116  const int outlineIdx = -1; // this is the id of the copper zone main outline
2117  zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ), outlineIdx );
2118  zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ), outlineIdx );
2119  zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ), outlineIdx );
2120  zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ), outlineIdx );
2121 
2122  if( r.rot )
2123  {
2124  wxPoint center( ( kicad_x( r.x1 ) + kicad_x( r.x2 ) ) / 2,
2125  ( kicad_y( r.y1 ) + kicad_y( r.y2 ) ) / 2 );
2126  zone->Rotate( center, r.rot->degrees * 10 );
2127  }
2128 
2130  ZONE::GetDefaultHatchPitch(), true );
2131  }
2132  else
2133  {
2134  PCB_LAYER_ID layer = kicad_layer( r.layer );
2135 
2136  if( layer == UNDEFINED_LAYER )
2137  {
2138  wxLogMessage( wxString::Format( _( "Ignoring a rectangle since Eagle layer '%s' (%d) "
2139  "was not mapped" ),
2140  eagle_layer_name( r.layer ), r.layer ) );
2141  return;
2142  }
2143 
2144  FP_SHAPE* dwg = new FP_SHAPE( aFootprint, SHAPE_T::POLY );
2145 
2146  aFootprint->Add( dwg );
2147 
2148  dwg->SetLayer( layer );
2149  dwg->SetWidth( 0 );
2150  dwg->SetFilled( true );
2151 
2152  std::vector<wxPoint> pts;
2153 
2154  wxPoint start( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ) );
2155  wxPoint end( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
2156 
2157  pts.push_back( start );
2158  pts.emplace_back( kicad_x( r.x2 ), kicad_y( r.y1 ) );
2159  pts.emplace_back( kicad_x( r.x2 ), kicad_y( r.y2 ) );
2160  pts.push_back( end );
2161 
2162  dwg->SetPolyPoints( pts );
2163 
2164  dwg->SetStart0( start );
2165  dwg->SetEnd0( end );
2166 
2167  if( r.rot )
2168  dwg->Rotate( dwg->GetCenter(), r.rot->degrees * 10 );
2169  }
2170 }
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
void SetEnd0(const wxPoint &aPoint)
Definition: fp_shape.h:114
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void SetFilled(bool aFlag)
Definition: eda_shape.h:92
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:875
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
void Rotate(const wxPoint &aCentre, double aAngle) override
Move the outlines.
Definition: zone.cpp:689
static int GetDefaultHatchPitch()
Definition: zone.cpp:1038
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
Definition: fp_shape.cpp:343
wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:79
#define _(s)
void SetWidth(int aWidth)
Definition: eda_shape.h:97
E_SERIE r
Definition: eserie.cpp:41
Eagle XML rectangle in binary.
Definition: eagle_parser.h:575
void SetStart0(const wxPoint &aPoint)
Definition: fp_shape.h:111
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void SetPolyPoints(const std::vector< wxPoint > &aPoints)
Definition: eda_shape.cpp:1085
bool AppendCorner(wxPoint aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition: zone.cpp:815
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
static void setKeepoutSettingsToZone(ZONE *aZone, LAYER_NUM aLayer)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
A specialization of ZONE for use in footprints.
Definition: zone.h:947
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188

References _, FOOTPRINT::Add(), APPEND, ZONE::AppendCorner(), EAGLE_LAYER::BRESTRICT, DIAGONAL_EDGE, eagle_layer_name(), Format(), PCB_SHAPE::GetCenter(), ZONE::GetDefaultHatchPitch(), kicad_layer(), kicad_x(), kicad_y(), POLY, r, FP_SHAPE::Rotate(), ZONE::Rotate(), ZONE::SetBorderDisplayStyle(), FP_SHAPE::SetEnd0(), EDA_SHAPE::SetFilled(), setKeepoutSettingsToZone(), BOARD_ITEM::SetLayer(), EDA_SHAPE::SetPolyPoints(), FP_SHAPE::SetStart0(), EDA_SHAPE::SetWidth(), EAGLE_LAYER::TRESTRICT, UNDEFINED_LAYER, and EAGLE_LAYER::VRESTRICT.

Referenced by makeFootprint().

◆ packageSMD()

void EAGLE_PLUGIN::packageSMD ( FOOTPRINT aFootprint,
wxXmlNode *  aTree 
) const
private

Handles common pad properties.

Definition at line 2403 of file eagle_plugin.cpp.

2404 {
2405  ESMD e( aTree );
2406  PCB_LAYER_ID layer = kicad_layer( e.layer );
2407 
2408  if( !IsCopperLayer( layer ) || e.dx.value == 0 || e.dy.value == 0 )
2409  return;
2410 
2411  PAD* pad = new PAD( aFootprint );
2412  aFootprint->Add( pad );
2413  transferPad( e, pad );
2414 
2415  pad->SetShape( PAD_SHAPE::RECT );
2416  pad->SetAttribute( PAD_ATTRIB::SMD );
2417 
2418  wxSize padSize( e.dx.ToPcbUnits(), e.dy.ToPcbUnits() );
2419  pad->SetSize( padSize );
2420  pad->SetLayer( layer );
2421 
2422  const LSET front( 3, F_Cu, F_Paste, F_Mask );
2423  const LSET back( 3, B_Cu, B_Paste, B_Mask );
2424 
2425  if( layer == F_Cu )
2426  pad->SetLayerSet( front );
2427  else if( layer == B_Cu )
2428  pad->SetLayerSet( back );
2429 
2430  int minPadSize = std::min( padSize.x, padSize.y );
2431 
2432  // Rounded rectangle pads
2433  int roundRadius =
2434  eagleClamp( m_rules->srMinRoundness * 2, (int) ( minPadSize * m_rules->srRoundness ),
2435  m_rules->srMaxRoundness * 2 );
2436 
2437  if( e.roundness || roundRadius > 0 )
2438  {
2439  double roundRatio = (double) roundRadius / minPadSize / 2.0;
2440 
2441  // Eagle uses a different definition of roundness, hence division by 200
2442  if( e.roundness )
2443  roundRatio = std::fmax( *e.roundness / 200.0, roundRatio );
2444 
2445  pad->SetShape( PAD_SHAPE::ROUNDRECT );
2446  pad->SetRoundRectRadiusRatio( roundRatio );
2447  }
2448 
2449  if( e.rot )
2450  pad->SetOrientation( e.rot->degrees * 10 );
2451 
2452  pad->SetLocalSolderPasteMargin( -eagleClamp( m_rules->mlMinCreamFrame,
2453  (int) ( m_rules->mvCreamFrame * minPadSize ),
2454  m_rules->mlMaxCreamFrame ) );
2455 
2456  // Solder mask
2457  if( e.stop && *e.stop == false ) // enabled by default
2458  {
2459  if( layer == F_Cu )
2460  pad->SetLayerSet( pad->GetLayerSet().set( F_Mask, false ) );
2461  else if( layer == B_Cu )
2462  pad->SetLayerSet( pad->GetLayerSet().set( B_Mask, false ) );
2463  }
2464 
2465  // Solder paste (only for SMD pads)
2466  if( e.cream && *e.cream == false ) // enabled by default
2467  {
2468  if( layer == F_Cu )
2469  pad->SetLayerSet( pad->GetLayerSet().set( F_Paste, false ) );
2470  else if( layer == B_Cu )
2471  pad->SetLayerSet( pad->GetLayerSet().set( B_Paste, false ) );
2472  }
2473 }
static T eagleClamp(T aMin, T aValue, T aMax)
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:294
Smd pad, appears on the solder paste layer (default)
int srMinRoundness
corner rounding radius, maximum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:107
Eagle SMD pad.
Definition: eagle_parser.h:728
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:516
double srRoundness
corner rounding ratio for SMD pads (percentage)
Definition: eagle_plugin.h:104
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:808
void transferPad(const EPAD_COMMON &aEaglePad, PAD *aPad) const
Deletes the footprint templates list.
int mlMinCreamFrame
solder paste mask, minimum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:97
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
Definition: layer_ids.h:71
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
Definition: pad.h:57
int mlMaxCreamFrame
solder paste mask, maximum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:98
int srMaxRoundness
Definition: eagle_plugin.h:110
double mvCreamFrame
Definition: eagle_plugin.h:94

References FOOTPRINT::Add(), B_Cu, B_Mask, B_Paste, ESMD::cream, EROT::degrees, ESMD::dx, ESMD::dy, eagleClamp(), F_Cu, F_Mask, F_Paste, IsCopperLayer(), kicad_layer(), ESMD::layer, m_rules, ERULES::mlMaxCreamFrame, ERULES::mlMinCreamFrame, ERULES::mvCreamFrame, PAD, pad, RECT, EPAD_COMMON::rot, ESMD::roundness, ROUNDRECT, SMD, ERULES::srMaxRoundness, ERULES::srMinRoundness, ERULES::srRoundness, EPAD_COMMON::stop, ECOORD::ToPcbUnits(), transferPad(), and ECOORD::value.

Referenced by makeFootprint().

◆ packageText()

void EAGLE_PLUGIN::packageText ( FOOTPRINT aFootprint,
wxXmlNode *  aTree 
) const
private

Definition at line 1986 of file eagle_plugin.cpp.

1987 {
1988  ETEXT t( aTree );
1989  PCB_LAYER_ID layer = kicad_layer( t.layer );
1990 
1991  if( layer == UNDEFINED_LAYER )
1992  {
1993  wxLogMessage( wxString::Format( _( "Ignoring a text since Eagle layer '%s' (%d) "
1994  "was not mapped" ),
1995  eagle_layer_name( t.layer ), t.layer ) );
1996  return;
1997  }
1998 
1999  FP_TEXT* txt;
2000 
2001  if( t.text.MakeUpper() == wxT( ">NAME" ) )
2002  txt = &aFootprint->Reference();
2003  else if( t.text.MakeUpper() == wxT( ">VALUE" ) )
2004  txt = &aFootprint->Value();
2005  else
2006  {
2007  // FIXME: graphical text items are rotated for some reason.
2008  txt = new FP_TEXT( aFootprint );
2009  aFootprint->Add( txt );
2010  }
2011 
2012  txt->SetText( FROM_UTF8( t.text.c_str() ) );
2013 
2014  wxPoint pos( kicad_x( t.x ), kicad_y( t.y ) );
2015 
2016  txt->SetTextPos( pos );
2017  txt->SetPos0( pos - aFootprint->GetPosition() );
2018 
2019  txt->SetLayer( layer );
2020 
2021  double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
2022  int textThickness = KiROUND( t.size.ToPcbUnits() * ratio / 100 );
2023 
2024  txt->SetTextThickness( textThickness );
2025  txt->SetTextSize( kicad_fontz( t.size, textThickness ) );
2026 
2027  int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
2028 
2029  // An eagle package is never rotated, the DTD does not allow it.
2030  // angle -= aFootprint->GetOrienation();
2031 
2032  if( t.rot )
2033  {
2034  int sign = t.rot->mirror ? -1 : 1;
2035  txt->SetMirrored( t.rot->mirror );
2036 
2037  double degrees = t.rot->degrees;
2038 
2039  if( degrees == 90 || t.rot->spin )
2040  {
2041  txt->SetTextAngle( sign * degrees * 10 );
2042  }
2043  else if( degrees == 180 )
2044  {
2045  align = ETEXT::TOP_RIGHT;
2046  }
2047  else if( degrees == 270 )
2048  {
2049  align = ETEXT::TOP_RIGHT;
2050  txt->SetTextAngle( sign * 90 * 10 );
2051  }
2052  }
2053 
2054  switch( align )
2055  {
2056  case ETEXT::CENTER:
2059  break;
2060 
2061  case ETEXT::CENTER_LEFT:
2064  break;
2065 
2066  case ETEXT::CENTER_RIGHT:
2069  break;
2070 
2071  case ETEXT::TOP_CENTER:
2074  break;
2075 
2076  case ETEXT::TOP_LEFT:
2079  break;
2080 
2081  case ETEXT::TOP_RIGHT:
2084  break;
2085 
2086  case ETEXT::BOTTOM_CENTER:
2089  break;
2090 
2091  case ETEXT::BOTTOM_LEFT:
2094  break;
2095 
2096  case ETEXT::BOTTOM_RIGHT:
2099  break;
2100  }
2101 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:209
int sign(T val)
Definition: util.h:104
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetTextAngle(double aAngle) override
Definition: fp_text.cpp:73
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:267
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
Eagle text element.
Definition: eagle_parser.h:637
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:502
FP_TEXT & Reference()
Definition: footprint.h:503
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:223
#define _(s)
void SetPos0(const wxPoint &aPos)
Definition: fp_text.h:165
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxSize kicad_fontz(const ECOORD &d, int aTextThickness) const
create a font size (fontz) from an eagle font size scalar and KiCad font thickness
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:222
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
wxPoint GetPosition() const override
Definition: footprint.h:187
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:180
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188

References _, FOOTPRINT::Add(), ETEXT::align, ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, ETEXT::CENTER, ETEXT::CENTER_LEFT, ETEXT::CENTER_RIGHT, EROT::degrees, eagle_layer_name(), Format(), FROM_UTF8(), FOOTPRINT::GetPosition(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP, kicad_fontz(), kicad_layer(), kicad_x(), kicad_y(), KiROUND(), ETEXT::layer, EROT::mirror, ETEXT::ratio, FOOTPRINT::Reference(), ETEXT::rot, EDA_TEXT::SetHorizJustify(), BOARD_ITEM::SetLayer(), EDA_TEXT::SetMirrored(), FP_TEXT::SetPos0(), EDA_TEXT::SetText(), FP_TEXT::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetVertJustify(), sign(), ETEXT::size, EROT::spin, ETEXT::text, ETEXT::TOP_CENTER, ETEXT::TOP_LEFT, ETEXT::TOP_RIGHT, ECOORD::ToPcbUnits(), UNDEFINED_LAYER, FOOTPRINT::Value(), ETEXT::x, and ETEXT::y.

Referenced by makeFootprint().

◆ packageWire()

void EAGLE_PLUGIN::packageWire ( FOOTPRINT aFootprint,
wxXmlNode *  aTree 
) const
private

Definition at line 1816 of file eagle_plugin.cpp.

1817 {
1818  EWIRE w( aTree );
1819  PCB_LAYER_ID layer = kicad_layer( w.layer );
1820  wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
1821  wxPoint end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
1822  int width = w.width.ToPcbUnits();
1823 
1824  if( layer == UNDEFINED_LAYER )
1825  {
1826  wxLogMessage( wxString::Format( _( "Ignoring a wire since Eagle layer '%s' (%d) "
1827  "was not mapped" ),
1828  eagle_layer_name( w.layer ), w.layer ) );
1829  return;
1830  }
1831 
1832  // KiCad cannot handle zero or negative line widths which apparently have meaning in Eagle.
1833  if( width <= 0 )
1834  {
1835  BOARD* board = aFootprint->GetBoard();
1836 
1837  if( board )
1838  {
1839  width = board->GetDesignSettings().GetLineThickness( layer );
1840  }
1841  else
1842  {
1843  // When loading footprint libraries, there is no board so use the default KiCad
1844  // line widths.
1845  switch( layer )
1846  {
1847  case Edge_Cuts: width = Millimeter2iu( DEFAULT_EDGE_WIDTH ); break;
1848 
1849  case F_SilkS:
1850  case B_SilkS: width = Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ); break;
1851 
1852  case F_CrtYd:
1853  case B_CrtYd: width = Millimeter2iu( DEFAULT_COURTYARD_WIDTH ); break;
1854 
1855  default: width = Millimeter2iu( DEFAULT_LINE_WIDTH ); break;
1856  }
1857  }
1858  }
1859 
1860  // FIXME: the cap attribute is ignored because KiCad can't create lines with flat ends.
1861  FP_SHAPE* dwg;
1862 
1863  if( !w.curve )
1864  {
1865  dwg = new FP_SHAPE( aFootprint, SHAPE_T::SEGMENT );
1866 
1867  dwg->SetStart0( start );
1868  dwg->SetEnd0( end );
1869  }
1870  else
1871  {
1872  dwg = new FP_SHAPE( aFootprint, SHAPE_T::ARC );
1873  wxPoint center = ConvertArcCenter( start, end, *w.curve );
1874 
1875  dwg->SetCenter0( center );
1876  dwg->SetStart0( start );
1877  dwg->SetArcAngleAndEnd0( *w.curve * -10.0, true ); // KiCad rotates the other way
1878  }
1879 
1880  dwg->SetLayer( layer );
1881  dwg->SetWidth( width );
1882  dwg->SetDrawCoord();
1883 
1884  aFootprint->Add( dwg );
1885 }
#define DEFAULT_EDGE_WIDTH
#define DEFAULT_COURTYARD_WIDTH
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
void SetEnd0(const wxPoint &aPoint)
Definition: fp_shape.h:114
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetArcAngleAndEnd0(double aAngle, bool aCheckNegativeAngle=false)
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: fp_shape.cpp:194
#define DEFAULT_LINE_WIDTH
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
#define DEFAULT_SILK_LINE_WIDTH
#define _(s)
void SetWidth(int aWidth)
Definition: eda_shape.h:97
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:81
void SetStart0(const wxPoint &aPoint)
Definition: fp_shape.h:111
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:191
PCB_LAYER_ID
A quick no