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 3011 of file eagle_plugin.cpp.

3012 {
3013  try
3014  {
3015  wxDateTime modtime = getModificationTime( aLibPath );
3016 
3017  // Fixes assertions in wxWidgets debug builds for the wxDateTime object. Refresh the
3018  // cache if either of the wxDateTime objects are invalid or the last file modification
3019  // time differs from the current file modification time.
3020  bool load = !m_mod_time.IsValid() || !modtime.IsValid() || m_mod_time != modtime;
3021 
3022  if( aLibPath != m_lib_path || load )
3023  {
3024  wxXmlNode* doc;
3025  LOCALE_IO toggle; // toggles on, then off, the C locale.
3026 
3027  deleteTemplates();
3028 
3029  // Set this before completion of loading, since we rely on it for
3030  // text of an exception. Delay setting m_mod_time until after successful load
3031  // however.
3032  m_lib_path = aLibPath;
3033 
3034  // 8 bit "filename" should be encoded according to disk filename encoding,
3035  // (maybe this is current locale, maybe not, its a filesystem issue),
3036  // and is not necessarily utf8.
3037  string filename = (const char*) aLibPath.char_str( wxConvFile );
3038 
3039  // Load the document
3040  wxFileName fn( filename );
3041  wxFFileInputStream stream( fn.GetFullPath() );
3042  wxXmlDocument xmlDocument;
3043 
3044  if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3045  {
3046  THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'." ),
3047  fn.GetFullPath() ) );
3048  }
3049 
3050  doc = xmlDocument.GetRoot();
3051 
3052  wxXmlNode* drawing = MapChildren( doc )["drawing"];
3053  NODE_MAP drawingChildren = MapChildren( drawing );
3054 
3055  // clear the cu map and then rebuild it.
3056  clear_cu_map();
3057 
3058  m_xpath->push( "eagle.drawing.layers" );
3059  wxXmlNode* layers = drawingChildren["layers"];
3060  loadLayerDefs( layers );
3062  m_xpath->pop();
3063 
3064  m_xpath->push( "eagle.drawing.library" );
3065  wxXmlNode* library = drawingChildren["library"];
3066  loadLibrary( library, nullptr );
3067  m_xpath->pop();
3068 
3069  m_mod_time = modtime;
3070  }
3071  }
3072  catch(...){}
3073  // TODO: Handle exceptions
3074  // catch( file_parser_error fpe )
3075  // {
3076  // // for xml_parser_error, what() has the line number in it,
3077  // // but no byte offset. That should be an adequate error message.
3078  // THROW_IO_ERROR( fpe.what() );
3079  // }
3080  //
3081  // // Class ptree_error is a base class for xml_parser_error & file_parser_error,
3082  // // so one catch should be OK for all errors.
3083  // catch( ptree_error pte )
3084  // {
3085  // string errmsg = pte.what();
3086  //
3087  // errmsg += " @\n";
3088  // errmsg += m_xpath->Contents();
3089  //
3090  // THROW_IO_ERROR( errmsg );
3091  // }
3092 }
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 2972 of file eagle_plugin.cpp.

2973 {
2974  if( m_props )
2975  {
2976  UTF8 page_width;
2977  UTF8 page_height;
2978 
2979  if( m_props->Value( "page_width", &page_width ) &&
2980  m_props->Value( "page_height", &page_height ) )
2981  {
2983 
2984  int w = atoi( page_width.c_str() );
2985  int h = atoi( page_height.c_str() );
2986 
2987  int desired_x = ( w - bbbox.GetWidth() ) / 2;
2988  int desired_y = ( h - bbbox.GetHeight() ) / 2;
2989 
2990  m_board->Move( wxPoint( desired_x - bbbox.GetX(), desired_y - bbbox.GetY() ) );
2991  }
2992  }
2993 }
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:98
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:109
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:110
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:99

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
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 2827 of file eagle_plugin.cpp.

2828 {
2829  // eagle copper layer:
2830  if( aEagleLayer >= 1 && aEagleLayer < int( arrayDim( m_cu_map ) ) )
2831  {
2832  LSET copperLayers;
2833 
2834  for( int copperLayer : m_cu_map )
2835  {
2836  if( copperLayer >= 0 )
2837  copperLayers[copperLayer] = true;
2838  }
2839 
2840  return { PCB_LAYER_ID( m_cu_map[aEagleLayer] ), copperLayers, true };
2841  }
2842 
2843  int kiLayer = UNSELECTED_LAYER;
2844  bool required = false;
2845  LSET permittedLayers;
2846 
2847  permittedLayers.set();
2848 
2849  // translate non-copper eagle layer to pcbnew layer
2850  switch( aEagleLayer )
2851  {
2852  // Eagle says "Dimension" layer, but it's for board perimeter
2854  kiLayer = Edge_Cuts;
2855  required = true;
2856  permittedLayers = LSET( 1, Edge_Cuts );
2857  break;
2858 
2859  case EAGLE_LAYER::TPLACE:
2860  kiLayer = F_SilkS;
2861  break;
2862  case EAGLE_LAYER::BPLACE:
2863  kiLayer = B_SilkS;
2864  break;
2865  case EAGLE_LAYER::TNAMES:
2866  kiLayer = F_SilkS;
2867  break;
2868  case EAGLE_LAYER::BNAMES:
2869  kiLayer = B_SilkS;
2870  break;
2871  case EAGLE_LAYER::TVALUES:
2872  kiLayer = F_Fab;
2873  break;
2874  case EAGLE_LAYER::BVALUES:
2875  kiLayer = B_Fab;
2876  break;
2877  case EAGLE_LAYER::TSTOP:
2878  kiLayer = F_Mask;
2879  break;
2880  case EAGLE_LAYER::BSTOP:
2881  kiLayer = B_Mask;
2882  break;
2883  case EAGLE_LAYER::TCREAM:
2884  kiLayer = F_Paste;
2885  break;
2886  case EAGLE_LAYER::BCREAM:
2887  kiLayer = B_Paste;
2888  break;
2889  case EAGLE_LAYER::TFINISH:
2890  kiLayer = F_Mask;
2891  break;
2892  case EAGLE_LAYER::BFINISH:
2893  kiLayer = B_Mask;
2894  break;
2895  case EAGLE_LAYER::TGLUE:
2896  kiLayer = F_Adhes;
2897  break;
2898  case EAGLE_LAYER::BGLUE:
2899  kiLayer = B_Adhes;
2900  break;
2901  case EAGLE_LAYER::DOCUMENT:
2902  kiLayer = Cmts_User;
2903  break;
2905  kiLayer = Cmts_User;
2906  break;
2908  kiLayer = Cmts_User;
2909  break;
2910 
2911  // Packages show the future chip pins on SMD parts using layer 51.
2912  // This is an area slightly smaller than the PAD/SMD copper area.
2913  // Carry those visual aids into the FOOTPRINT on the fabrication layer,
2914  // not silkscreen. This is perhaps not perfect, but there is not a lot
2915  // of other suitable paired layers
2916  case EAGLE_LAYER::TDOCU:
2917  kiLayer = F_Fab;
2918  break;
2919  case EAGLE_LAYER::BDOCU:
2920  kiLayer = B_Fab;
2921  break;
2922 
2923  // these layers are defined as user layers. put them on ECO layers
2925  kiLayer = Eco1_User;
2926  break;
2928  kiLayer = Eco2_User;
2929  break;
2930 
2931  // these will also appear in the ratsnest, so there's no need for a warning
2932  case EAGLE_LAYER::UNROUTED:
2933  kiLayer = Dwgs_User;
2934  break;
2935 
2936  case EAGLE_LAYER::TKEEPOUT:
2937  kiLayer = F_CrtYd;
2938  break;
2939  case EAGLE_LAYER::BKEEPOUT:
2940  kiLayer = B_CrtYd;
2941  break;
2942 
2943  case EAGLE_LAYER::MILLING:
2944  case EAGLE_LAYER::TTEST:
2945  case EAGLE_LAYER::BTEST:
2946  case EAGLE_LAYER::HOLES:
2947  default:
2948  kiLayer = UNDEFINED_LAYER;
2949  break;
2950  }
2951 
2952  return { PCB_LAYER_ID( kiLayer ), permittedLayers, required };
2953 }
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:505
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 2775 of file eagle_plugin.cpp.

2777 {
2778  std::map<wxString, PCB_LAYER_ID> layer_map;
2779 
2780  for ( const INPUT_LAYER_DESC& layer : aInputLayerDescriptionVector )
2781  {
2782  PCB_LAYER_ID layerId = std::get<0>( defaultKicadLayer( eagle_layer_id( layer.Name ) ) );
2783  layer_map.emplace( layer.Name, layerId );
2784  }
2785 
2786  return layer_map;
2787 }
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 2434 of file eagle_plugin.cpp.

2435 {
2436  for( auto& t : m_templates )
2437  delete t.second;
2438 
2439  m_templates.clear();
2440 }
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 2964 of file eagle_plugin.cpp.

2965 {
2966  static const int unknown = -1;
2967  auto it = m_eagleLayersIds.find( aLayerName );
2968  return it == m_eagleLayersIds.end() ? unknown : it->second;
2969 }
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 2956 of file eagle_plugin.cpp.

2957 {
2958  static const wxString unknown( "unknown" );
2959  auto it = m_eagleLayers.find( aLayer );
2960  return it == m_eagleLayers.end() ? unknown : it->second.name;
2961 }
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 3095 of file eagle_plugin.cpp.

3097 {
3098  wxString errorMsg;
3099 
3100  init( aProperties );
3101 
3102  try
3103  {
3104  cacheLib( aLibraryPath );
3105  }
3106  catch( const IO_ERROR& ioe )
3107  {
3108  errorMsg = ioe.What();
3109  }
3110 
3111  // Some of the files may have been parsed correctly so we want to add the valid files to
3112  // the library.
3113 
3114  for( FOOTPRINT_MAP::const_iterator it = m_templates.begin(); it != m_templates.end(); ++it )
3115  aFootprintNames.Add( FROM_UTF8( it->first.c_str() ) );
3116 
3117  if( !errorMsg.IsEmpty() && !aBestEfforts )
3118  THROW_IO_ERROR( errorMsg );
3119 }
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 3140 of file eagle_plugin.cpp.

3141 {
3142  PLUGIN::FootprintLibOptions( aListToAppendTo );
3143 }
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 3122 of file eagle_plugin.cpp.

3125 {
3126  init( aProperties );
3127  cacheLib( aLibraryPath );
3128  FOOTPRINT_MAP::const_iterator it = m_templates.find( aFootprintName );
3129 
3130  if( it == m_templates.end() )
3131  return nullptr;
3132 
3133  // Return a copy of the template
3134  FOOTPRINT* copy = (FOOTPRINT*) it->second->Duplicate();
3135  copy->SetParent( nullptr );
3136  return copy;
3137 }
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 2996 of file eagle_plugin.cpp.

2997 {
2998  // File hasn't been loaded yet.
2999  if( aPath.IsEmpty() )
3000  return wxDateTime::Now();
3001 
3002  wxFileName fn( aPath );
3003 
3004  if( fn.IsFileReadable() )
3005  return fn.GetModificationTime();
3006  else
3007  return wxDateTime( 0.0 );
3008 }

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 2820 of file eagle_plugin.cpp.

2821 {
2822  auto result = m_layer_map.find( eagle_layer_name( aEagleLayer ) );
2823  return result == m_layer_map.end() ? UNDEFINED_LAYER : result->second;
2824 }
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(), 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( "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( "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 += "\[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 2443 of file eagle_plugin.cpp.

2444 {
2446 
2447  m_xpath->push( "classes.class", "number" );
2448 
2449  std::vector<ECLASS> eClasses;
2450  wxXmlNode* classNode = aClasses->GetChildren();
2451 
2452  while( classNode )
2453  {
2454  checkpoint();
2455 
2456  ECLASS eClass( classNode );
2457  NETCLASSPTR netclass;
2458 
2459  if( eClass.name.CmpNoCase( "default" ) == 0 )
2460  {
2461  netclass = bds.GetNetClasses().GetDefault();
2462  }
2463  else
2464  {
2465  netclass.reset( new NETCLASS( eClass.name ) );
2466  m_board->GetDesignSettings().GetNetClasses().Add( netclass );
2467  }
2468 
2469  netclass->SetTrackWidth( INT_MAX );
2470  netclass->SetViaDiameter( INT_MAX );
2471  netclass->SetViaDrill( INT_MAX );
2472 
2473  eClasses.emplace_back( eClass );
2474  m_classMap[ eClass.number ] = netclass;
2475 
2476  // Get next class
2477  classNode = classNode->GetNext();
2478  }
2479 
2480  m_customRules = "(version 1)";
2481 
2482  for( ECLASS& eClass : eClasses )
2483  {
2484  for( std::pair<const wxString&, ECOORD> entry : eClass.clearanceMap )
2485  {
2486  if( m_classMap[ entry.first ] != nullptr )
2487  {
2488  wxString rule;
2489  rule.Printf( "(rule \"class %s:%s\"\n"
2490  " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2491  " (constraint clearance (min %smm)))\n",
2492  eClass.number,
2493  entry.first,
2494  eClass.name,
2495  m_classMap[ entry.first ]->GetName(),
2496  StringFromValue( EDA_UNITS::MILLIMETRES, entry.second.ToPcbUnits() ) );
2497 
2498  m_customRules += "\n" + rule;
2499  }
2500  }
2501  }
2502 
2503  m_xpath->pop(); // "classes.class"
2504 }
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 1124 of file eagle_plugin.cpp.

1125 {
1126  if( !aElements )
1127  return;
1128 
1129  m_xpath->push( "elements.element", "name" );
1130 
1131  EATTR name;
1132  EATTR value;
1133  bool refanceNamePresetInPackageLayout;
1134  bool valueNamePresetInPackageLayout;
1135 
1136  // Get the first element and iterate
1137  wxXmlNode* element = aElements->GetChildren();
1138 
1139  while( element )
1140  {
1141  checkpoint();
1142 
1143  if( element->GetName() != "element" )
1144  {
1145  // Get next item
1146  element = element->GetNext();
1147  continue;
1148  }
1149 
1150  EELEMENT e( element );
1151 
1152  // use "NULL-ness" as an indication of presence of the attribute:
1153  EATTR* nameAttr = nullptr;
1154  EATTR* valueAttr = nullptr;
1155 
1156  m_xpath->Value( e.name.c_str() );
1157 
1158  wxString pkg_key = makeKey( e.library, e.package );
1159 
1160  FOOTPRINT_MAP::const_iterator it = m_templates.find( pkg_key );
1161 
1162  if( it == m_templates.end() )
1163  {
1164  wxString emsg = wxString::Format( _( "No '%s' package in library '%s'." ),
1165  FROM_UTF8( e.package.c_str() ),
1166  FROM_UTF8( e.library.c_str() ) );
1167  THROW_IO_ERROR( emsg );
1168  }
1169 
1170  FOOTPRINT* footprint = static_cast<FOOTPRINT*>( it->second->Duplicate() );
1171 
1172  m_board->Add( footprint, ADD_MODE::APPEND );
1173 
1174  // update the nets within the pads of the clone
1175  for( PAD* pad : footprint->Pads() )
1176  {
1177  wxString pn_key = makeKey( e.name, pad->GetNumber() );
1178 
1179  NET_MAP_CITER ni = m_pads_to_nets.find( pn_key );
1180  if( ni != m_pads_to_nets.end() )
1181  {
1182  const ENET* enet = &ni->second;
1183  pad->SetNetCode( enet->netcode );
1184  }
1185  }
1186 
1187  refanceNamePresetInPackageLayout = true;
1188  valueNamePresetInPackageLayout = true;
1189  footprint->SetPosition( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
1190 
1191  // Is >NAME field set in package layout ?
1192  if( footprint->GetReference().size() == 0 )
1193  {
1194  footprint->Reference().SetVisible( false ); // No so no show
1195  refanceNamePresetInPackageLayout = false;
1196  }
1197 
1198  // Is >VALUE field set in package layout
1199  if( footprint->GetValue().size() == 0 )
1200  {
1201  footprint->Value().SetVisible( false ); // No so no show
1202  valueNamePresetInPackageLayout = false;
1203  }
1204 
1205  footprint->SetReference( FROM_UTF8( e.name.c_str() ) );
1206  footprint->SetValue( FROM_UTF8( e.value.c_str() ) );
1207 
1208  if( !e.smashed )
1209  {
1210  // Not smashed so show NAME & VALUE
1211  if( valueNamePresetInPackageLayout )
1212  footprint->Value().SetVisible( true ); // Only if place holder in package layout
1213 
1214  if( refanceNamePresetInPackageLayout )
1215  footprint->Reference().SetVisible( true ); // Only if place holder in package layout
1216  }
1217  else if( *e.smashed == true )
1218  {
1219  // Smashed so set default to no show for NAME and VALUE
1220  footprint->Value().SetVisible( false );
1221  footprint->Reference().SetVisible( false );
1222 
1223  // initialize these to default values in case the <attribute> elements are not present.
1224  m_xpath->push( "attribute", "name" );
1225 
1226  // VALUE and NAME can have something like our text "effects" overrides
1227  // in SWEET and new schematic. Eagle calls these XML elements "attribute".
1228  // There can be one for NAME and/or VALUE both. Features present in the
1229  // EATTR override the ones established in the package only if they are
1230  // present here (except for rot, which if not present means angle zero).
1231  // So the logic is a bit different than in packageText() and in plain text.
1232 
1233  // Get the first attribute and iterate
1234  wxXmlNode* attribute = element->GetChildren();
1235 
1236  while( attribute )
1237  {
1238  if( attribute->GetName() != "attribute" )
1239  {
1240  attribute = attribute->GetNext();
1241  continue;
1242  }
1243 
1244  EATTR a( attribute );
1245 
1246  if( a.name == "NAME" )
1247  {
1248  name = a;
1249  nameAttr = &name;
1250 
1251  // do we have a display attribute ?
1252  if( a.display )
1253  {
1254  // Yes!
1255  switch( *a.display )
1256  {
1257  case EATTR::VALUE :
1258  {
1259  wxString reference = e.name;
1260 
1261  // EAGLE allows references to be single digits. This breaks KiCad
1262  // netlisting, which requires parts to have non-digit + digit
1263  // annotation. If the reference begins with a number, we prepend
1264  // 'UNK' (unknown) for the symbol designator.
1265  if( reference.find_first_not_of( "0123456789" ) == wxString::npos )
1266  reference.Prepend( "UNK" );
1267 
1268  nameAttr->name = reference;
1269  footprint->SetReference( reference );
1270 
1271  if( refanceNamePresetInPackageLayout )
1272  footprint->Reference().SetVisible( true );
1273 
1274  break;
1275  }
1276 
1277  case EATTR::NAME :
1278  if( refanceNamePresetInPackageLayout )
1279  {
1280  footprint->SetReference( "NAME" );
1281  footprint->Reference().SetVisible( true );
1282  }
1283 
1284  break;
1285 
1286  case EATTR::BOTH :
1287  if( refanceNamePresetInPackageLayout )
1288  footprint->Reference().SetVisible( true );
1289 
1290  nameAttr->name = nameAttr->name + " = " + e.name;
1291  footprint->SetReference( "NAME = " + e.name );
1292  break;
1293 
1294  case EATTR::Off :
1295  footprint->Reference().SetVisible( false );
1296  break;
1297 
1298  default:
1299  nameAttr->name = e.name;
1300 
1301  if( refanceNamePresetInPackageLayout )
1302  footprint->Reference().SetVisible( true );
1303  }
1304  }
1305  else
1306  {
1307  // No display, so default is visible, and show value of NAME
1308  footprint->Reference().SetVisible( true );
1309  }
1310  }
1311  else if( a.name == "VALUE" )
1312  {
1313  value = a;
1314  valueAttr = &value;
1315 
1316  if( a.display )
1317  {
1318  // Yes!
1319  switch( *a.display )
1320  {
1321  case EATTR::VALUE :
1322  valueAttr->value = opt_wxString( e.value );
1323  footprint->SetValue( e.value );
1324 
1325  if( valueNamePresetInPackageLayout )
1326  footprint->Value().SetVisible( true );
1327 
1328  break;
1329 
1330  case EATTR::NAME :
1331  if( valueNamePresetInPackageLayout )
1332  footprint->Value().SetVisible( true );
1333 
1334  footprint->SetValue( "VALUE" );
1335  break;
1336 
1337  case EATTR::BOTH :
1338  if( valueNamePresetInPackageLayout )
1339  footprint->Value().SetVisible( true );
1340 
1341  valueAttr->value = opt_wxString( "VALUE = " + e.value );
1342  footprint->SetValue( "VALUE = " + e.value );
1343  break;
1344 
1345  case EATTR::Off :
1346  footprint->Value().SetVisible( false );
1347  break;
1348 
1349  default:
1350  valueAttr->value = opt_wxString( e.value );
1351 
1352  if( valueNamePresetInPackageLayout )
1353  footprint->Value().SetVisible( true );
1354  }
1355  }
1356  else
1357  {
1358  // No display, so default is visible, and show value of NAME
1359  footprint->Value().SetVisible( true );
1360  }
1361 
1362  }
1363 
1364  attribute = attribute->GetNext();
1365  }
1366 
1367  m_xpath->pop(); // "attribute"
1368  }
1369 
1370  orientFootprintAndText( footprint, e, nameAttr, valueAttr );
1371 
1372  // Set the local coordinates for the footprint text items
1373  footprint->Reference().SetLocalCoord();
1374  footprint->Value().SetLocalCoord();
1375 
1376  // Get next element
1377  element = element->GetNext();
1378  }
1379 
1380  m_xpath->pop(); // "elements.element"
1381 }
void SetReference(const wxString &aReference)
Definition: footprint.h:473
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:486
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:500
OPTIONAL_XML_ATTRIBUTE< wxString > opt_wxString
Definition: eagle_parser.h:365
FP_TEXT & Reference()
Definition: footprint.h:501
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:464
#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:494
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:1561
#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 1101 of file eagle_plugin.cpp.

1102 {
1103  if( !aLibs )
1104  return;
1105 
1106  m_xpath->push( "libraries.library", "name" );
1107 
1108  // Get the first library and iterate
1109  wxXmlNode* library = aLibs->GetChildren();
1110 
1111  while( library )
1112  {
1113  const wxString& lib_name = library->GetAttribute( "name" );
1114 
1115  m_xpath->Value( lib_name.c_str() );
1116  loadLibrary( library, &lib_name );
1117  library = library->GetNext();
1118  }
1119 
1120  m_xpath->pop();
1121 }
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 1043 of file eagle_plugin.cpp.

1044 {
1045  if( !aLib )
1046  return;
1047 
1048  // library will have <xmlattr> node, skip that and get the single packages node
1049  wxXmlNode* packages = MapChildren( aLib )["packages"];
1050 
1051  if( !packages )
1052  return;
1053 
1054  m_xpath->push( "packages" );
1055 
1056  // Create a FOOTPRINT for all the eagle packages, for use later via a copy constructor
1057  // to instantiate needed footprints in our BOARD. Save the FOOTPRINT templates in
1058  // a FOOTPRINT_MAP using a single lookup key consisting of libname+pkgname.
1059 
1060  // Get the first package and iterate
1061  wxXmlNode* package = packages->GetChildren();
1062 
1063  while( package )
1064  {
1065  checkpoint();
1066 
1067  m_xpath->push( "package", "name" );
1068 
1069  wxString pack_ref = package->GetAttribute( "name" );
1070  ReplaceIllegalFileNameChars( pack_ref, '_' );
1071 
1072  m_xpath->Value( pack_ref.ToUTF8() );
1073 
1074  wxString key = aLibName ? makeKey( *aLibName, pack_ref ) : pack_ref;
1075 
1076  FOOTPRINT* m = makeFootprint( package, pack_ref );
1077 
1078  // add the templating FOOTPRINT to the FOOTPRINT template factory "m_templates"
1079  std::pair<FOOTPRINT_MAP::iterator, bool> r = m_templates.insert( {key, m} );
1080 
1081  if( !r.second /* && !( m_props && m_props->Value( "ignore_duplicates" ) ) */ )
1082  {
1083  wxString lib = aLibName ? *aLibName : m_lib_path;
1084  const wxString& pkg = pack_ref;
1085 
1086  wxString emsg = wxString::Format( _( "<package> '%s' duplicated in <library> '%s'" ),
1087  pkg,
1088  lib );
1089  THROW_IO_ERROR( emsg );
1090  }
1091 
1092  m_xpath->pop();
1093 
1094  package = package->GetNext();
1095  }
1096 
1097  m_xpath->pop(); // "packages"
1098 }
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 == "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 == "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 == "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 == "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 == "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( "@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 == "frame" )
974  {
975  // picture this
976  }
977  else if( grName == "polygon" )
978  {
979  m_xpath->push( "polygon" );
980  loadPolygon( gr );
981  m_xpath->pop(); // "polygon"
982  }
983  else if( grName == "dimension" )
984  {
985  EDIMENSION d( gr );
986  PCB_LAYER_ID layer = kicad_layer( d.layer );
987 
988  if( layer != UNDEFINED_LAYER )
989  {
990  const BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
991  PCB_DIM_ALIGNED* dimension = new PCB_DIM_ALIGNED( m_board );
992  m_board->Add( dimension, ADD_MODE::APPEND );
993 
994  if( d.dimensionType )
995  {
996  // Eagle dimension graphic arms may have different lengths, but they look
997  // incorrect in KiCad (the graphic is tilted). Make them even length in
998  // such case.
999  if( *d.dimensionType == "horizontal" )
1000  {
1001  int newY = ( d.y1.ToPcbUnits() + d.y2.ToPcbUnits() ) / 2;
1002  d.y1 = ECOORD( newY, ECOORD::EAGLE_UNIT::EU_NM );
1003  d.y2 = ECOORD( newY, ECOORD::EAGLE_UNIT::EU_NM );
1004  }
1005  else if( *d.dimensionType == "vertical" )
1006  {
1007  int newX = ( d.x1.ToPcbUnits() + d.x2.ToPcbUnits() ) / 2;
1008  d.x1 = ECOORD( newX, ECOORD::EAGLE_UNIT::EU_NM );
1009  d.x2 = ECOORD( newX, ECOORD::EAGLE_UNIT::EU_NM );
1010  }
1011  }
1012 
1013  dimension->SetLayer( layer );
1014  dimension->SetPrecision( DIMENSION_PRECISION );
1015 
1016  // The origin and end are assumed to always be in this order from eagle
1017  dimension->SetStart( wxPoint( kicad_x( d.x1 ), kicad_y( d.y1 ) ) );
1018  dimension->SetEnd( wxPoint( kicad_x( d.x2 ), kicad_y( d.y2 ) ) );
1019  dimension->Text().SetTextSize( designSettings.GetTextSize( layer ) );
1020  dimension->Text().SetTextThickness( designSettings.GetTextThickness( layer ) );
1021  dimension->SetLineThickness( designSettings.GetLineThickness( layer ) );
1022  dimension->SetUnits( EDA_UNITS::MILLIMETRES );
1023 
1024  // check which axis the dimension runs in
1025  // because the "height" of the dimension is perpendicular to that axis
1026  // Note the check is just if two axes are close enough to each other
1027  // Eagle appears to have some rounding errors
1028  if( abs( ( d.x1 - d.x2 ).ToPcbUnits() ) < 50000 ) // 50000 nm = 0.05 mm
1029  dimension->SetHeight( kicad_x( d.x3 - d.x1 ) );
1030  else
1031  dimension->SetHeight( kicad_y( d.y3 - d.y1 ) );
1032  }
1033  }
1034 
1035  // Get next graphic
1036  gr = gr->GetNext();
1037  }
1038 
1039  m_xpath->pop();
1040 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:209
void SetReference(const wxString &aReference)
Definition: footprint.h:473
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
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:83
void SetEnd(const wxPoint &aEnd)
Definition: eda_shape.h:126
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:163
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:910
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:525
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
int GetTextThickness(PCB_LAYER_ID aLayer) const
Return the default text thickness from the layer class for the given layer.
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:501
void SetStart(const wxPoint &aStart)
Definition: eda_shape.h:101
void Rotate(const wxPoint &aCentre, double aAngle) override
Move the outlines.
Definition: zone.cpp:721
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:597
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
static int GetDefaultHatchPitch()
Definition: zone.cpp:1102
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:88
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:797
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:850
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:91
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
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(), BOARD_DESIGN_SETTINGS::GetLineThickness(), ZONE::GetPosition(), BOARD_DESIGN_SETTINGS::GetTextSize(), BOARD_DESIGN_SETTINGS::GetTextThickness(), 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_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, 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, ECIRCLE::x, ETEXT::x, EWIRE::x1, EDIMENSION::x1, EWIRE::x2, EDIMENSION::x2, EDIMENSION::x3, 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 1384 of file eagle_plugin.cpp.

1385 {
1386  EPOLYGON p( aPolyNode );
1387  PCB_LAYER_ID layer = kicad_layer( p.layer );
1388  ZONE* zone = nullptr;
1389  bool keepout = ( p.layer == EAGLE_LAYER::TRESTRICT
1390  || p.layer == EAGLE_LAYER::BRESTRICT
1391  || p.layer == EAGLE_LAYER::VRESTRICT );
1392 
1393  if( layer == UNDEFINED_LAYER )
1394  {
1395  wxLogMessage( wxString::Format( _( "Ignoring a polygon since Eagle layer '%s' (%d) "
1396  "was not mapped" ),
1397  eagle_layer_name( p.layer ), p.layer ) );
1398  return nullptr;
1399  }
1400 
1401  if( !IsCopperLayer( layer ) && !keepout )
1402  return nullptr;
1403 
1404  // use a "netcode = 0" type ZONE:
1405  zone = new ZONE( m_board );
1406  m_board->Add( zone, ADD_MODE::APPEND );
1407 
1408  if( !keepout )
1409  zone->SetLayer( layer );
1410  else
1411  setKeepoutSettingsToZone( zone, p.layer );
1412 
1413  // Get the first vertex and iterate
1414  wxXmlNode* vertex = aPolyNode->GetChildren();
1415  std::vector<EVERTEX> vertices;
1416 
1417  // Create a circular vector of vertices
1418  // The "curve" parameter indicates a curve from the current
1419  // to the next vertex, so we keep the first at the end as well
1420  // to allow the curve to link back
1421  while( vertex )
1422  {
1423  if( vertex->GetName() == "vertex" )
1424  vertices.emplace_back( vertex );
1425 
1426  vertex = vertex->GetNext();
1427  }
1428 
1429  vertices.push_back( vertices[0] );
1430 
1431  SHAPE_POLY_SET polygon;
1432  polygon.NewOutline();
1433 
1434  for( size_t i = 0; i < vertices.size() - 1; i++ )
1435  {
1436  EVERTEX v1 = vertices[i];
1437 
1438  // Append the corner
1439  polygon.Append( kicad_x( v1.x ), kicad_y( v1.y ) );
1440 
1441  if( v1.curve )
1442  {
1443  EVERTEX v2 = vertices[i + 1];
1444  wxPoint center = ConvertArcCenter( wxPoint( kicad_x( v1.x ), kicad_y( v1.y ) ),
1445  wxPoint( kicad_x( v2.x ), kicad_y( v2.y ) ),
1446  *v1.curve );
1447  double angle = DEG2RAD( *v1.curve );
1448  double end_angle = atan2( kicad_y( v2.y ) - center.y, kicad_x( v2.x ) - center.x );
1449  double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
1450  + pow( center.y - kicad_y( v1.y ), 2 ) );
1451 
1452  int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, *v1.curve );
1453  double delta_angle = angle / segCount;
1454 
1455  for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle );
1456  a -= delta_angle )
1457  {
1458  polygon.Append( KiROUND( radius * cos( a ) ) + center.x,
1459  KiROUND( radius * sin( a ) ) + center.y );
1460  }
1461  }
1462  }
1463 
1464  // Eagle traces the zone such that half of the pen width is outside the polygon.
1465  // We trace the zone such that the copper is completely inside.
1466  if( p.width.ToPcbUnits() > 0 )
1467  {
1468  polygon.Inflate( p.width.ToPcbUnits() / 2, 32, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
1470  }
1471 
1472  zone->AddPolygon( polygon.COutline( 0 ) );
1473 
1474  // If the pour is a cutout it needs to be set to a keepout
1475  if( p.pour == EPOLYGON::CUTOUT )
1476  {
1477  zone->SetIsRuleArea( true );
1478  zone->SetDoNotAllowVias( false );
1479  zone->SetDoNotAllowTracks( false );
1480  zone->SetDoNotAllowPads( false );
1481  zone->SetDoNotAllowFootprints( false );
1482  zone->SetDoNotAllowCopperPour( true );
1484  }
1485  else if( p.pour == EPOLYGON::HATCH )
1486  {
1487  int spacing = p.spacing ? p.spacing->ToPcbUnits() : 50 * IU_PER_MILS;
1488 
1490  zone->SetHatchThickness( p.width.ToPcbUnits() );
1491  zone->SetHatchGap( spacing - p.width.ToPcbUnits() );
1492  zone->SetHatchOrientation( 0 );
1493  }
1494 
1495  // We divide the thickness by half because we are tracing _inside_ the zone outline
1496  // This means the radius of curvature will be twice the size for an equivalent EAGLE zone
1498  p.width.ToPcbUnits() / 2 ) );
1499 
1500  if( p.isolate )
1501  zone->SetLocalClearance( p.isolate->ToPcbUnits() );
1502  else
1503  zone->SetLocalClearance( 1 ); // @todo: set minimum clearance value based on board settings
1504 
1505  // missing == yes per DTD.
1506  bool thermals = !p.thermals || *p.thermals;
1508 
1509  if( thermals )
1510  {
1511  // FIXME: eagle calculates dimensions for thermal spokes
1512  // based on what the zone is connecting to.
1513  // (i.e. width of spoke is half of the smaller side of an smd pad)
1514  // This is a basic workaround
1515  zone->SetThermalReliefGap( p.width.ToPcbUnits() + 50000 ); // 50000nm == 0.05mm
1516  zone->SetThermalReliefSpokeWidth( p.width.ToPcbUnits() + 50000 );
1517  }
1518 
1519  int rank = p.rank ? (p.max_priority - *p.rank) : p.max_priority;
1520  zone->SetPriority( rank );
1521 
1522  return zone;
1523 }
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:745
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:614
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:742
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:746
Represent a set of closed polygons.
#define _(s)
void SetDoNotAllowVias(bool aEnable)
Definition: zone.h:744
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:797
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:743
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:136
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:833
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:747
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 2507 of file eagle_plugin.cpp.

2508 {
2509  ZONES zones; // per net
2510  int netCode = 1;
2511 
2512  m_xpath->push( "signals.signal", "name" );
2513 
2514  // Get the first signal and iterate
2515  wxXmlNode* net = aSignals->GetChildren();
2516 
2517  while( net )
2518  {
2519  checkpoint();
2520 
2521  bool sawPad = false;
2522 
2523  zones.clear();
2524 
2525  const wxString& netName = escapeName( net->GetAttribute( "name" ) );
2526  NETINFO_ITEM* netInfo = new NETINFO_ITEM( m_board, netName, netCode );
2527  NETCLASSPTR netclass;
2528 
2529  if( net->HasAttribute( "class" ) )
2530  {
2531  netclass = m_classMap[ net->GetAttribute( "class" ) ];
2532 
2533  netclass->Add( netName );
2534  netInfo->SetNetClass( netclass );
2535  }
2536 
2537  m_board->Add( netInfo );
2538 
2539  m_xpath->Value( netName.c_str() );
2540 
2541  // Get the first net item and iterate
2542  wxXmlNode* netItem = net->GetChildren();
2543 
2544  // (contactref | polygon | wire | via)*
2545  while( netItem )
2546  {
2547  const wxString& itemName = netItem->GetName();
2548 
2549  if( itemName == "wire" )
2550  {
2551  m_xpath->push( "wire" );
2552 
2553  EWIRE w( netItem );
2554  PCB_LAYER_ID layer = kicad_layer( w.layer );
2555 
2556  if( IsCopperLayer( layer ) )
2557  {
2558  wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
2559  double angle = 0.0;
2560  double end_angle = 0.0;
2561  double radius = 0.0;
2562  double delta_angle = 0.0;
2563  wxPoint center;
2564 
2565  int width = w.width.ToPcbUnits();
2566 
2567  if( width < m_min_trace )
2568  m_min_trace = width;
2569 
2570  if( netclass && width < netclass->GetTrackWidth() )
2571  netclass->SetTrackWidth( width );
2572 
2573  if( w.curve )
2574  {
2575  center = ConvertArcCenter( wxPoint( kicad_x( w.x1 ), kicad_y( w.y1 ) ),
2576  wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ),
2577  *w.curve );
2578 
2579  angle = DEG2RAD( *w.curve );
2580 
2581  end_angle = atan2( kicad_y( w.y2 ) - center.y,
2582  kicad_x( w.x2 ) - center.x );
2583 
2584  radius = sqrt( pow( center.x - kicad_x( w.x1 ), 2 ) +
2585  pow( center.y - kicad_y( w.y1 ), 2 ) );
2586 
2587  int segs = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
2588  *w.curve );
2589  delta_angle = angle / segs;
2590  }
2591 
2592  while( fabs( angle ) > fabs( delta_angle ) )
2593  {
2594  wxASSERT( radius > 0.0 );
2595  wxPoint end( KiROUND( radius * cos( end_angle + angle ) + center.x ),
2596  KiROUND( radius * sin( end_angle + angle ) + center.y ) );
2597 
2598  PCB_TRACK* t = new PCB_TRACK( m_board );
2599 
2600  t->SetPosition( start );
2601  t->SetEnd( end );
2602  t->SetWidth( width );
2603  t->SetLayer( layer );
2604  t->SetNetCode( netCode );
2605 
2606  m_board->Add( t );
2607 
2608  start = end;
2609  angle -= delta_angle;
2610  }
2611 
2612  PCB_TRACK* t = new PCB_TRACK( m_board );
2613 
2614  t->SetPosition( start );
2615  t->SetEnd( wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ) );
2616  t->SetWidth( width );
2617  t->SetLayer( layer );
2618  t->SetNetCode( netCode );
2619 
2620  m_board->Add( t );
2621  }
2622  else
2623  {
2624  // put non copper wires where the sun don't shine.
2625  }
2626 
2627  m_xpath->pop();
2628  }
2629  else if( itemName == "via" )
2630  {
2631  m_xpath->push( "via" );
2632  EVIA v( netItem );
2633 
2634  if( v.layer_front_most > v.layer_back_most )
2635  std::swap( v.layer_front_most, v.layer_back_most );
2636 
2637  PCB_LAYER_ID layer_front_most = kicad_layer( v.layer_front_most );
2638  PCB_LAYER_ID layer_back_most = kicad_layer( v.layer_back_most );
2639 
2640  if( IsCopperLayer( layer_front_most ) && IsCopperLayer( layer_back_most )
2641  && layer_front_most != layer_back_most )
2642  {
2643  int kidiam;
2644  int drillz = v.drill.ToPcbUnits();
2645  PCB_VIA* via = new PCB_VIA( m_board );
2646  m_board->Add( via );
2647 
2648  if( v.diam )
2649  {
2650  kidiam = v.diam->ToPcbUnits();
2651  via->SetWidth( kidiam );
2652  }
2653  else
2654  {
2655  double annulus = drillz * m_rules->rvViaOuter; // eagle "restring"
2656  annulus = eagleClamp( m_rules->rlMinViaOuter, annulus,
2658  kidiam = KiROUND( drillz + 2 * annulus );
2659  via->SetWidth( kidiam );
2660  }
2661 
2662  via->SetDrill( drillz );
2663 
2664  // make sure the via diameter respects the restring rules
2665 
2666  if( !v.diam || via->GetWidth() <= via->GetDrill() )
2667  {
2668  double annulus =
2670  (double) ( via->GetWidth() / 2 - via->GetDrill() ),
2672  via->SetWidth( drillz + 2 * annulus );
2673  }
2674 
2675  if( kidiam < m_min_via )
2676  m_min_via = kidiam;
2677 
2678  if( netclass && kidiam < netclass->GetViaDiameter() )
2679  netclass->SetViaDiameter( kidiam );
2680 
2681  if( drillz < m_min_hole )
2682  m_min_hole = drillz;
2683 
2684  if( netclass && drillz < netclass->GetViaDrill() )
2685  netclass->SetViaDrill( drillz );
2686 
2687  if( ( kidiam - drillz ) / 2 < m_min_annulus )
2688  m_min_annulus = ( kidiam - drillz ) / 2;
2689 
2690  if( layer_front_most == F_Cu && layer_back_most == B_Cu )
2691  {
2692  via->SetViaType( VIATYPE::THROUGH );
2693  }
2697  else if( v.layer_back_most - v.layer_front_most == 1 )
2698  {
2699  via->SetViaType( VIATYPE::MICROVIA );
2700  }
2701  else
2702  {
2703  via->SetViaType( VIATYPE::BLIND_BURIED );
2704  }
2705 
2706  wxPoint pos( kicad_x( v.x ), kicad_y( v.y ) );
2707 
2708  via->SetLayerPair( layer_front_most, layer_back_most );
2709  via->SetPosition( pos );
2710  via->SetEnd( pos );
2711 
2712  via->SetNetCode( netCode );
2713  }
2714 
2715  m_xpath->pop();
2716  }
2717 
2718  else if( itemName == "contactref" )
2719  {
2720  m_xpath->push( "contactref" );
2721  // <contactref element="RN1" pad="7"/>
2722 
2723  const wxString& reference = netItem->GetAttribute( "element" );
2724  const wxString& pad = netItem->GetAttribute( "pad" );
2725  wxString key = makeKey( reference, pad ) ;
2726 
2727  m_pads_to_nets[ key ] = ENET( netCode, netName );
2728 
2729  m_xpath->pop();
2730 
2731  sawPad = true;
2732  }
2733 
2734  else if( itemName == "polygon" )
2735  {
2736  m_xpath->push( "polygon" );
2737  auto* zone = loadPolygon( netItem );
2738 
2739  if( zone )
2740  {
2741  zones.push_back( zone );
2742 
2743  if( !zone->GetIsRuleArea() )
2744  zone->SetNetCode( netCode );
2745  }
2746 
2747  m_xpath->pop(); // "polygon"
2748  }
2749 
2750  netItem = netItem->GetNext();
2751  }
2752 
2753  if( zones.size() && !sawPad )
2754  {
2755  // KiCad does not support an unconnected zone with its own non-zero netcode,
2756  // but only when assigned netcode = 0 w/o a name...
2757  for( ZONE* zone : zones )
2758  zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
2759 
2760  // therefore omit this signal/net.
2761  }
2762  else
2763  {
2764  netCode++;
2765  }
2766 
2767  // Get next signal
2768  net = net->GetNext();
2769  }
2770 
2771  m_xpath->pop(); // "signals.signal"
2772 }
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:163
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:797
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 1700 of file eagle_plugin.cpp.

1701 {
1702  std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>( m_board );
1703 
1704  LIB_ID fpID;
1705  fpID.Parse( aPkgName, true );
1706  m->SetFPID( fpID );
1707 
1708  // Get the first package item and iterate
1709  wxXmlNode* packageItem = aPackage->GetChildren();
1710 
1711  while( packageItem )
1712  {
1713  const wxString& itemName = packageItem->GetName();
1714 
1715  if( itemName == "description" )
1716  m->SetDescription( FROM_UTF8( packageItem->GetNodeContent().c_str() ) );
1717  else if( itemName == "wire" )
1718  packageWire( m.get(), packageItem );
1719  else if( itemName == "pad" )
1720  packagePad( m.get(), packageItem );
1721  else if( itemName == "text" )
1722  packageText( m.get(), packageItem );
1723  else if( itemName == "rectangle" )
1724  packageRectangle( m.get(), packageItem );
1725  else if( itemName == "polygon" )
1726  packagePolygon( m.get(), packageItem );
1727  else if( itemName == "circle" )
1728  packageCircle( m.get(), packageItem );
1729  else if( itemName == "hole" )
1730  packageHole( m.get(), packageItem, false );
1731  else if( itemName == "smd" )
1732  packageSMD( m.get(), packageItem );
1733 
1734  packageItem = packageItem->GetNext();
1735  }
1736 
1737  return m.release();
1738 }
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
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
void packageSMD(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
Handles common pad properties.

References FROM_UTF8(), 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 2790 of file eagle_plugin.cpp.

2791 {
2792  std::vector<INPUT_LAYER_DESC> inputDescs;
2793 
2794  for ( const std::pair<const int, ELAYER>& layerPair : m_eagleLayers )
2795  {
2796  const ELAYER& eLayer = layerPair.second;
2797 
2798  INPUT_LAYER_DESC layerDesc;
2799  std::tie( layerDesc.AutoMapLayer, layerDesc.PermittedLayers, layerDesc.Required ) =
2800  defaultKicadLayer( eLayer.number );
2801 
2802  if( layerDesc.AutoMapLayer == UNDEFINED_LAYER )
2803  continue; // Ignore unused copper layers
2804 
2805  layerDesc.Name = eLayer.name;
2806 
2807  inputDescs.push_back( layerDesc );
2808  }
2809 
2810  if( m_progressReporter && dynamic_cast<wxWindow*>( m_progressReporter ) )
2811  dynamic_cast<wxWindow*>( m_progressReporter )->Hide();
2812 
2813  m_layer_map = m_layer_mapping_handler( inputDescs );
2814 
2815  if( m_progressReporter && dynamic_cast<wxWindow*>( m_progressReporter ))
2816  dynamic_cast<wxWindow*>( m_progressReporter )->Show();
2817 }
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 1526 of file eagle_plugin.cpp.

1528 {
1529  if( e.rot )
1530  {
1531  if( e.rot->mirror )
1532  {
1533  double orientation = e.rot->degrees + 180.0;
1534  aFootprint->SetOrientation( orientation * 10 );
1535  aFootprint->Flip( aFootprint->GetPosition(), false );
1536  }
1537  else
1538  {
1539  aFootprint->SetOrientation( e.rot->degrees * 10 );
1540  }
1541  }
1542 
1543  orientFPText( aFootprint, e, &aFootprint->Reference(), aNameAttr );
1544  orientFPText( aFootprint, e, &aFootprint->Value(), aValueAttr );
1545 }
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:500
FP_TEXT & Reference()
Definition: footprint.h:501
void SetOrientation(double aNewAngle)
Definition: footprint.cpp:1680
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: footprint.cpp:1490
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 1548 of file eagle_plugin.cpp.

1550 {
1551  // Smashed part ?
1552  if( aAttr )
1553  {
1554  // Yes
1555  const EATTR& a = *aAttr;
1556 
1557  if( a.value )
1558  {
1559  aFPText->SetText( FROM_UTF8( a.value->c_str() ) );
1560  }
1561 
1562  if( a.x && a.y ) // OPT
1563  {
1564  wxPoint pos( kicad_x( *a.x ), kicad_y( *a.y ) );
1565  aFPText->SetTextPos( pos );
1566  }
1567 
1568  // Even though size and ratio are both optional, I am not seeing
1569  // a case where ratio is present but size is not.
1570  double ratio = 8;
1571  wxSize fontz = aFPText->GetTextSize();
1572  int textThickness = KiROUND( fontz.y * ratio / 100 );
1573 
1574  aFPText->SetTextThickness( textThickness );
1575  if( a.size )
1576  {
1577  fontz = kicad_fontz( *a.size, textThickness );
1578  aFPText->SetTextSize( fontz );
1579 
1580  if( a.ratio )
1581  ratio = *a.ratio;
1582  }
1583 
1584 
1585 
1586  int align = ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
1587 
1588  if( a.align )
1589  align = a.align;
1590 
1591  // The "rot" in a EATTR seems to be assumed to be zero if it is not
1592  // present, and this zero rotation becomes an override to the
1593  // package's text field. If they did not want zero, they specify
1594  // what they want explicitly.
1595  double degrees = a.rot ? a.rot->degrees : 0;
1596  double orient; // relative to parent
1597 
1598  int sign = 1;
1599  bool spin = false;
1600 
1601  if( a.rot )
1602  {
1603  spin = a.rot->spin;
1604  sign = a.rot->mirror ? -1 : 1;
1605  aFPText->SetMirrored( a.rot->mirror );
1606  }
1607 
1608  if( degrees == 90 || degrees == 0 || spin )
1609  {
1610  orient = degrees - aFootprint->GetOrientation() / 10;
1611  aFPText->SetTextAngle( sign * orient * 10 );
1612  }
1613  else if( degrees == 180 )
1614  {
1615  orient = 0 - aFootprint->GetOrientation() / 10;
1616  aFPText->SetTextAngle( sign * orient * 10 );
1617  align = -align;
1618  }
1619  else if( degrees == 270 )
1620  {
1621  orient = 90 - aFootprint->GetOrientation() / 10;
1622  align = -align;
1623  aFPText->SetTextAngle( sign * orient * 10 );
1624  }
1625  else
1626  {
1627  orient = 90 - degrees - aFootprint->GetOrientation() / 10;
1628  aFPText->SetTextAngle( sign * orient * 10 );
1629  }
1630 
1631  switch( align )
1632  {
1633  case ETEXT::TOP_RIGHT:
1636  break;
1637 
1638  case ETEXT::BOTTOM_LEFT:
1641  break;
1642 
1643  case ETEXT::TOP_LEFT:
1646  break;
1647 
1648  case ETEXT::BOTTOM_RIGHT:
1651  break;
1652 
1653  case ETEXT::TOP_CENTER:
1656  break;
1657 
1658  case ETEXT::BOTTOM_CENTER:
1661  break;
1662 
1663  case ETEXT::CENTER:
1666  break;
1667 
1668  case ETEXT::CENTER_LEFT:
1671  break;
1672 
1673  case ETEXT::CENTER_RIGHT:
1676  break;
1677 
1678  default:
1679  ;
1680  }
1681  }
1682  else
1683  {
1684  // Part is not smash so use Lib default for NAME/VALUE // the text is per the original
1685  // package, sans <attribute>.
1686  double degrees = ( aFPText->GetTextAngle() + aFootprint->GetOrientation() ) / 10;
1687 
1688  // @todo there are a few more cases than these to contend with:
1689  if( ( !aFPText->IsMirrored() && ( abs( degrees ) == 180 || abs( degrees ) == 270 ) )
1690  || ( aFPText->IsMirrored() && ( degrees == 360 ) ) )
1691  {
1692  // ETEXT::TOP_RIGHT:
1695  }
1696  }
1697 }
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 2206 of file eagle_plugin.cpp.

2207 {
2208  ECIRCLE e( aTree );
2209 
2210  int width = e.width.ToPcbUnits();
2211  int radius = e.radius.ToPcbUnits();
2212 
2213  if( e.layer == EAGLE_LAYER::TRESTRICT
2214  || e.layer == EAGLE_LAYER::BRESTRICT
2215  || e.layer == EAGLE_LAYER::VRESTRICT )
2216  {
2217  FP_ZONE* zone = new FP_ZONE( aFootprint );
2218  aFootprint->Add( zone, ADD_MODE::APPEND );
2219 
2220  setKeepoutSettingsToZone( zone, e.layer );
2221 
2222  // approximate circle as polygon with a edge every 10 degree
2223  wxPoint center( kicad_x( e.x ), kicad_y( e.y ) );
2224  int outlineRadius = radius + ( width / 2 );
2225 
2226  for( int angle = 0; angle < 360; angle += 10 )
2227  {
2228  wxPoint rotatedPoint( outlineRadius, 0 );
2229  RotatePoint( &rotatedPoint, angle * 10. );
2230  zone->AppendCorner( center + rotatedPoint, -1 );
2231  }
2232 
2233  if( width > 0 )
2234  {
2235  zone->NewHole();
2236  int innerRadius = radius - ( width / 2 );
2237 
2238  for( int angle = 0; angle < 360; angle += 10 )
2239  {
2240  wxPoint rotatedPoint( innerRadius, 0 );
2241  RotatePoint( &rotatedPoint, angle * 10. );
2242  zone->AppendCorner( center + rotatedPoint, 0 );
2243  }
2244  }
2245 
2247  ZONE::GetDefaultHatchPitch(), true );
2248  }
2249  else
2250  {
2251  PCB_LAYER_ID layer = kicad_layer( e.layer );
2252 
2253  if( layer == UNDEFINED_LAYER )
2254  {
2255  wxLogMessage( wxString::Format( _( "Ignoring a circle since Eagle layer '%s' (%d) "
2256  "was not mapped" ),
2257  eagle_layer_name( e.layer ), e.layer ) );
2258  return;
2259  }
2260 
2261  FP_SHAPE* gr = new FP_SHAPE( aFootprint, SHAPE_T::CIRCLE );
2262 
2263  // width == 0 means filled circle
2264  if( width <= 0 )
2265  {
2266  width = radius;
2267  radius = radius / 2;
2268  gr->SetFilled( true );
2269  }
2270 
2271  aFootprint->Add( gr );
2272  gr->SetWidth( width );
2273 
2274  switch( (int) layer )
2275  {
2276  case UNDEFINED_LAYER:
2277  layer = Cmts_User;
2278  break;
2279  default:
2280  break;
2281  }
2282 
2283  gr->SetLayer( layer );
2284  gr->SetStart0( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
2285  gr->SetEnd0( wxPoint( kicad_x( e.x ) + radius, kicad_y( e.y ) ) );
2286  gr->SetDrawCoord();
2287  }
2288 }
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:83
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:163
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:910
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:597
static int GetDefaultHatchPitch()
Definition: zone.cpp:1102
Eagle circle.
Definition: eagle_parser.h:562
#define _(s)
void SetWidth(int aWidth)
Definition: eda_shape.h:88
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:850
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:945
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 2291 of file eagle_plugin.cpp.

2292 {
2293  EHOLE e( aTree );
2294 
2295  if( e.drill.value == 0 )
2296  return;
2297 
2298  // we add a PAD_ATTRIB::NPTH pad to this footprint.
2299  PAD* pad = new PAD( aFootprint );
2300  aFootprint->Add( pad );
2301 
2302  pad->SetShape( PAD_SHAPE::CIRCLE );
2303  pad->SetAttribute( PAD_ATTRIB::NPTH );
2304 
2305  // Mechanical purpose only:
2306  // no offset, no net name, no pad name allowed
2307  // pad->SetOffset( wxPoint( 0, 0 ) );
2308  // pad->SetNumber( wxEmptyString );
2309 
2310  wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) );
2311 
2312  if( aCenter )
2313  {
2314  pad->SetPos0( wxPoint( 0, 0 ) );
2315  aFootprint->SetPosition( padpos );
2316  pad->SetPosition( padpos );
2317  }
2318  else
2319  {
2320  pad->SetPos0( padpos );
2321  pad->SetPosition( padpos + aFootprint->GetPosition() );
2322  }
2323 
2324  wxSize sz( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() );
2325 
2326  pad->SetDrillSize( sz );
2327  pad->SetSize( sz );
2328 
2329  pad->SetLayerSet( LSET::AllCuMask().set( B_Mask ).set( F_Mask ) );
2330 }
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:1561
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 1814 of file eagle_plugin.cpp.

1815 {
1816  // this is thru hole technology here, no SMDs
1817  EPAD e( aTree );
1818  int shape = EPAD::UNDEF;
1819  int eagleDrillz = e.drill.ToPcbUnits();
1820 
1821  PAD* pad = new PAD( aFootprint );
1822  aFootprint->Add( pad );
1823  transferPad( e, pad );
1824 
1825  if( e.first && *e.first && m_rules->psFirst != EPAD::UNDEF )
1826  shape = m_rules->psFirst;
1827  else if( aFootprint->GetLayer() == F_Cu && m_rules->psTop != EPAD::UNDEF )
1828  shape = m_rules->psTop;
1829  else if( aFootprint->GetLayer() == B_Cu && m_rules->psBottom != EPAD::UNDEF )
1830  shape = m_rules->psBottom;
1831 
1832  pad->SetDrillSize( wxSize( eagleDrillz, eagleDrillz ) );
1833  pad->SetLayerSet( LSET::AllCuMask() );
1834 
1835  if( eagleDrillz < m_min_hole )
1836  m_min_hole = eagleDrillz;
1837 
1838  // Solder mask
1839  if( !e.stop || *e.stop == true ) // enabled by default
1840  pad->SetLayerSet( pad->GetLayerSet().set( B_Mask ).set( F_Mask ) );
1841 
1842  if( shape == EPAD::ROUND || shape == EPAD::SQUARE || shape == EPAD::OCTAGON )
1843  e.shape = shape;
1844 
1845  if( e.shape )
1846  {
1847  switch( *e.shape )
1848  {
1849  case EPAD::ROUND:
1850  pad->SetShape( PAD_SHAPE::CIRCLE );
1851  break;
1852 
1853  case EPAD::OCTAGON:
1854  // no KiCad octagonal pad shape, use PAD_CIRCLE for now.
1855  // pad->SetShape( PAD_OCTAGON );
1856  wxASSERT( pad->GetShape() == PAD_SHAPE::CIRCLE ); // verify set in PAD constructor
1857  pad->SetShape( PAD_SHAPE::CHAMFERED_RECT );
1858  pad->SetChamferPositions( RECT_CHAMFER_ALL );
1859  pad->SetChamferRectRatio( 0.25 );
1860  break;
1861 
1862  case EPAD::LONG:
1863  pad->SetShape( PAD_SHAPE::OVAL );
1864  break;
1865 
1866  case EPAD::SQUARE:
1867  pad->SetShape( PAD_SHAPE::RECT );
1868  break;
1869 
1870  case EPAD::OFFSET:
1871  pad->SetShape( PAD_SHAPE::OVAL );
1872  break;
1873  }
1874  }
1875  else
1876  {
1877  // if shape is not present, our default is circle and that matches their default "round"
1878  }
1879 
1880  if( e.diameter && e.diameter->value > 0 )
1881  {
1882  int diameter = e.diameter->ToPcbUnits();
1883  pad->SetSize( wxSize( diameter, diameter ) );
1884  }
1885  else
1886  {
1887  double drillz = pad->GetDrillSize().x;
1888  double annulus = drillz * m_rules->rvPadTop; // copper annulus, eagle "restring"
1889  annulus = eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
1890  int diameter = KiROUND( drillz + 2 * annulus );
1891  pad->SetSize( wxSize( KiROUND( diameter ), KiROUND( diameter ) ) );
1892  }
1893 
1894  if( pad->GetShape() == PAD_SHAPE::OVAL )
1895  {
1896  // The Eagle "long" pad is wider than it is tall,
1897  // m_elongation is percent elongation
1898  wxSize sz = pad->GetSize();
1899  sz.x = ( sz.x * ( 100 + m_rules->psElongationLong ) ) / 100;
1900  pad->SetSize( sz );
1901 
1902  if( e.shape && *e.shape == EPAD::OFFSET )
1903  {
1904  int offset = KiROUND( ( sz.x - sz.y ) / 2.0 );
1905  pad->SetOffset( wxPoint( offset, 0 ) );
1906  }
1907  }
1908 
1909  if( e.rot )
1910  {
1911  pad->SetOrientation( e.rot->degrees * 10 );
1912  }
1913 }
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:142

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 2103 of file eagle_plugin.cpp.

2104 {
2105  EPOLYGON p( aTree );
2106 
2107  std::vector<wxPoint> pts;
2108 
2109  // Get the first vertex and iterate
2110  wxXmlNode* vertex = aTree->GetChildren();
2111  std::vector<EVERTEX> vertices;
2112 
2113  // Create a circular vector of vertices
2114  // The "curve" parameter indicates a curve from the current
2115  // to the next vertex, so we keep the first at the end as well
2116  // to allow the curve to link back
2117  while( vertex )
2118  {
2119  if( vertex->GetName() == "vertex" )
2120  vertices.emplace_back( vertex );
2121 
2122  vertex = vertex->GetNext();
2123  }
2124 
2125  vertices.push_back( vertices[0] );
2126 
2127  for( size_t i = 0; i < vertices.size() - 1; i++ )
2128  {
2129  EVERTEX v1 = vertices[i];
2130 
2131  // Append the corner
2132  pts.emplace_back( kicad_x( v1.x ), kicad_y( v1.y ) );
2133 
2134  if( v1.curve )
2135  {
2136  EVERTEX v2 = vertices[i + 1];
2137  wxPoint center =
2138  ConvertArcCenter( wxPoint( kicad_x( v1.x ), kicad_y( v1.y ) ),
2139  wxPoint( kicad_x( v2.x ), kicad_y( v2.y ) ), *v1.curve );
2140  double angle = DEG2RAD( *v1.curve );
2141  double end_angle = atan2( kicad_y( v2.y ) - center.y, kicad_x( v2.x ) - center.x );
2142  double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
2143  + pow( center.y - kicad_y( v1.y ), 2 ) );
2144 
2145  // Don't allow a zero-radius curve
2146  if( KiROUND( radius ) == 0 )
2147  radius = 1.0;
2148 
2149  int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, *v1.curve );
2150  double delta = angle / segCount;
2151 
2152  for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta ); a -= delta )
2153  {
2154  pts.push_back( wxPoint( KiROUND( radius * cos( a ) ),
2155  KiROUND( radius * sin( a ) ) ) + center );
2156  }
2157  }
2158  }
2159 
2160  if( p.layer == EAGLE_LAYER::TRESTRICT
2161  || p.layer == EAGLE_LAYER::BRESTRICT
2162  || p.layer == EAGLE_LAYER::VRESTRICT )
2163  {
2164  FP_ZONE* zone = new FP_ZONE( aFootprint );
2165  aFootprint->Add( zone, ADD_MODE::APPEND );
2166 
2167  setKeepoutSettingsToZone( zone, p.layer );
2168 
2169  SHAPE_LINE_CHAIN outline( pts );
2170  outline.SetClosed( true );
2171  zone->Outline()->AddOutline( outline );
2172 
2174  ZONE::GetDefaultHatchPitch(), true );
2175  }
2176  else
2177  {
2178  PCB_LAYER_ID layer = kicad_layer( p.layer );
2179 
2180  if( layer == UNDEFINED_LAYER )
2181  {
2182  wxLogMessage( wxString::Format( _( "Ignoring a polygon since Eagle layer '%s' (%d) "
2183  "was not mapped" ),
2184  eagle_layer_name( p.layer ), p.layer ) );
2185  return;
2186  }
2187 
2188  FP_SHAPE* dwg = new FP_SHAPE( aFootprint, SHAPE_T::POLY );
2189 
2190  aFootprint->Add( dwg );
2191 
2192  dwg->SetWidth( 0 ); // it's filled, no need for boundary width
2193  dwg->SetFilled( true );
2194  dwg->SetLayer( layer );
2195 
2196  dwg->SetPolyPoints( pts );
2197  dwg->SetStart0( *pts.begin() );
2198  dwg->SetEnd0( pts.back() );
2199  dwg->SetDrawCoord();
2200  dwg->GetPolyShape().Inflate( p.width.ToPcbUnits() / 2, 32,
2202  }
2203 }
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:83
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:163
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:910
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:1102
#define _(s)
void SetWidth(int aWidth)
Definition: eda_shape.h:88
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:207
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:1063
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:945
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 2034 of file eagle_plugin.cpp.

2035 {
2036  ERECT r( aTree );
2037 
2038  if( r.layer == EAGLE_LAYER::TRESTRICT || r.layer == EAGLE_LAYER::BRESTRICT
2039  || r.layer == EAGLE_LAYER::VRESTRICT )
2040  {
2041  FP_ZONE* zone = new FP_ZONE( aFootprint );
2042  aFootprint->Add( zone, ADD_MODE::APPEND );
2043 
2044  setKeepoutSettingsToZone( zone, r.layer );
2045 
2046  const int outlineIdx = -1; // this is the id of the copper zone main outline
2047  zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ), outlineIdx );
2048  zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ), outlineIdx );
2049  zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ), outlineIdx );
2050  zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ), outlineIdx );
2051 
2052  if( r.rot )
2053  {
2054  wxPoint center( ( kicad_x( r.x1 ) + kicad_x( r.x2 ) ) / 2,
2055  ( kicad_y( r.y1 ) + kicad_y( r.y2 ) ) / 2 );
2056  zone->Rotate( center, r.rot->degrees * 10 );
2057  }
2058 
2060  ZONE::GetDefaultHatchPitch(), true );
2061  }
2062  else
2063  {
2064  PCB_LAYER_ID layer = kicad_layer( r.layer );
2065 
2066  if( layer == UNDEFINED_LAYER )
2067  {
2068  wxLogMessage( wxString::Format( _( "Ignoring a rectangle since Eagle layer '%s' (%d) "
2069  "was not mapped" ),
2070  eagle_layer_name( r.layer ), r.layer ) );
2071  return;
2072  }
2073 
2074  FP_SHAPE* dwg = new FP_SHAPE( aFootprint, SHAPE_T::POLY );
2075 
2076  aFootprint->Add( dwg );
2077 
2078  dwg->SetLayer( layer );
2079  dwg->SetWidth( 0 );
2080  dwg->SetFilled( true );
2081 
2082  std::vector<wxPoint> pts;
2083 
2084  wxPoint start( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ) );
2085  wxPoint end( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
2086 
2087  pts.push_back( start );
2088  pts.emplace_back( kicad_x( r.x2 ), kicad_y( r.y1 ) );
2089  pts.emplace_back( kicad_x( r.x2 ), kicad_y( r.y2 ) );
2090  pts.push_back( end );
2091 
2092  dwg->SetPolyPoints( pts );
2093 
2094  dwg->SetStart0( start );
2095  dwg->SetEnd0( end );
2096 
2097  if( r.rot )
2098  dwg->Rotate( dwg->GetCenter(), r.rot->degrees * 10 );
2099  }
2100 }
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:83
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:163
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:910
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:721
static int GetDefaultHatchPitch()
Definition: zone.cpp:1102
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
Definition: fp_shape.cpp:326
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:88
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:1063
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:850
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:945
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 2333 of file eagle_plugin.cpp.

2334 {
2335  ESMD e( aTree );
2336  PCB_LAYER_ID layer = kicad_layer( e.layer );
2337 
2338  if( !IsCopperLayer( layer ) || e.dx.value == 0 || e.dy.value == 0 )
2339  return;
2340 
2341  PAD* pad = new PAD( aFootprint );
2342  aFootprint->Add( pad );
2343  transferPad( e, pad );
2344 
2345  pad->SetShape( PAD_SHAPE::RECT );
2346  pad->SetAttribute( PAD_ATTRIB::SMD );
2347 
2348  wxSize padSize( e.dx.ToPcbUnits(), e.dy.ToPcbUnits() );
2349  pad->SetSize( padSize );
2350  pad->SetLayer( layer );
2351 
2352  const LSET front( 3, F_Cu, F_Paste, F_Mask );
2353  const LSET back( 3, B_Cu, B_Paste, B_Mask );
2354 
2355  if( layer == F_Cu )
2356  pad->SetLayerSet( front );
2357  else if( layer == B_Cu )
2358  pad->SetLayerSet( back );
2359 
2360  int minPadSize = std::min( padSize.x, padSize.y );
2361 
2362  // Rounded rectangle pads
2363  int roundRadius =
2364  eagleClamp( m_rules->srMinRoundness * 2, (int) ( minPadSize * m_rules->srRoundness ),
2365  m_rules->srMaxRoundness * 2 );
2366 
2367  if( e.roundness || roundRadius > 0 )
2368  {
2369  double roundRatio = (double) roundRadius / minPadSize / 2.0;
2370 
2371  // Eagle uses a different definition of roundness, hence division by 200
2372  if( e.roundness )
2373  roundRatio = std::fmax( *e.roundness / 200.0, roundRatio );
2374 
2375  pad->SetShape( PAD_SHAPE::ROUNDRECT );
2376  pad->SetRoundRectRadiusRatio( roundRatio );
2377  }
2378 
2379  if( e.rot )
2380  pad->SetOrientation( e.rot->degrees * 10 );
2381 
2382  pad->SetLocalSolderPasteMargin( -eagleClamp( m_rules->mlMinCreamFrame,
2383  (int) ( m_rules->mvCreamFrame * minPadSize ),
2384  m_rules->mlMaxCreamFrame ) );
2385 
2386  // Solder mask
2387  if( e.stop && *e.stop == false ) // enabled by default
2388  {
2389  if( layer == F_Cu )
2390  pad->SetLayerSet( pad->GetLayerSet().set( F_Mask, false ) );
2391  else if( layer == B_Cu )
2392  pad->SetLayerSet( pad->GetLayerSet().set( B_Mask, false ) );
2393  }
2394 
2395  // Solder paste (only for SMD pads)
2396  if( e.cream && *e.cream == false ) // enabled by default
2397  {
2398  if( layer == F_Cu )
2399  pad->SetLayerSet( pad->GetLayerSet().set( F_Paste, false ) );
2400  else if( layer == B_Cu )
2401  pad->SetLayerSet( pad->GetLayerSet().set( B_Paste, false ) );
2402  }
2403 }
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:505
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:797
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 1916 of file eagle_plugin.cpp.

1917 {
1918  ETEXT t( aTree );
1919  PCB_LAYER_ID layer = kicad_layer( t.layer );
1920 
1921  if( layer == UNDEFINED_LAYER )
1922  {
1923  wxLogMessage( wxString::Format( _( "Ignoring a text since Eagle layer '%s' (%d) "
1924  "was not mapped" ),
1925  eagle_layer_name( t.layer ), t.layer ) );
1926  return;
1927  }
1928 
1929  FP_TEXT* txt;
1930 
1931  if( t.text.MakeUpper() == ">NAME" )
1932  txt = &aFootprint->Reference();
1933  else if( t.text.MakeUpper() == ">VALUE" )
1934  txt = &aFootprint->Value();
1935  else
1936  {
1937  // FIXME: graphical text items are rotated for some reason.
1938  txt = new FP_TEXT( aFootprint );
1939  aFootprint->Add( txt );
1940  }
1941 
1942  txt->SetText( FROM_UTF8( t.text.c_str() ) );
1943 
1944  wxPoint pos( kicad_x( t.x ), kicad_y( t.y ) );
1945 
1946  txt->SetTextPos( pos );
1947  txt->SetPos0( pos - aFootprint->GetPosition() );
1948 
1949  txt->SetLayer( layer );
1950 
1951  double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
1952  int textThickness = KiROUND( t.size.ToPcbUnits() * ratio / 100 );
1953 
1954  txt->SetTextThickness( textThickness );
1955  txt->SetTextSize( kicad_fontz( t.size, textThickness ) );
1956 
1957  int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
1958 
1959  // An eagle package is never rotated, the DTD does not allow it.
1960  // angle -= aFootprint->GetOrienation();
1961 
1962  if( t.rot )
1963  {
1964  int sign = t.rot->mirror ? -1 : 1;
1965  txt->SetMirrored( t.rot->mirror );
1966 
1967  double degrees = t.rot->degrees;
1968 
1969  if( degrees == 90 || t.rot->spin )
1970  {
1971  txt->SetTextAngle( sign * degrees * 10 );
1972  }
1973  else if( degrees == 180 )
1974  {
1975  align = ETEXT::TOP_RIGHT;
1976  }
1977  else if( degrees == 270 )
1978  {
1979  align = ETEXT::TOP_RIGHT;
1980  txt->SetTextAngle( sign * 90 * 10 );
1981  }
1982  }
1983 
1984  switch( align )
1985  {
1986  case ETEXT::CENTER:
1989  break;
1990 
1991  case ETEXT::CENTER_LEFT:
1994  break;
1995 
1996  case ETEXT::CENTER_RIGHT:
1999  break;
2000 
2001  case ETEXT::TOP_CENTER:
2004  break;
2005 
2006  case ETEXT::TOP_LEFT:
2009  break;
2010 
2011  case ETEXT::TOP_RIGHT:
2014  break;
2015 
2016  case ETEXT::BOTTOM_CENTER:
2019  break;
2020 
2021  case ETEXT::BOTTOM_LEFT:
2024  break;
2025 
2026  case ETEXT::BOTTOM_RIGHT:
2029  break;
2030  }
2031 }
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:163
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:500
FP_TEXT & Reference()
Definition: footprint.h:501
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 1741 of file eagle_plugin.cpp.

1742 {
1743  EWIRE w( aTree );
1744  PCB_LAYER_ID layer = kicad_layer( w.layer );
1745  wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
1746  wxPoint end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
1747  int width = w.width.ToPcbUnits();
1748 
1749  if( layer == UNDEFINED_LAYER )
1750  {
1751  wxLogMessage( wxString::Format( _( "Ignoring a wire since Eagle layer '%s' (%d) "
1752  "was not mapped" ),
1753  eagle_layer_name( w.layer ), w.layer ) );
1754  return;
1755  }
1756 
1757  // KiCad cannot handle zero or negative line widths which apparently have meaning in Eagle.
1758  if( width <= 0 )
1759  {
1760  BOARD* board = aFootprint->GetBoard();
1761 
1762  if( board )
1763  {
1764  width = board->GetDesignSettings().GetLineThickness( layer );
1765  }
1766  else
1767  {
1768  // When loading footprint libraries, there is no board so use the default KiCad
1769  // line widths.
1770  switch( layer )
1771  {
1772  case Edge_Cuts: width = Millimeter2iu( DEFAULT_EDGE_WIDTH ); break;
1773 
1774  case F_SilkS:
1775  case B_SilkS: width = Millimeter2iu( DEFAULT_SILK_LINE_WIDTH ); break;
1776 
1777  case F_CrtYd:
1778  case B_CrtYd: width = Millimeter2iu( DEFAULT_COURTYARD_WIDTH ); break;
1779 
1780  default: width = Millimeter2iu( DEFAULT_LINE_WIDTH ); break;
1781  }
1782  }
1783  }
1784 
1785  // FIXME: the cap attribute is ignored because KiCad can't create lines
1786  // with flat ends.
1787  FP_SHAPE* dwg;
1788 
1789  if( !w.curve )
1790  {
1791  dwg = new FP_SHAPE( aFootprint, SHAPE_T::SEGMENT );
1792 
1793  dwg->SetStart0( start );
1794  dwg->SetEnd0( end );
1795  }
1796  else
1797  {
1798  dwg = new FP_SHAPE( aFootprint, SHAPE_T::ARC );
1799  wxPoint center = ConvertArcCenter( start, end, *w.curve );
1800 
1801  dwg->SetCenter0( center );
1802  dwg->SetStart0( start );
1803  dwg->SetArcAngleAndEnd0( *w.curve * -10.0, true ); // KiCad rotates the other way
1804  }
1805 
1806  dwg->SetLayer( layer );
1807  dwg->SetWidth( width );
1808  dwg->SetDrawCoord();
1809 
1810  aFootprint->Add( dwg );
1811 }
#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:163
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:188
#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:88
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 note on layer IDs:
Definition: layer_ids.h:65
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Eagle wire.
Definition: eagle_parser.h:491
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:36
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
static constexpr int Millimeter2iu(double mm)
void SetCenter0(const wxPoint &aPt)
Definition: fp_shape.cpp:162
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188

References _, FOOTPRINT::Add(), ARC, B_CrtYd, B_SilkS, ConvertArcCenter(), EWIRE::curve, DEFAULT_COURTYARD_WIDTH, DEFAULT_EDGE_WIDTH, DEFAULT_LINE_WIDTH, DEFAULT_SILK_LINE_WIDTH, eagle_layer_name(), Edge_Cuts, F_CrtYd, F_SilkS, Format(), BOARD_ITEM::GetBoard(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetLineThickness(), kicad_layer(), kicad_x(), kicad_y(), EWIRE::layer, Millimeter2iu(), SEGMENT, FP_SHAPE::SetArcAngleAndEnd0(), FP_SHAPE::SetCenter0(), FP_SHAPE::SetDrawCoord(), FP_SHAPE::SetEnd0(), BOARD_ITEM::SetLayer(), FP_SHAPE::SetStart0(), EDA_SHAPE::SetWidth(), ECOORD::ToPcbUnits(), UNDEFINED_LAYER, EWIRE::width, EWIRE::x1, EWIRE::x2, EWIRE::y1, and EWIRE::y2.

Referenced by makeFootprint().

◆ PluginName()

const wxString EAGLE_PLUGIN::PluginName ( ) const
overridevirtual

Return a brief hard coded name for this PLUGIN.

Implements PLUGIN.

Definition at line 300 of file eagle_plugin.cpp.

301 {
302  return wxT( "Eagle" );
303 }

◆ PrefetchLib()

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

If possible, prefetches the specified library (e.g.

performing downloads). Does not parse. Threadsafe.

This is a no-op for libraries that cannot be prefetched. Plugins that cannot prefetch need not override this; a default no-op is provided.

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.
Exceptions
IO_ERRORif there is an error prefetching the library.

Definition at line 75 of file plugin.cpp.

76 {
77 }

◆ RegisterLayerMappingCallback()

virtual void LAYER_REMAPPABLE_PLUGIN::RegisterLayerMappingCallback ( LAYER_MAPPING_HANDLER  aLayerMappingHandler)
inlinevirtualinherited

Register a different handler to be called when mapping of input layers to KiCad layers occurs.

The function is marked as virtual, so the plugins can implement extra logic (e.g., enable warnings or checks)

Parameters
aLayerMappingHandler

Reimplemented in CADSTAR_PCB_ARCHIVE_PLUGIN.

Definition at line 73 of file plugin_common_layer_mapping.h.

74  {
75