KiCad PCB EDA Suite
EAGLE_PLUGIN Class Reference

EAGLE_PLUGIN 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

Public Types

typedef int BIU
 

Public Member Functions

const wxString PluginName () const override
 Function PluginName returns a brief hard coded name for this PLUGIN. More...
 
BOARDLoad (const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=NULL) override
 Function Load loads information from some input file format that this PLUGIN implementation knows about, into either a new BOARD or an existing one. More...
 
const wxString GetFileExtension () const override
 Function GetFileExtension returns the file extension for the PLUGIN. More...
 
void FootprintEnumerate (wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const PROPERTIES *aProperties=NULL) override
 Return a list of footprint names contained within the library at aLibraryPath. More...
 
MODULEFootprintLoad (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL) override
 Function FootprintLoad loads 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
 Function IsFootprintLibWritable returns true iff the library at aLibraryPath is writable. More...
 
void FootprintLibOptions (PROPERTIES *aProperties) const override
 Function FootprintLibOptions appends supported PLUGIN options to aListToAppenTo along with internationalized descriptions. More...
 
 EAGLE_PLUGIN ()
 
 ~EAGLE_PLUGIN ()
 
virtual void Save (const wxString &aFileName, BOARD *aBoard, const PROPERTIES *aProperties=NULL)
 Function Save will 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=NULL)
 Function PrefetchLib If possible, prefetches the specified library (e.g. More...
 
virtual const MODULEGetEnumeratedFootprint (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL)
 Function GetEnumeratedFootprint 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=NULL)
 Function FootprintExists check for the existence of a footprint. More...
 
virtual void FootprintSave (const wxString &aLibraryPath, const MODULE *aFootprint, const PROPERTIES *aProperties=NULL)
 Function FootprintSave will write aModule to an existing library located at aLibraryPath. More...
 
virtual void FootprintDelete (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL)
 Function FootprintDelete deletes aFootprintName from the library at aLibraryPath. More...
 
virtual void FootprintLibCreate (const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
 Function FootprintLibCreate creates a new empty footprint library at aLibraryPath empty. More...
 
virtual bool FootprintLibDelete (const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
 Function FootprintLibDelete deletes 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...
 

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 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) const
 create a font size (fontz) from an eagle font size scalar More...
 
PCB_LAYER_ID kicad_layer (int aLayer) const
 Convert an Eagle layer to a KiCad layer. More...
 
const wxString & eagle_layer_name (int aLayer) const
 Get Eagle layer name by its number. 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 loadSignals (wxXmlNode *aSignals)
 
void loadLibrary (wxXmlNode *aLib, const wxString *aLibName)
 Function loadLibrary loads 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)
 
ZONE_CONTAINERloadPolygon (wxXmlNode *aPolyNode)
 Loads a copper or keepout polygon and adds it to the board. More...
 
void orientModuleAndText (MODULE *m, const EELEMENT &e, const EATTR *nameAttr, const EATTR *valueAttr)
 
void orientModuleText (MODULE *m, const EELEMENT &e, TEXTE_MODULE *txt, const EATTR *a)
 
void centerBoard ()
 move the BOARD into the center of the page More...
 
wxString fmtDEG (double aAngle) const
 Function fmtDEG formats an angle in a way particular to a board file format. More...
 
MODULEmakeModule (wxXmlNode *aPackage, const wxString &aPkgName) const
 Function makeModule creates a MODULE from an Eagle package. More...
 
void packageWire (MODULE *aModule, wxXmlNode *aTree) const
 
void packagePad (MODULE *aModule, wxXmlNode *aTree) const
 
void packageText (MODULE *aModule, wxXmlNode *aTree) const
 
void packageRectangle (MODULE *aModule, wxXmlNode *aTree) const
 
void packagePolygon (MODULE *aModule, wxXmlNode *aTree) const
 
void packageCircle (MODULE *aModule, wxXmlNode *aTree) const
 
void packageHole (MODULE *aModule, wxXmlNode *aTree, bool aCenter) const
 Function packageHole @parameter aModule - The KiCad module to which to assign the hole @parameter aTree - The Eagle XML node that is of type "hole" @parameter aCenter - If true, center the hole in the module and offset the module position. More...
 
void packageSMD (MODULE *aModule, wxXmlNode *aTree) const
 
void transferPad (const EPAD_COMMON &aEaglePad, D_PAD *aPad) const
 

Handles common pad properties

More...
 
void deleteTemplates ()
 

Deletes the footprint templates list

More...
 

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 layers data stored by the layer number. More...
 
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 module names from eagle "hole"s. More...
 
NET_MAP m_pads_to_nets
 net list More...
 
MODULE_MAP m_templates
 is part of a MODULE 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...
 
int m_min_trace
 smallest trace we find on Load(), in BIU. More...
 
int m_min_via
 smallest via we find on Load(), in BIU. More...
 
int m_min_via_hole
 smallest via diameter hole we find on Load(), in BIU. More...
 
wxString m_lib_path
 
wxDateTime m_mod_time
 

Detailed Description

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

Definition at line 117 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 168 of file eagle_plugin.h.

◆ ELAYERS

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

Definition at line 167 of file eagle_plugin.h.

Constructor & Destructor Documentation

◆ EAGLE_PLUGIN()

EAGLE_PLUGIN::EAGLE_PLUGIN ( )

Definition at line 183 of file eagle_plugin.cpp.

183  :
184  m_rules( new ERULES() ),
185  m_xpath( new XPATH() ),
186  m_mod_time( wxDateTime::Now() )
187 {
188  init( NULL );
189  clear_cu_map();
190 }
void clear_cu_map()
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
XPATH keeps track of what we are working on within a PTREE.
Definition: eagle_parser.h:112
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:174
#define NULL
subset of eagle.drawing.board.designrules in the XML document
Definition: eagle_plugin.h:45
wxDateTime m_mod_time
Definition: eagle_plugin.h:194

References clear_cu_map(), init(), and NULL.

◆ ~EAGLE_PLUGIN()

EAGLE_PLUGIN::~EAGLE_PLUGIN ( )

Definition at line 193 of file eagle_plugin.cpp.

194 {
195  deleteTemplates();
196  delete m_rules;
197  delete m_xpath;
198 }
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:174
void deleteTemplates()
Deletes the footprint templates list

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

2420 {
2421  try
2422  {
2423  wxDateTime modtime = getModificationTime( aLibPath );
2424 
2425  // Fixes assertions in wxWidgets debug builds for the wxDateTime object. Refresh the
2426  // cache if either of the wxDateTime objects are invalid or the last file modification
2427  // time differs from the current file modification time.
2428  bool load = !m_mod_time.IsValid() || !modtime.IsValid() || m_mod_time != modtime;
2429 
2430  if( aLibPath != m_lib_path || load )
2431  {
2432  wxXmlNode* doc;
2433  LOCALE_IO toggle; // toggles on, then off, the C locale.
2434 
2435  deleteTemplates();
2436 
2437  // Set this before completion of loading, since we rely on it for
2438  // text of an exception. Delay setting m_mod_time until after successful load
2439  // however.
2440  m_lib_path = aLibPath;
2441 
2442  // 8 bit "filename" should be encoded according to disk filename encoding,
2443  // (maybe this is current locale, maybe not, its a filesystem issue),
2444  // and is not necessarily utf8.
2445  string filename = (const char*) aLibPath.char_str( wxConvFile );
2446 
2447  // Load the document
2448  wxXmlDocument xmlDocument;
2449  wxFileName fn( filename );
2450 
2451  if( !xmlDocument.Load( fn.GetFullPath() ) )
2452  THROW_IO_ERROR( wxString::Format( _( "Unable to read file \"%s\"" ),
2453  fn.GetFullPath() ) );
2454 
2455  doc = xmlDocument.GetRoot();
2456 
2457  wxXmlNode* drawing = MapChildren( doc )["drawing"];
2458  NODE_MAP drawingChildren = MapChildren( drawing );
2459 
2460  // clear the cu map and then rebuild it.
2461  clear_cu_map();
2462 
2463  m_xpath->push( "eagle.drawing.layers" );
2464  wxXmlNode* layers = drawingChildren["layers"];
2465  loadLayerDefs( layers );
2466  m_xpath->pop();
2467 
2468  m_xpath->push( "eagle.drawing.library" );
2469  wxXmlNode* library = drawingChildren["library"];
2470  loadLibrary( library, NULL );
2471  m_xpath->pop();
2472 
2473  m_mod_time = modtime;
2474  }
2475  }
2476  catch(...){}
2477  // TODO: Handle exceptions
2478  // catch( file_parser_error fpe )
2479  // {
2480  // // for xml_parser_error, what() has the line number in it,
2481  // // but no byte offset. That should be an adequate error message.
2482  // THROW_IO_ERROR( fpe.what() );
2483  // }
2484  //
2485  // // Class ptree_error is a base class for xml_parser_error & file_parser_error,
2486  // // so one catch should be OK for all errors.
2487  // catch( ptree_error pte )
2488  // {
2489  // string errmsg = pte.what();
2490  //
2491  // errmsg += " @\n";
2492  // errmsg += m_xpath->Contents();
2493  //
2494  // THROW_IO_ERROR( errmsg );
2495  // }
2496 }
void clear_cu_map()
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:90
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:117
void loadLayerDefs(wxXmlNode *aLayers)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides 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:174
#define NULL
wxString m_lib_path
Definition: eagle_plugin.h:193
#define THROW_IO_ERROR(msg)
static wxDateTime getModificationTime(const wxString &aPath)
get a file's or dir's modification time.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:31
wxDateTime m_mod_time
Definition: eagle_plugin.h:194
void loadLibrary(wxXmlNode *aLib, const wxString *aLibName)
Function loadLibrary loads the Eagle "library" XML element, which can occur either under a "libraries...
void deleteTemplates()
Deletes the footprint templates list
void pop()
Definition: eagle_parser.h:124
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48

References _, clear_cu_map(), deleteTemplates(), Format(), getModificationTime(), loadLayerDefs(), loadLibrary(), m_lib_path, m_mod_time, m_xpath, MapChildren(), NULL, 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 2377 of file eagle_plugin.cpp.

2378 {
2379  if( m_props )
2380  {
2381  UTF8 page_width;
2382  UTF8 page_height;
2383 
2384  if( m_props->Value( "page_width", &page_width ) &&
2385  m_props->Value( "page_height", &page_height ) )
2386  {
2388 
2389  int w = atoi( page_width.c_str() );
2390  int h = atoi( page_height.c_str() );
2391 
2392  int desired_x = ( w - bbbox.GetWidth() ) / 2;
2393  int desired_y = ( h - bbbox.GetHeight() ) / 2;
2394 
2395  DBG(printf( "bbox.width:%d bbox.height:%d w:%d h:%d desired_x:%d desired_y:%d\n",
2396  bbbox.GetWidth(), bbbox.GetHeight(), w, h, desired_x, desired_y );)
2397 
2398  m_board->Move( wxPoint( desired_x - bbbox.GetX(), desired_y - bbbox.GetY() ) );
2399  }
2400  }
2401 }
UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to...
Definition: utf8.h:73
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:187
int GetX() const
Definition: eda_rect.h:111
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:791
int GetWidth() const
Definition: eda_rect.h:119
const char * c_str() const
Definition: utf8.h:107
const PROPERTIES * m_props
passed via Save() or Load(), no ownership, may be NULL.
Definition: eagle_plugin.h:186
int GetHeight() const
Definition: eda_rect.h:120
void Move(const wxPoint &aMoveVector) override
Function Move move this object.
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
int GetY() const
Definition: eda_rect.h:112
#define DBG(x)
Definition: fctsys.h:33
bool Value(const char *aName, UTF8 *aFetchedValue=NULL) const
Function Value fetches a property by aName and returns true if that property was found,...
Definition: properties.cpp:24

References UTF8::c_str(), DBG, 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().

◆ clear_cu_map()

void EAGLE_PLUGIN::clear_cu_map ( )
private

Definition at line 327 of file eagle_plugin.cpp.

328 {
329  // All cu layers are invalid until we see them in the <layers> section while
330  // loading either a board or library. See loadLayerDefs().
331  for( unsigned i = 0; i < arrayDim(m_cu_map); ++i )
332  m_cu_map[i] = -1;
333 }
int m_cu_map[17]
map eagle to kicad, cu layers only.
Definition: eagle_plugin.h:170
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:108

References arrayDim(), and m_cu_map.

Referenced by cacheLib(), and EAGLE_PLUGIN().

◆ deleteTemplates()

void EAGLE_PLUGIN::deleteTemplates ( )
private

Deletes the footprint templates list

Definition at line 2052 of file eagle_plugin.cpp.

2053 {
2054  for( auto& t : m_templates )
2055  delete t.second;
2056 
2057  m_templates.clear();
2058 }
MODULE_MAP m_templates
is part of a MODULE factory that operates using copy construction.
Definition: eagle_plugin.h:181

References m_templates.

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

◆ eagle_layer_name()

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

Get Eagle layer name by its number.

Definition at line 2369 of file eagle_plugin.cpp.

2370 {
2371  static const wxString unknown( "unknown" );
2372  auto it = m_eagleLayers.find( aLayer );
2373  return it == m_eagleLayers.end() ? unknown : it->second.name;
2374 }
std::map< int, ELAYER > m_eagleLayers
Eagle layers data stored by the layer number.
Definition: eagle_plugin.h:171

References m_eagleLayers.

Referenced by kicad_layer().

◆ fmtDEG()

wxString EAGLE_PLUGIN::fmtDEG ( double  aAngle) const
private

Function fmtDEG formats an angle in a way particular to a board file format.

This function is the opposite or complement of degParse(). One has to know what the other is doing.

◆ FootprintDelete()

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

Function FootprintDelete deletes 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 GITHUB_PLUGIN, PCB_IO, and GPCB_PLUGIN.

Definition at line 109 of file plugin.cpp.

111 {
112  // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
113  not_implemented( this, __FUNCTION__ );
114 }
static void not_implemented(PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws 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 = NULL 
)
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 2499 of file eagle_plugin.cpp.

2501 {
2502  wxString errorMsg;
2503 
2504  init( aProperties );
2505 
2506  try
2507  {
2508  cacheLib( aLibraryPath );
2509  }
2510  catch( const IO_ERROR& ioe )
2511  {
2512  errorMsg = ioe.What();
2513  }
2514 
2515  // Some of the files may have been parsed correctly so we want to add the valid files to
2516  // the library.
2517 
2518  for( MODULE_CITER it = m_templates.begin(); it != m_templates.end(); ++it )
2519  aFootprintNames.Add( FROM_UTF8( it->first.c_str() ) );
2520 
2521  if( !errorMsg.IsEmpty() && !aBestEfforts )
2522  THROW_IO_ERROR( errorMsg );
2523 }
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
void init(const PROPERTIES *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
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:33
#define THROW_IO_ERROR(msg)
MODULE_MAP::const_iterator MODULE_CITER
MODULE_MAP m_templates
is part of a MODULE factory that operates using copy construction.
Definition: eagle_plugin.h:181
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76

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 = NULL 
)
virtualinherited

Function FootprintExists check for the existence of a footprint.

Reimplemented in PCB_IO.

Definition at line 84 of file plugin.cpp.

86 {
87  // default implementation
88  return FootprintLoad( aLibraryPath, aFootprintName, aProperties ) != nullptr;
89 }
virtual MODULE * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL)
Function FootprintLoad loads a footprint having aFootprintName from the aLibraryPath containing a lib...
Definition: plugin.cpp:92

References PLUGIN::FootprintLoad().

◆ FootprintLibCreate()

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

Function FootprintLibCreate creates 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 GITHUB_PLUGIN, and PCB_IO.

Definition at line 117 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)
Function not_implemented throws 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 = NULL 
)
virtualinherited

Function FootprintLibDelete deletes 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
bool - true if library deleted, false if library did not exist.
Exceptions
IO_ERRORif there is a problem deleting an existing library.

Reimplemented in GITHUB_PLUGIN, PCB_IO, LEGACY_PLUGIN, and GPCB_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  return false;
129 }
static void not_implemented(PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws 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

Function FootprintLibOptions appends 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 that 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 2543 of file eagle_plugin.cpp.

2544 {
2545  PLUGIN::FootprintLibOptions( aListToAppendTo );
2546 
2547  /*
2548  (*aListToAppendTo)["ignore_duplicates"] = UTF8( _(
2549  "Ignore duplicately named footprints within the same Eagle library. "
2550  "Only the first similarly named footprint will be loaded."
2551  ));
2552  */
2553 }
virtual void FootprintLibOptions(PROPERTIES *aListToAppendTo) const
Function FootprintLibOptions appends supported PLUGIN options to aListToAppenTo along with internatio...
Definition: plugin.cpp:140

References PLUGIN::FootprintLibOptions().

◆ FootprintLoad()

MODULE * EAGLE_PLUGIN::FootprintLoad ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties = NULL 
)
overridevirtual

Function FootprintLoad loads 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.
Returns
MODULE* - 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 2526 of file eagle_plugin.cpp.

2528 {
2529  init( aProperties );
2530  cacheLib( aLibraryPath );
2531  MODULE_CITER mi = m_templates.find( aFootprintName );
2532 
2533  if( mi == m_templates.end() )
2534  return NULL;
2535 
2536  // copy constructor to clone the template
2537  MODULE* ret = new MODULE( *mi->second );
2538 
2539  return ret;
2540 }
void init(const PROPERTIES *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
void cacheLib(const wxString &aLibraryPath)
This PLUGIN only caches one footprint library, this determines which one.
#define NULL
MODULE_MAP::const_iterator MODULE_CITER
MODULE_MAP m_templates
is part of a MODULE factory that operates using copy construction.
Definition: eagle_plugin.h:181

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

◆ FootprintSave()

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

Function FootprintSave will write aModule 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 GITHUB_PLUGIN, and PCB_IO.

Definition at line 101 of file plugin.cpp.

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

References not_implemented().

◆ GetEnumeratedFootprint()

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

Function GetEnumeratedFootprint a version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management.

Reimplemented in PCB_IO, and GPCB_PLUGIN.

Definition at line 75 of file plugin.cpp.

78 {
79  // default implementation
80  return FootprintLoad( aLibraryPath, aFootprintName, aProperties );
81 }
virtual MODULE * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL)
Function FootprintLoad loads a footprint having aFootprintName from the aLibraryPath containing a lib...
Definition: plugin.cpp:92

References PLUGIN::FootprintLoad().

◆ GetFileExtension()

const wxString EAGLE_PLUGIN::GetFileExtension ( ) const
overridevirtual

Function GetFileExtension returns the file extension for the PLUGIN.

Implements PLUGIN.

Definition at line 207 of file eagle_plugin.cpp.

208 {
209  return wxT( "brd" );
210 }

◆ 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 135 of file eagle_plugin.h.

136  {
137  return getModificationTime( aLibraryPath ).GetValue().GetValue();
138  }
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 2404 of file eagle_plugin.cpp.

2405 {
2406  // File hasn't been loaded yet.
2407  if( aPath.IsEmpty() )
2408  return wxDateTime::Now();
2409 
2410  wxFileName fn( aPath );
2411 
2412  if( fn.IsFileReadable() )
2413  return fn.GetModificationTime();
2414  else
2415  return wxDateTime( 0.0 );
2416 }

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

310 {
311  m_hole_count = 0;
312  m_min_trace = 0;
313  m_min_via = 0;
314  m_min_via_hole = 0;
315  m_xpath->clear();
316  m_pads_to_nets.clear();
317 
318  m_board = NULL;
319  m_props = aProperties;
320 
321 
322  delete m_rules;
323  m_rules = new ERULES();
324 }
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:187
void clear()
Definition: eagle_parser.h:122
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
int m_min_via
smallest via we find on Load(), in BIU.
Definition: eagle_plugin.h:190
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:174
int m_min_via_hole
smallest via diameter hole we find on Load(), in BIU.
Definition: eagle_plugin.h:191
const PROPERTIES * m_props
passed via Save() or Load(), no ownership, may be NULL.
Definition: eagle_plugin.h:186
#define NULL
subset of eagle.drawing.board.designrules in the XML document
Definition: eagle_plugin.h:45
int m_min_trace
smallest trace we find on Load(), in BIU.
Definition: eagle_plugin.h:189
int m_hole_count
generates unique module names from eagle "hole"s.
Definition: eagle_plugin.h:177
NET_MAP m_pads_to_nets
net list
Definition: eagle_plugin.h:179

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

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

◆ IsFootprintLibWritable()

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

Function IsFootprintLibWritable returns true iff the library at aLibraryPath is writable.

(Often system libraries are 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 140 of file eagle_plugin.h.

141  {
142  return false; // until someone writes others like FootprintSave(), etc.
143  }

◆ kicad_fontz()

wxSize EAGLE_PLUGIN::kicad_fontz ( const ECOORD d) const
inlineprivate

create a font size (fontz) from an eagle font size scalar

Definition at line 213 of file eagle_plugin.cpp.

214 {
215  // texts seem to better match eagle when scaled down by 0.95
216  int kz = d.ToPcbUnits() * 95 / 100;
217  return wxSize( kz, kz );
218 }
int ToPcbUnits() const
Definition: eagle_parser.h:444

References ECOORD::ToPcbUnits().

Referenced by loadPlain(), orientModuleText(), 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 2300 of file eagle_plugin.cpp.

2301 {
2302  int kiLayer;
2303 
2304  // eagle copper layer:
2305  if( aEagleLayer >= 1 && aEagleLayer < int( arrayDim( m_cu_map ) ) )
2306  {
2307  kiLayer = m_cu_map[aEagleLayer];
2308  }
2309 
2310  else
2311  {
2312  // translate non-copper eagle layer to pcbnew layer
2313  switch( aEagleLayer )
2314  {
2315  // Eagle says "Dimension" layer, but it's for board perimeter
2316  case EAGLE_LAYER::MILLING: kiLayer = Edge_Cuts; break;
2317  case EAGLE_LAYER::DIMENSION: kiLayer = Edge_Cuts; break;
2318 
2319  case EAGLE_LAYER::TPLACE: kiLayer = F_SilkS; break;
2320  case EAGLE_LAYER::BPLACE: kiLayer = B_SilkS; break;
2321  case EAGLE_LAYER::TNAMES: kiLayer = F_SilkS; break;
2322  case EAGLE_LAYER::BNAMES: kiLayer = B_SilkS; break;
2323  case EAGLE_LAYER::TVALUES: kiLayer = F_Fab; break;
2324  case EAGLE_LAYER::BVALUES: kiLayer = B_Fab; break;
2325  case EAGLE_LAYER::TSTOP: kiLayer = F_Mask; break;
2326  case EAGLE_LAYER::BSTOP: kiLayer = B_Mask; break;
2327  case EAGLE_LAYER::TCREAM: kiLayer = F_Paste; break;
2328  case EAGLE_LAYER::BCREAM: kiLayer = B_Paste; break;
2329  case EAGLE_LAYER::TFINISH: kiLayer = F_Mask; break;
2330  case EAGLE_LAYER::BFINISH: kiLayer = B_Mask; break;
2331  case EAGLE_LAYER::TGLUE: kiLayer = F_Adhes; break;
2332  case EAGLE_LAYER::BGLUE: kiLayer = B_Adhes; break;
2333  case EAGLE_LAYER::DOCUMENT: kiLayer = Cmts_User; break;
2334  case EAGLE_LAYER::REFERENCELC: kiLayer = Cmts_User; break;
2335  case EAGLE_LAYER::REFERENCELS: kiLayer = Cmts_User; break;
2336 
2337  // Packages show the future chip pins on SMD parts using layer 51.
2338  // This is an area slightly smaller than the PAD/SMD copper area.
2339  // Carry those visual aids into the MODULE on the fabrication layer,
2340  // not silkscreen. This is perhaps not perfect, but there is not a lot
2341  // of other suitable paired layers
2342  case EAGLE_LAYER::TDOCU: kiLayer = F_Fab; break;
2343  case EAGLE_LAYER::BDOCU: kiLayer = B_Fab; break;
2344 
2345  // these layers are defined as user layers. put them on ECO layers
2346  case EAGLE_LAYER::USERLAYER1: kiLayer = Eco1_User; break;
2347  case EAGLE_LAYER::USERLAYER2: kiLayer = Eco2_User; break;
2348 
2349  case EAGLE_LAYER::UNROUTED:
2350  case EAGLE_LAYER::TKEEPOUT:
2351  case EAGLE_LAYER::BKEEPOUT:
2352  case EAGLE_LAYER::TTEST:
2353  case EAGLE_LAYER::BTEST:
2354  case EAGLE_LAYER::HOLES:
2355  default:
2356  // some layers do not map to KiCad
2357  wxLogMessage( wxString::Format( _( "Unsupported Eagle layer '%s' (%d), converted to Dwgs.User layer" ),
2358  eagle_layer_name( aEagleLayer ), aEagleLayer ) );
2359 
2360  kiLayer = Dwgs_User;
2361  break;
2362  }
2363  }
2364 
2365  return PCB_LAYER_ID( kiLayer );
2366 }
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
int m_cu_map[17]
map eagle to kicad, cu layers only.
Definition: eagle_plugin.h:170
PCB_LAYER_ID
A quick note on layer IDs:
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:108
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:31

References _, arrayDim(), B_Adhes, 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, eagle_layer_name(), Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_Fab, F_Mask, F_Paste, F_SilkS, Format(), 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, EAGLE_LAYER::UNROUTED, EAGLE_LAYER::USERLAYER1, and EAGLE_LAYER::USERLAYER2.

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 202 of file eagle_plugin.h.

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

References ECOORD::ToPcbUnits().

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

◆ Load()

BOARD * EAGLE_PLUGIN::Load ( const wxString &  aFileName,
BOARD aAppendToMe,
const PROPERTIES aProperties = NULL 
)
overridevirtual

Function Load loads 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.
Returns
BOARD* - 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 221 of file eagle_plugin.cpp.

222 {
223  LOCALE_IO toggle; // toggles on, then off, the C locale.
224  wxXmlNode* doc;
225 
226  init( aProperties );
227 
228  m_board = aAppendToMe ? aAppendToMe : new BOARD();
229 
230  // Give the filename to the board if it's new
231  if( !aAppendToMe )
232  m_board->SetFileName( aFileName );
233 
234  // delete on exception, if I own m_board, according to aAppendToMe
235  unique_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board );
236 
237  try
238  {
239  // Load the document
240  wxXmlDocument xmlDocument;
241  wxFileName fn = aFileName;
242 
243  if( !xmlDocument.Load( fn.GetFullPath() ) )
244  THROW_IO_ERROR( wxString::Format( _( "Unable to read file \"%s\"" ),
245  fn.GetFullPath() ) );
246 
247  doc = xmlDocument.GetRoot();
248 
249  m_min_trace = INT_MAX;
250  m_min_via = INT_MAX;
251  m_min_via_hole = INT_MAX;
252 
253  loadAllSections( doc );
254 
255  BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
256 
257  if( m_min_trace < designSettings.m_TrackMinWidth )
258  designSettings.m_TrackMinWidth = m_min_trace;
259 
260  if( m_min_via < designSettings.m_ViasMinSize )
261  designSettings.m_ViasMinSize = m_min_via;
262 
263  if( m_min_via_hole < designSettings.m_ViasMinDrill )
264  designSettings.m_ViasMinDrill = m_min_via_hole;
265 
266  if( m_rules->mdWireWire )
267  {
268  NETCLASSPTR defaultNetclass = designSettings.GetDefault();
269  int clearance = KiROUND( m_rules->mdWireWire );
270 
271  if( clearance < defaultNetclass->GetClearance() )
272  defaultNetclass->SetClearance( clearance );
273  }
274 
275  // should be empty, else missing m_xpath->pop()
276  wxASSERT( m_xpath->Contents().size() == 0 );
277  }
278  // Catch all exceptions thrown from the parser.
279  catch( const XML_PARSER_ERROR &exc )
280  {
281  wxString errmsg = exc.what();
282 
283  errmsg += "\n@ ";
284  errmsg += m_xpath->Contents();
285 
286  THROW_IO_ERROR( errmsg );
287  }
288 
289  // IO_ERROR exceptions are left uncaught, they pass upwards from here.
290 
291  // Ensure the copper layers count is a multiple of 2
292  // Pcbnew does not like boards with odd layers count
293  // (these boards cannot exist. they actually have a even layers count)
294  int lyrcnt = m_board->GetCopperLayerCount();
295 
296  if( (lyrcnt % 2) != 0 )
297  {
298  lyrcnt++;
299  m_board->SetCopperLayerCount( lyrcnt );
300  }
301 
302  centerBoard();
303 
304  deleter.release();
305  return m_board;
306 }
wxString Contents()
return the contents of the XPATH as a single string
Definition: eagle_parser.h:139
void loadAllSections(wxXmlNode *aDocument)
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:187
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:90
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
void SetCopperLayerCount(int aCount)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
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:190
XML_PARSER_ERROR implements a simple wrapper around runtime_error to isolate the errors thrown by the...
Definition: eagle_parser.h:70
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:174
int m_min_via_hole
smallest via diameter hole we find on Load(), in BIU.
Definition: eagle_plugin.h:191
#define NULL
int m_TrackMinWidth
track min value for width ((min copper size value
int m_ViasMinSize
vias (not micro vias) min diameter
int m_ViasMinDrill
vias (not micro vias) min drill diameter
#define THROW_IO_ERROR(msg)
void SetFileName(const wxString &aFileName)
Definition: class_board.h:213
double mdWireWire
wire to wire spacing I presume.
Definition: eagle_plugin.h:76
int m_min_trace
smallest trace we find on Load(), in BIU.
Definition: eagle_plugin.h:189
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
NETCLASSPTR GetDefault() const
Function GetDefault.
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:160
#define _(s)
Definition: 3d_actions.cpp:31
int GetCopperLayerCount() const
Function GetCopperLayerCount.
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:61
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.

References _, centerBoard(), XPATH::Contents(), Format(), BOARD::GetCopperLayerCount(), BOARD_DESIGN_SETTINGS::GetDefault(), BOARD::GetDesignSettings(), init(), KiROUND(), loadAllSections(), m_board, m_min_trace, m_min_via, m_min_via_hole, m_rules, BOARD_DESIGN_SETTINGS::m_TrackMinWidth, BOARD_DESIGN_SETTINGS::m_ViasMinDrill, BOARD_DESIGN_SETTINGS::m_ViasMinSize, m_xpath, ERULES::mdWireWire, NULL, BOARD::SetCopperLayerCount(), BOARD::SetFileName(), and THROW_IO_ERROR.

◆ loadAllSections()

void EAGLE_PLUGIN::loadAllSections ( wxXmlNode *  aDocument)
private

Definition at line 336 of file eagle_plugin.cpp.

337 {
338  wxXmlNode* drawing = MapChildren( aDoc )["drawing"];
339  NODE_MAP drawingChildren = MapChildren( drawing );
340 
341  wxXmlNode* board = drawingChildren["board"];
342  NODE_MAP boardChildren = MapChildren( board );
343 
344  m_xpath->push( "eagle.drawing" );
345 
346  {
347  m_xpath->push( "board" );
348 
349  wxXmlNode* designrules = boardChildren["designrules"];
350  loadDesignRules( designrules );
351 
352  m_xpath->pop();
353  }
354 
355  {
356  m_xpath->push( "layers" );
357 
358  wxXmlNode* layers = drawingChildren["layers"];
359  loadLayerDefs( layers );
360 
361  m_xpath->pop();
362  }
363 
364  {
365  m_xpath->push( "board" );
366 
367  wxXmlNode* plain = boardChildren["plain"];
368  loadPlain( plain );
369 
370  wxXmlNode* signals = boardChildren["signals"];
371  loadSignals( signals );
372 
373  wxXmlNode* libs = boardChildren["libraries"];
374  loadLibraries( libs );
375 
376  wxXmlNode* elems = boardChildren["elements"];
377  loadElements( elems );
378 
379  m_xpath->pop(); // "board"
380  }
381 
382  m_xpath->pop(); // "eagle.drawing"
383 }
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:117
void loadLayerDefs(wxXmlNode *aLayers)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides 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:174
void loadLibraries(wxXmlNode *aLibs)
void loadPlain(wxXmlNode *aPlain)
void loadElements(wxXmlNode *aElements)
void pop()
Definition: eagle_parser.h:124
void loadDesignRules(wxXmlNode *aDesignRules)
void loadSignals(wxXmlNode *aSignals)
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48

References loadDesignRules(), loadElements(), loadLayerDefs(), loadLibraries(), loadPlain(), loadSignals(), m_xpath, MapChildren(), XPATH::pop(), and XPATH::push().

Referenced by Load().

◆ loadDesignRules()

void EAGLE_PLUGIN::loadDesignRules ( wxXmlNode *  aDesignRules)
private

Definition at line 386 of file eagle_plugin.cpp.

387 {
388  if( aDesignRules )
389  {
390  m_xpath->push( "designrules" );
391  m_rules->parse( aDesignRules );
392  m_xpath->pop(); // "designrules"
393  }
394 }
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:117
void parse(wxXmlNode *aRules)
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:174
void pop()
Definition: eagle_parser.h:124

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

877 {
878  if( !aElements )
879  return;
880 
881  m_xpath->push( "elements.element", "name" );
882 
883  EATTR name;
884  EATTR value;
885  bool refanceNamePresetInPackageLayout;
886  bool valueNamePresetInPackageLayout;
887 
888  // Get the first element and iterate
889  wxXmlNode* element = aElements->GetChildren();
890 
891  while( element )
892  {
893  if( element->GetName() != "element" )
894  {
895  wxLogDebug( "expected: <element> read <%s>. Skip it", element->GetName() );
896  // Get next item
897  element = element->GetNext();
898  continue;
899  }
900 
901  EELEMENT e( element );
902 
903  // use "NULL-ness" as an indication of presence of the attribute:
904  EATTR* nameAttr = 0;
905  EATTR* valueAttr = 0;
906 
907  m_xpath->Value( e.name.c_str() );
908 
909  wxString pkg_key = makeKey( e.library, e.package );
910 
911  MODULE_CITER mi = m_templates.find( pkg_key );
912 
913  if( mi == m_templates.end() )
914  {
915  wxString emsg = wxString::Format( _( "No \"%s\" package in library \"%s\"" ),
916  GetChars( FROM_UTF8( e.package.c_str() ) ),
917  GetChars( FROM_UTF8( e.library.c_str() ) ) );
918  THROW_IO_ERROR( emsg );
919  }
920 
921  // copy constructor to clone the template
922  MODULE* m = new MODULE( *mi->second );
924 
925  // update the nets within the pads of the clone
926  for( auto pad : m->Pads() )
927  {
928  wxString pn_key = makeKey( e.name, pad->GetName() );
929 
930  NET_MAP_CITER ni = m_pads_to_nets.find( pn_key );
931  if( ni != m_pads_to_nets.end() )
932  {
933  const ENET* enet = &ni->second;
934  pad->SetNetCode( enet->netcode );
935  }
936  }
937 
938  refanceNamePresetInPackageLayout = true;
939  valueNamePresetInPackageLayout = true;
940  m->SetPosition( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
941 
942  // Is >NAME field set in package layout ?
943  if( m->GetReference().size() == 0 )
944  {
945  m->Reference().SetVisible( false ); // No so no show
946  refanceNamePresetInPackageLayout = false;
947  }
948 
949  // Is >VALUE field set in package layout
950  if( m->GetValue().size() == 0 )
951  {
952  m->Value().SetVisible( false ); // No so no show
953  valueNamePresetInPackageLayout = false;
954  }
955 
956  m->SetReference( FROM_UTF8( e.name.c_str() ) );
957  m->SetValue( FROM_UTF8( e.value.c_str() ) );
958 
959  if( !e.smashed )
960  { // Not smashed so show NAME & VALUE
961  if( valueNamePresetInPackageLayout )
962  m->Value().SetVisible( true ); // Only if place holder in package layout
963 
964  if( refanceNamePresetInPackageLayout )
965  m->Reference().SetVisible( true ); // Only if place holder in package layout
966  }
967  else if( *e.smashed == true )
968  { // Smashed so set default to no show for NAME and VALUE
969  m->Value().SetVisible( false );
970  m->Reference().SetVisible( false );
971 
972  // initialize these to default values in case the <attribute> elements are not present.
973  m_xpath->push( "attribute", "name" );
974 
975  // VALUE and NAME can have something like our text "effects" overrides
976  // in SWEET and new schematic. Eagle calls these XML elements "attribute".
977  // There can be one for NAME and/or VALUE both. Features present in the
978  // EATTR override the ones established in the package only if they are
979  // present here (except for rot, which if not present means angle zero).
980  // So the logic is a bit different than in packageText() and in plain text.
981 
982  // Get the first attribute and iterate
983  wxXmlNode* attribute = element->GetChildren();
984 
985  while( attribute )
986  {
987  if( attribute->GetName() != "attribute" )
988  {
989  wxLogDebug( "expected: <attribute> read <%s>. Skip it", attribute->GetName() );
990  attribute = attribute->GetNext();
991  continue;
992  }
993 
994  EATTR a( attribute );
995 
996  if( a.name == "NAME" )
997  {
998  name = a;
999  nameAttr = &name;
1000 
1001  // do we have a display attribute ?
1002  if( a.display )
1003  {
1004  // Yes!
1005  switch( *a.display )
1006  {
1007  case EATTR::VALUE :
1008  {
1009  wxString reference = e.name;
1010 
1011  // EAGLE allows references to be single digits. This breaks KiCad netlisting, which requires
1012  // parts to have non-digit + digit annotation. If the reference begins with a number,
1013  // we prepend 'UNK' (unknown) for the symbol designator
1014  if( reference.find_first_not_of( "0123456789" ) == wxString::npos )
1015  reference.Prepend( "UNK" );
1016 
1017  nameAttr->name = reference;
1018  m->SetReference( reference );
1019  if( refanceNamePresetInPackageLayout )
1020  m->Reference().SetVisible( true );
1021  break;
1022  }
1023  case EATTR::NAME :
1024  if( refanceNamePresetInPackageLayout )
1025  {
1026  m->SetReference( "NAME" );
1027  m->Reference().SetVisible( true );
1028  }
1029  break;
1030 
1031  case EATTR::BOTH :
1032  if( refanceNamePresetInPackageLayout )
1033  m->Reference().SetVisible( true );
1034  nameAttr->name = nameAttr->name + " = " + e.name;
1035  m->SetReference( "NAME = " + e.name );
1036  break;
1037 
1038  case EATTR::Off :
1039  m->Reference().SetVisible( false );
1040  break;
1041 
1042  default:
1043  nameAttr->name = e.name;
1044  if( refanceNamePresetInPackageLayout )
1045  m->Reference().SetVisible( true );
1046  }
1047  }
1048  else
1049  // No display, so default is visible, and show value of NAME
1050  m->Reference().SetVisible( true );
1051  }
1052  else if( a.name == "VALUE" )
1053  {
1054  value = a;
1055  valueAttr = &value;
1056 
1057  if( a.display )
1058  {
1059  // Yes!
1060  switch( *a.display )
1061  {
1062  case EATTR::VALUE :
1063  valueAttr->value = opt_wxString( e.value );
1064  m->SetValue( e.value );
1065  if( valueNamePresetInPackageLayout )
1066  m->Value().SetVisible( true );
1067  break;
1068 
1069  case EATTR::NAME :
1070  if( valueNamePresetInPackageLayout )
1071  m->Value().SetVisible( true );
1072  m->SetValue( "VALUE" );
1073  break;
1074 
1075  case EATTR::BOTH :
1076  if( valueNamePresetInPackageLayout )
1077  m->Value().SetVisible( true );
1078  valueAttr->value = opt_wxString( "VALUE = " + e.value );
1079  m->SetValue( "VALUE = " + e.value );
1080  break;
1081 
1082  case EATTR::Off :
1083  m->Value().SetVisible( false );
1084  break;
1085 
1086  default:
1087  valueAttr->value = opt_wxString( e.value );
1088  if( valueNamePresetInPackageLayout )
1089  m->Value().SetVisible( true );
1090  }
1091  }
1092  else
1093  // No display, so default is visible, and show value of NAME
1094  m->Value().SetVisible( true );
1095 
1096  }
1097 
1098  attribute = attribute->GetNext();
1099  }
1100 
1101  m_xpath->pop(); // "attribute"
1102  }
1103 
1104  orientModuleAndText( m, e, nameAttr, valueAttr );
1105 
1106  // Set the local coordinates for the footprint text items
1107  m->Reference().SetLocalCoord();
1108  m->Value().SetLocalCoord();
1109 
1110  // Get next element
1111  element = element->GetNext();
1112  }
1113 
1114  m_xpath->pop(); // "elements.element"
1115 }
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
TEXTE_MODULE & Reference()
Definition: class_module.h:477
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:187
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:117
Eagle element element.
Definition: eagle_parser.h:803
void SetVisible(bool aVisible)
Definition: eda_text.h:169
PADS & Pads()
Definition: class_module.h:173
const wxString GetValue() const
Function GetValue.
Definition: class_module.h:461
NET_MAP::const_iterator NET_MAP_CITER
Definition: eagle_plugin.h:41
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:174
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:436
OPTIONAL_XML_ATTRIBUTE< wxString > opt_wxString
Definition: eagle_parser.h:379
wxString name
Definition: eagle_parser.h:610
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
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.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:476
void SetReference(const wxString &aReference)
Function SetReference.
Definition: class_module.h:446
#define THROW_IO_ERROR(msg)
void SetPosition(const wxPoint &aPos) override
opt_wxString value
Definition: eagle_parser.h:611
Eagle net.
Definition: eagle_parser.h:467
void orientModuleAndText(MODULE *m, const EELEMENT &e, const EATTR *nameAttr, const EATTR *valueAttr)
EATTR parses an Eagle "attribute" XML element.
Definition: eagle_parser.h:608
void SetLocalCoord()
Set relative coordinates.
MODULE_MAP::const_iterator MODULE_CITER
int netcode
Definition: eagle_parser.h:469
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:101
const char * name
Definition: DXF_plotter.cpp:60
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:31
MODULE_MAP m_templates
is part of a MODULE factory that operates using copy construction.
Definition: eagle_plugin.h:181
void SetValue(const wxString &aValue)
Function SetValue.
Definition: class_module.h:470
NET_MAP m_pads_to_nets
net list
Definition: eagle_plugin.h:179
void pop()
Definition: eagle_parser.h:124
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:127

References _, BOARD::Add(), APPEND, EATTR::BOTH, EATTR::display, Format(), FROM_UTF8(), GetChars(), MODULE::GetReference(), MODULE::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, orientModuleAndText(), EELEMENT::package, MODULE::Pads(), XPATH::pop(), XPATH::push(), MODULE::Reference(), TEXTE_MODULE::SetLocalCoord(), MODULE::SetPosition(), MODULE::SetReference(), MODULE::SetValue(), EDA_TEXT::SetVisible(), EELEMENT::smashed, THROW_IO_ERROR, XPATH::Value(), MODULE::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 397 of file eagle_plugin.cpp.

398 {
399  if( !aLayers )
400  return;
401 
402  ELAYERS cu; // copper layers
403 
404  // Get the first layer and iterate
405  wxXmlNode* layerNode = aLayers->GetChildren();
406 
407  m_eagleLayers.clear();
408 
409  while( layerNode )
410  {
411  ELAYER elayer( layerNode );
412  m_eagleLayers.insert( std::make_pair( elayer.number, elayer ) );
413 
414  // find the subset of layers that are copper and active
415  if( elayer.number >= 1 && elayer.number <= 16 && ( !elayer.active || *elayer.active ) )
416  {
417  cu.push_back( elayer );
418  }
419 
420  layerNode = layerNode->GetNext();
421  }
422 
423  // establish cu layer map:
424  int ki_layer_count = 0;
425 
426  for( EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
427  {
428  if( ki_layer_count == 0 )
429  m_cu_map[it->number] = F_Cu;
430  else if( ki_layer_count == int( cu.size()-1 ) )
431  m_cu_map[it->number] = B_Cu;
432  else
433  {
434  // some eagle boards do not have contiguous layer number sequences.
435 
436 #if 0 // pre PCB_LAYER_ID & LSET:
437  m_cu_map[it->number] = cu.size() - 1 - ki_layer_count;
438 #else
439  m_cu_map[it->number] = ki_layer_count;
440 #endif
441  }
442  }
443 
444 #if 0 && defined(DEBUG)
445  printf( "m_cu_map:\n" );
446  for( unsigned i=0; i<arrayDim(m_cu_map); ++i )
447  {
448  printf( "\t[%d]:%d\n", i, m_cu_map[i] );
449  }
450 #endif
451 
452  // Set the layer names and cu count if we're loading a board.
453  if( m_board )
454  {
455  m_board->SetCopperLayerCount( cu.size() );
456 
457  for( EITER it = cu.begin(); it != cu.end(); ++it )
458  {
459  PCB_LAYER_ID layer = kicad_layer( it->number );
460 
461  // these function provide their own protection against UNDEFINED_LAYER:
462  m_board->SetLayerName( layer, FROM_UTF8( it->name.c_str() ) );
463  m_board->SetLayerType( layer, LT_SIGNAL );
464 
465  // could map the colors here
466  }
467  }
468 }
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:187
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void SetCopperLayerCount(int aCount)
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Function SetLayerType changes the type of the layer given by aLayer.
int m_cu_map[17]
map eagle to kicad, cu layers only.
Definition: eagle_plugin.h:170
PCB_LAYER_ID
A quick note on layer IDs:
std::map< int, ELAYER > m_eagleLayers
Eagle layers data stored by the layer number.
Definition: eagle_plugin.h:171
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Function SetLayerName changes the name of the layer given by aLayer.
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:108
std::vector< ELAYER > ELAYERS
Definition: eagle_plugin.h:167
ELAYERS::const_iterator EITER
Definition: eagle_plugin.h:168

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

Referenced by cacheLib(), and loadAllSections().

◆ loadLibraries()

void EAGLE_PLUGIN::loadLibraries ( wxXmlNode *  aLibs)
private

Definition at line 853 of file eagle_plugin.cpp.

854 {
855  if( !aLibs )
856  return;
857 
858  m_xpath->push( "libraries.library", "name" );
859 
860  // Get the first library and iterate
861  wxXmlNode* library = aLibs->GetChildren();
862 
863  while( library )
864  {
865  const wxString& lib_name = library->GetAttribute( "name" );
866 
867  m_xpath->Value( lib_name.c_str() );
868  loadLibrary( library, &lib_name );
869  library = library->GetNext();
870  }
871 
872  m_xpath->pop();
873 }
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:117
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:174
void loadLibrary(wxXmlNode *aLib, const wxString *aLibName)
Function loadLibrary loads the Eagle "library" XML element, which can occur either under a "libraries...
void pop()
Definition: eagle_parser.h:124
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:127

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

Referenced by loadAllSections().

◆ loadLibrary()

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

Function loadLibrary loads 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 793 of file eagle_plugin.cpp.

794 {
795  if( !aLib )
796  return;
797 
798  // library will have <xmlattr> node, skip that and get the single packages node
799  wxXmlNode* packages = MapChildren( aLib )["packages"];
800 
801  if( !packages )
802  return;
803 
804  m_xpath->push( "packages" );
805 
806  // Create a MODULE for all the eagle packages, for use later via a copy constructor
807  // to instantiate needed MODULES in our BOARD. Save the MODULE templates in
808  // a MODULE_MAP using a single lookup key consisting of libname+pkgname.
809 
810  // Get the first package and iterate
811  wxXmlNode* package = packages->GetChildren();
812 
813  while( package )
814  {
815  m_xpath->push( "package", "name" );
816 
817  wxString pack_ref = package->GetAttribute( "name" );
818  ReplaceIllegalFileNameChars( pack_ref, '_' );
819 
820  m_xpath->Value( pack_ref.ToUTF8() );
821 
822  wxString key = aLibName ? makeKey( *aLibName, pack_ref ) : pack_ref;
823 
824  MODULE* m = makeModule( package, pack_ref );
825 
826  // add the templating MODULE to the MODULE template factory "m_templates"
827  std::pair<MODULE_ITER, bool> r = m_templates.insert( {key, m} );
828 
829  if( !r.second
830  // && !( m_props && m_props->Value( "ignore_duplicates" ) )
831  )
832  {
833  wxString lib = aLibName ? *aLibName : m_lib_path;
834  const wxString& pkg = pack_ref;
835 
836  wxString emsg = wxString::Format(
837  _( "<package> name: \"%s\" duplicated in eagle <library>: \"%s\"" ),
838  GetChars( pkg ),
839  GetChars( lib )
840  );
841  THROW_IO_ERROR( emsg );
842  }
843 
844  m_xpath->pop();
845 
846  package = package->GetNext();
847  }
848 
849  m_xpath->pop(); // "packages"
850 }
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:117
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
Definition: string.cpp:680
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides 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:174
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 m_lib_path
Definition: eagle_plugin.h:193
#define THROW_IO_ERROR(msg)
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:101
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:31
MODULE_MAP m_templates
is part of a MODULE factory that operates using copy construction.
Definition: eagle_plugin.h:181
void pop()
Definition: eagle_parser.h:124
MODULE * makeModule(wxXmlNode *aPackage, const wxString &aPkgName) const
Function makeModule creates a MODULE from an Eagle package.
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:127

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

Referenced by cacheLib(), and loadLibraries().

◆ loadPlain()

void EAGLE_PLUGIN::loadPlain ( wxXmlNode *  aPlain)
private

Definition at line 473 of file eagle_plugin.cpp.

474 {
475  if( !aGraphics )
476  return;
477 
478  m_xpath->push( "plain" );
479 
480  // Get the first graphic and iterate
481  wxXmlNode* gr = aGraphics->GetChildren();
482 
483  // (polygon | wire | text | circle | rectangle | frame | hole)*
484  while( gr )
485  {
486  wxString grName = gr->GetName();
487 
488  if( grName == "wire" )
489  {
490  m_xpath->push( "wire" );
491 
492  EWIRE w( gr );
493  PCB_LAYER_ID layer = kicad_layer( w.layer );
494 
495  wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
496  wxPoint end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
497 
498  if( layer != UNDEFINED_LAYER )
499  {
500  DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
501  int width = w.width.ToPcbUnits();
502 
503  // KiCad cannot handle zero or negative line widths
504  if( width <= 0 )
505  width = m_board->GetDesignSettings().GetLineThickness( layer );
506 
507  m_board->Add( dseg, ADD_MODE::APPEND );
508 
509  if( !w.curve )
510  {
511  dseg->SetStart( start );
512  dseg->SetEnd( end );
513  }
514  else
515  {
516  wxPoint center = ConvertArcCenter( start, end, *w.curve );
517 
518  dseg->SetShape( S_ARC );
519  dseg->SetStart( center );
520  dseg->SetEnd( start );
521  dseg->SetAngle( *w.curve * -10.0 ); // KiCad rotates the other way
522  }
523 
524  dseg->SetTimeStamp( EagleTimeStamp( gr ) );
525  dseg->SetLayer( layer );
526  dseg->SetWidth( width );
527  }
528 
529  m_xpath->pop();
530  }
531  else if( grName == "text" )
532  {
533  m_xpath->push( "text" );
534 
535  ETEXT t( gr );
536  PCB_LAYER_ID layer = kicad_layer( t.layer );
537 
538  if( layer != UNDEFINED_LAYER )
539  {
540  TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
541  m_board->Add( pcbtxt, ADD_MODE::APPEND );
542 
543  pcbtxt->SetLayer( layer );
544  pcbtxt->SetTimeStamp( EagleTimeStamp( gr ) );
545  pcbtxt->SetText( FROM_UTF8( t.text.c_str() ) );
546  pcbtxt->SetTextPos( wxPoint( kicad_x( t.x ), kicad_y( t.y ) ) );
547 
548  pcbtxt->SetTextSize( kicad_fontz( t.size ) );
549 
550  double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
551 
552  pcbtxt->SetThickness( t.size.ToPcbUnits() * ratio / 100 );
553 
554  int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;
555 
556  if( t.rot )
557  {
558  int sign = t.rot->mirror ? -1 : 1;
559  pcbtxt->SetMirrored( t.rot->mirror );
560 
561  double degrees = t.rot->degrees;
562 
563  if( degrees == 90 || t.rot->spin )
564  pcbtxt->SetTextAngle( sign * t.rot->degrees * 10 );
565  else if( degrees == 180 )
566  align = ETEXT::TOP_RIGHT;
567  else if( degrees == 270 )
568  {
569  pcbtxt->SetTextAngle( sign * 90 * 10 );
570  align = ETEXT::TOP_RIGHT;
571  }
572  else // Ok so text is not at 90,180 or 270 so do some funny stuff to get placement right
573  {
574  if( ( degrees > 0 ) && ( degrees < 90 ) )
575  pcbtxt->SetTextAngle( sign * t.rot->degrees * 10 );
576  else if( ( degrees > 90 ) && ( degrees < 180 ) )
577  {
578  pcbtxt->SetTextAngle( sign * ( t.rot->degrees + 180 ) * 10 );
579  align = ETEXT::TOP_RIGHT;
580  }
581  else if( ( degrees > 180 ) && ( degrees < 270 ) )
582  {
583  pcbtxt->SetTextAngle( sign * ( t.rot->degrees - 180 ) * 10 );
584  align = ETEXT::TOP_RIGHT;
585  }
586  else if( ( degrees > 270 ) && ( degrees < 360 ) )
587  {
588  pcbtxt->SetTextAngle( sign * t.rot->degrees * 10 );
589  align = ETEXT::BOTTOM_LEFT;
590  }
591  }
592  }
593 
594  switch( align )
595  {
596  case ETEXT::CENTER:
597  // this was the default in pcbtxt's constructor
598  break;
599 
600  case ETEXT::CENTER_LEFT:
602  break;
603 
604  case ETEXT::CENTER_RIGHT:
606  break;
607 
608  case ETEXT::TOP_CENTER:
610  break;
611 
612  case ETEXT::TOP_LEFT:
615  break;
616 
617  case ETEXT::TOP_RIGHT:
620  break;
621 
624  break;
625 
626  case ETEXT::BOTTOM_LEFT:
629  break;
630 
631  case ETEXT::BOTTOM_RIGHT:
634  break;
635  }
636  }
637  m_xpath->pop();
638  }
639  else if( grName == "circle" )
640  {
641  m_xpath->push( "circle" );
642 
643  ECIRCLE c( gr );
644  PCB_LAYER_ID layer = kicad_layer( c.layer );
645 
646  if( layer != UNDEFINED_LAYER ) // unsupported layer
647  {
648  DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
649  m_board->Add( dseg, ADD_MODE::APPEND );
650 
651  int width = c.width.ToPcbUnits();
652  int radius = c.radius.ToPcbUnits();
653 
654  // with == 0 means filled circle
655  if( width <= 0 )
656  {
657  width = radius;
658  radius = radius / 2;
659  }
660 
661  dseg->SetShape( S_CIRCLE );
662  dseg->SetTimeStamp( EagleTimeStamp( gr ) );
663  dseg->SetLayer( layer );
664  dseg->SetStart( wxPoint( kicad_x( c.x ), kicad_y( c.y ) ) );
665  dseg->SetEnd( wxPoint( kicad_x( c.x ) + radius, kicad_y( c.y ) ) );
666  dseg->SetWidth( width );
667  }
668  m_xpath->pop();
669  }
670  else if( grName == "rectangle" )
671  {
672  // This seems to be a simplified rectangular [copper] zone, cannot find any
673  // net related info on it from the DTD.
674  m_xpath->push( "rectangle" );
675 
676  ERECT r( gr );
677  PCB_LAYER_ID layer = kicad_layer( r.layer );
678 
679  if( IsCopperLayer( layer ) )
680  {
681  // use a "netcode = 0" type ZONE:
682  ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board );
683  m_board->Add( zone, ADD_MODE::APPEND );
684 
685  zone->SetTimeStamp( EagleTimeStamp( gr ) );
686  zone->SetLayer( layer );
688 
690 
691  const int outlineIdx = -1; // this is the id of the copper zone main outline
692  zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ), outlineIdx );
693  zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ), outlineIdx );
694  zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ), outlineIdx );
695  zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ), outlineIdx );
696 
697  if( r.rot )
698  {
699  zone->Rotate( zone->GetPosition(), r.rot->degrees * 10 );
700  }
701  // this is not my fault:
702  zone->SetHatch( outline_hatch, zone->GetDefaultHatchPitch(), true );
703  }
704 
705  m_xpath->pop();
706  }
707  else if( grName == "hole" )
708  {
709  m_xpath->push( "hole" );
710 
711  // Fabricate a MODULE with a single PAD_ATTRIB_HOLE_NOT_PLATED pad.
712  // Use m_hole_count to gen up a unique name.
713 
714  MODULE* module = new MODULE( m_board );
715  m_board->Add( module, ADD_MODE::APPEND );
716  module->SetReference( wxString::Format( "@HOLE%d", m_hole_count++ ) );
717  module->Reference().SetVisible( false );
718 
719  packageHole( module, gr, true );
720 
721  m_xpath->pop();
722  }
723  else if( grName == "frame" )
724  {
725  // picture this
726  }
727  else if( grName == "polygon" )
728  {
729  m_xpath->push( "polygon" );
730  loadPolygon( gr );
731  m_xpath->pop(); // "polygon"
732  }
733  else if( grName == "dimension" )
734  {
735  EDIMENSION d( gr );
736  PCB_LAYER_ID layer = kicad_layer( d.layer );
737 
738  if( layer != UNDEFINED_LAYER )
739  {
740  const BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
741  DIMENSION* dimension = new DIMENSION( m_board );
742  m_board->Add( dimension, ADD_MODE::APPEND );
743 
744  if( d.dimensionType )
745  {
746  // Eagle dimension graphic arms may have different lengths, but they look
747  // incorrect in KiCad (the graphic is tilted). Make them even length in such case.
748  if( *d.dimensionType == "horizontal" )
749  {
750  int newY = ( d.y1.ToPcbUnits() + d.y2.ToPcbUnits() ) / 2;
751  d.y1 = ECOORD( newY, ECOORD::EAGLE_UNIT::EU_NM );
752  d.y2 = ECOORD( newY, ECOORD::EAGLE_UNIT::EU_NM );
753  }
754  else if( *d.dimensionType == "vertical" )
755  {
756  int newX = ( d.x1.ToPcbUnits() + d.x2.ToPcbUnits() ) / 2;
757  d.x1 = ECOORD( newX, ECOORD::EAGLE_UNIT::EU_NM );
758  d.x2 = ECOORD( newX, ECOORD::EAGLE_UNIT::EU_NM );
759  }
760  }
761 
762  dimension->SetLayer( layer );
763  // The origin and end are assumed to always be in this order from eagle
764  dimension->SetOrigin( wxPoint( kicad_x( d.x1 ), kicad_y( d.y1 ) ),
766  dimension->SetEnd( wxPoint( kicad_x( d.x2 ), kicad_y( d.y2 ) ),
768  dimension->Text().SetTextSize( designSettings.GetTextSize( layer ) );
769  dimension->Text().SetThickness( designSettings.GetTextThickness( layer ) );
770  dimension->SetWidth( designSettings.GetLineThickness( layer ) );
771  dimension->SetUnits( EDA_UNITS::MILLIMETRES, false );
772 
773  // check which axis the dimension runs in
774  // because the "height" of the dimension is perpendicular to that axis
775  // Note the check is just if two axes are close enough to each other
776  // Eagle appears to have some rounding errors
777  if( abs( ( d.x1 - d.x2 ).ToPcbUnits() ) < 50000 ) // 50000 nm = 0.05 mm
778  dimension->SetHeight( kicad_x( d.x3 - d.x1 ), DIMENSION_PRECISION );
779  else
780  dimension->SetHeight( kicad_y( d.y3 - d.y1 ), DIMENSION_PRECISION );
781 
783  }
784  }
785 
786  // Get next graphic
787  gr = gr->GetNext();
788  }
789  m_xpath->pop();
790 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:172
int sign(T val)
Definition: util.h:90
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
void SetHatch(ZONE_HATCH_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Function SetHatch sets all hatch parameters for the zone.
Definition: class_zone.cpp:958
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
void SetTextAngle(double aAngle)
TEXTE_MODULE & Reference()
Definition: class_module.h:477
void SetShape(STROKE_T aShape)
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:187
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:117
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:231
void SetVisible(bool aVisible)
Definition: eda_text.h:169
void SetHeight(int aHeight, int aPrecision)
Function SetHeight Sets the length of feature lines.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
int GetTextThickness(PCB_LAYER_ID aLayer) const
Function GetTextThickness Returns the default text thickness from the layer class for the given layer...
void SetUnits(EDA_UNITS aUnits, bool aUseMils)
const wxPoint GetPosition() const override
Definition: class_zone.cpp:198
Eagle text element.
Definition: eagle_parser.h:651
static int GetDefaultHatchPitch()
Function GetDefaultHatchPitchMils.
void SetLayer(PCB_LAYER_ID aLayer) override
Function SetLayer sets the layer this item is on.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:174
void packageHole(MODULE *aModule, wxXmlNode *aTree, bool aCenter) const
Function packageHole @parameter aModule - The KiCad module to which to assign the hole @parameter aTr...
int GetLineThickness(PCB_LAYER_ID aLayer) const
Function GetLineThickness Returns the default graphic segment thickness from the layer class for the ...
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
PCB_LAYER_ID
A quick note on layer IDs:
void SetOrigin(const wxPoint &aOrigin, int aPrecision)
Function SetOrigin Sets a new origin of the crossbar line.
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:111
void SetEnd(const wxPoint &aEnd, int aPrecision)
Function SetEnd Sets a new end of the crossbar line.
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:187
Arcs (with rounded ends)
Eagle circle.
Definition: eagle_parser.h:576
void Rotate(const wxPoint &centre, double angle) override
Function Rotate Move the outlines.
Definition: class_zone.cpp:802
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Function SetLayer sets the layer this item is on.
Definition: class_zone.cpp:231
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Sets net using a net code.
void SetReference(const wxString &aReference)
Function SetReference.
Definition: class_module.h:446
timestamp_t EagleTimeStamp(wxXmlNode *aTree)
Make a unique time stamp
int m_hole_count
generates unique module names from eagle "hole"s.
Definition: eagle_plugin.h:177
Eagle XML rectangle in binary.
Definition: eagle_parser.h:589
void SetStart(const wxPoint &aStart)
void AdjustDimensionDetails(int aPrecision)
Function AdjustDimensionDetails Calculate coordinates of segments used to draw the dimension.
ZONE_HATCH_STYLE
Zone hatch styles.
Definition: zone_settings.h:45
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:186
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC
TEXTE_PCB & Text()
#define DIMENSION_PRECISION
void SetEnd(const wxPoint &aEnd)
Eagle wire.
Definition: eagle_parser.h:505
void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
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: class_zone.cpp:915
wxSize kicad_fontz(const ECOORD &d) const
create a font size (fontz) from an eagle font size scalar
Eagle dimension element.
Definition: eagle_parser.h:634
void pop()
Definition: eagle_parser.h:124
void SetWidth(int aWidth)
ZONE_CONTAINER * loadPolygon(wxXmlNode *aPolyNode)
Loads a copper or keepout polygon and adds it to the board.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:463
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Function GetTextSize Returns the default text size from the layer class for the given layer.
DIMENSION.
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
void SetThickness(int aNewThickness)
Set the pen width.
Definition: eda_text.h:143
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
void SetWidth(int aWidth)

References BOARD::Add(), DIMENSION::AdjustDimensionDetails(), ETEXT::align, APPEND, ZONE_CONTAINER::AppendCorner(), ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, ETEXT::CENTER, ETEXT::CENTER_LEFT, ETEXT::CENTER_RIGHT, ConvertArcCenter(), EWIRE::curve, EROT::degrees, DIAGONAL_EDGE, DIMENSION_PRECISION, EDIMENSION::dimensionType, EagleTimeStamp(), Format(), FROM_UTF8(), ZONE_CONTAINER::GetDefaultHatchPitch(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetLineThickness(), ZONE_CONTAINER::GetPosition(), BOARD_DESIGN_SETTINGS::GetTextSize(), BOARD_DESIGN_SETTINGS::GetTextThickness(), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_TOP, IsCopperLayer(), kicad_fontz(), kicad_layer(), kicad_x(), kicad_y(), EWIRE::layer, ECIRCLE::layer, ERECT::layer, EDIMENSION::layer, ETEXT::layer, loadPolygon(), m_board, m_hole_count, m_xpath, MILLIMETRES, EROT::mirror, packageHole(), XPATH::pop(), XPATH::push(), ECIRCLE::radius, ETEXT::ratio, MODULE::Reference(), ERECT::rot, ETEXT::rot, ZONE_CONTAINER::Rotate(), S_ARC, S_CIRCLE, DRAWSEGMENT::SetAngle(), DRAWSEGMENT::SetEnd(), DIMENSION::SetEnd(), ZONE_CONTAINER::SetHatch(), DIMENSION::SetHeight(), EDA_TEXT::SetHorizJustify(), DIMENSION::SetLayer(), ZONE_CONTAINER::SetLayer(), BOARD_ITEM::SetLayer(), EDA_TEXT::SetMirrored(), BOARD_CONNECTED_ITEM::SetNetCode(), DIMENSION::SetOrigin(), MODULE::SetReference(), DRAWSEGMENT::SetShape(), DRAWSEGMENT::SetStart(), EDA_TEXT::SetText(), TEXTE_PCB::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetThickness(), EDA_ITEM::SetTimeStamp(), DIMENSION::SetUnits(), EDA_TEXT::SetVertJustify(), EDA_TEXT::SetVisible(), DRAWSEGMENT::SetWidth(), DIMENSION::SetWidth(), sign(), ETEXT::size, EROT::spin, DIMENSION::Text(), ETEXT::text, ETEXT::TOP_CENTER, ETEXT::TOP_LEFT, ETEXT::TOP_RIGHT, ECOORD::ToPcbUnits(), NETINFO_LIST::UNCONNECTED, UNDEFINED_LAYER, EWIRE::width, ECIRCLE::width, ECIRCLE::x, ETEXT::x, EWIRE::x1, ERECT::x1, EDIMENSION::x1, EWIRE::x2, ERECT::x2, EDIMENSION::x2, EDIMENSION::x3, ECIRCLE::y, ETEXT::y, EWIRE::y1, ERECT::y1, EDIMENSION::y1, EWIRE::y2, ERECT::y2, EDIMENSION::y2, and EDIMENSION::y3.

Referenced by loadAllSections().

◆ loadPolygon()

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

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

Returns
The loaded zone or nullptr if was not processed.

Definition at line 1118 of file eagle_plugin.cpp.

1119 {
1120  EPOLYGON p( aPolyNode );
1121  PCB_LAYER_ID layer = kicad_layer( p.layer );
1122  ZONE_CONTAINER* zone = nullptr;
1123  bool keepout = ( p.layer == EAGLE_LAYER::TRESTRICT || p.layer == EAGLE_LAYER::BRESTRICT );
1124 
1125  if( !IsCopperLayer( layer ) && !keepout )
1126  return nullptr;
1127 
1128  // use a "netcode = 0" type ZONE:
1129  zone = new ZONE_CONTAINER( m_board );
1130  zone->SetTimeStamp( EagleTimeStamp( aPolyNode ) );
1131  m_board->Add( zone, ADD_MODE::APPEND );
1132 
1133  if( p.layer == EAGLE_LAYER::TRESTRICT ) // front layer keepout
1134  zone->SetLayer( F_Cu );
1135  else if( p.layer == EAGLE_LAYER::BRESTRICT ) // bottom layer keepout
1136  zone->SetLayer( B_Cu );
1137  else
1138  zone->SetLayer( layer );
1139 
1140  if( keepout )
1141  {
1142  zone->SetIsKeepout( true );
1143  zone->SetDoNotAllowVias( true );
1144  zone->SetDoNotAllowTracks( true );
1145  zone->SetDoNotAllowCopperPour( true );
1146  }
1147 
1148  // Get the first vertex and iterate
1149  wxXmlNode* vertex = aPolyNode->GetChildren();
1150  std::vector<EVERTEX> vertices;
1151 
1152  // Create a circular vector of vertices
1153  // The "curve" parameter indicates a curve from the current
1154  // to the next vertex, so we keep the first at the end as well
1155  // to allow the curve to link back
1156  while( vertex )
1157  {
1158  if( vertex->GetName() == "vertex" )
1159  vertices.emplace_back( vertex );
1160 
1161  vertex = vertex->GetNext();
1162  }
1163 
1164  vertices.push_back( vertices[0] );
1165 
1166  SHAPE_POLY_SET polygon;
1167  polygon.NewOutline();
1168 
1169  for( size_t i = 0; i < vertices.size() - 1; i++ )
1170  {
1171  EVERTEX v1 = vertices[i];
1172 
1173  // Append the corner
1174  polygon.Append( kicad_x( v1.x ), kicad_y( v1.y ) );
1175 
1176  if( v1.curve )
1177  {
1178  EVERTEX v2 = vertices[i + 1];
1179  wxPoint center = ConvertArcCenter(
1180  wxPoint( kicad_x( v1.x ), kicad_y( v1.y ) ),
1181  wxPoint( kicad_x( v2.x ), kicad_y( v2.y ) ), *v1.curve );
1182  double angle = DEG2RAD( *v1.curve );
1183  double end_angle = atan2( kicad_y( v2.y ) - center.y,
1184  kicad_x( v2.x ) - center.x );
1185  double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
1186  + pow( center.y - kicad_y( v1.y ), 2 ) );
1187 
1188  // If we are curving, we need at least 2 segments otherwise
1189  // delta_angle == angle
1190  double delta_angle = angle / std::max(
1191  2, GetArcToSegmentCount( KiROUND( radius ),
1192  ARC_HIGH_DEF, *v1.curve ) - 1 );
1193 
1194  for( double a = end_angle + angle;
1195  fabs( a - end_angle ) > fabs( delta_angle );
1196  a -= delta_angle )
1197  {
1198  polygon.Append( KiROUND( radius * cos( a ) ) + center.x,
1199  KiROUND( radius * sin( a ) ) + center.y );
1200  }
1201  }
1202  }
1203 
1204  // Eagle traces the zone such that half of the pen width is outside the polygon.
1205  // We trace the zone such that the copper is completely inside.
1206  if( p.width.ToPcbUnits() > 0 )
1207  {
1208  polygon.Inflate( p.width.ToPcbUnits() / 2, 32, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
1210  }
1211 
1212  zone->AddPolygon( polygon.COutline( 0 ) );
1213 
1214  // If the pour is a cutout it needs to be set to a keepout
1215  if( p.pour == EPOLYGON::CUTOUT )
1216  {
1217  zone->SetIsKeepout( true );
1218  zone->SetDoNotAllowCopperPour( true );
1220  }
1221  else if( p.pour == EPOLYGON::HATCH )
1222  {
1223  int spacing = p.spacing ? p.spacing->ToPcbUnits() : 50 * IU_PER_MILS;
1224 
1226  zone->SetHatchFillTypeThickness( p.width.ToPcbUnits() );
1227  zone->SetHatchFillTypeGap( spacing - p.width.ToPcbUnits() );
1228  zone->SetHatchFillTypeOrientation( 0 );
1229  }
1230 
1231  // We divide the thickness by half because we are tracing _inside_ the zone outline
1232  // This means the radius of curvature will be twice the size for an equivalent EAGLE zone
1233  zone->SetMinThickness(
1234  std::max<int>( ZONE_THICKNESS_MIN_VALUE_MIL * IU_PER_MILS, p.width.ToPcbUnits() / 2 ) );
1235 
1236  if( p.isolate )
1237  zone->SetZoneClearance( p.isolate->ToPcbUnits() );
1238  else
1239  zone->SetZoneClearance( 1 ); // @todo: set minimum clearance value based on board settings
1240 
1241  // missing == yes per DTD.
1242  bool thermals = !p.thermals || *p.thermals;
1244 
1245  if( thermals )
1246  {
1247  // FIXME: eagle calculates dimensions for thermal spokes
1248  // based on what the zone is connecting to.
1249  // (i.e. width of spoke is half of the smaller side of an smd pad)
1250  // This is a basic workaround
1251  zone->SetThermalReliefGap( p.width.ToPcbUnits() + 50000 ); // 50000nm == 0.05mm
1252  zone->SetThermalReliefCopperBridge( p.width.ToPcbUnits() + 50000 );
1253  }
1254 
1255  int rank = p.rank ? (p.max_priority - *p.rank) : p.max_priority;
1256  zone->SetPriority( rank );
1257 
1258  return zone;
1259 }
void SetDoNotAllowTracks(bool aEnable)
Definition: class_zone.h:639
Eagle vertex.
Definition: eagle_parser.h:752
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition: class_zone.h:181
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:187
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
ECOORD y
Definition: eagle_parser.h:755
void SetHatchStyle(ZONE_HATCH_STYLE aStyle)
Definition: class_zone.h:525
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Performs outline inflation/deflation.
void SetDoNotAllowVias(bool aEnable)
Definition: class_zone.h:638
void SetPriority(unsigned aPriority)
Function SetPriority.
Definition: class_zone.h:94
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
PCB_LAYER_ID
A quick note on layer IDs:
void SetHatchFillTypeGap(int aStep)
Definition: class_zone.h:199
pads are covered by copper
SHAPE_POLY_SET.
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Function SetLayer sets the layer this item is on.
Definition: class_zone.cpp:231
void SetZoneClearance(int aZoneClearance)
Definition: class_zone.h:177
timestamp_t EagleTimeStamp(wxXmlNode *aTree)
Make a unique time stamp
int NewOutline()
Creates a new empty polygon in the set and returns its index
void AddPolygon(std::vector< wxPoint > &aPolygon)
add a polygon to the zone outline if the zone outline is empty, this is the main outline else it is a...
Definition: class_zone.cpp:890
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:756
void SetThermalReliefCopperBridge(int aThermalReliefCopperBridge)
Definition: class_zone.h:161
void SetDoNotAllowCopperPour(bool aEnable)
Definition: class_zone.h:637
Use thermal relief for pads.
#define ZONE_THICKNESS_MIN_VALUE_MIL
Definition: zones.h:41
void SetFillMode(ZONE_FILL_MODE aFillMode)
Definition: class_zone.h:155
ECOORD x
Definition: eagle_parser.h:754
double DEG2RAD(double deg)
Definition: trigo.h:210
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void SetHatchFillTypeOrientation(double aStep)
Definition: class_zone.h:202
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define IU_PER_MILS
Definition: plotter.cpp:137
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:61
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void SetHatchFillTypeThickness(int aThickness)
Definition: class_zone.h:196
Eagle polygon, without vertices which are parsed as needed.
Definition: eagle_parser.h:763
void SetIsKeepout(bool aEnable)
Definition: class_zone.h:636
void SetMinThickness(int aMinThickness)
Definition: class_zone.h:187
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
void SetThermalReliefGap(int aThermalReliefGap)
Definition: class_zone.h:158
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)

References BOARD::Add(), ZONE_CONTAINER::AddPolygon(), SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS, PNS::angle(), APPEND, SHAPE_POLY_SET::Append(), B_Cu, EAGLE_LAYER::BRESTRICT, ConvertArcCenter(), SHAPE_POLY_SET::COutline(), EVERTEX::curve, EPOLYGON::CUTOUT, DEG2RAD(), EagleTimeStamp(), F_Cu, 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_CONTAINER::SetDoNotAllowCopperPour(), ZONE_CONTAINER::SetDoNotAllowTracks(), ZONE_CONTAINER::SetDoNotAllowVias(), ZONE_CONTAINER::SetFillMode(), ZONE_CONTAINER::SetHatchFillTypeGap(), ZONE_CONTAINER::SetHatchFillTypeOrientation(), ZONE_CONTAINER::SetHatchFillTypeThickness(), ZONE_CONTAINER::SetHatchStyle(), ZONE_CONTAINER::SetIsKeepout(), ZONE_CONTAINER::SetLayer(), ZONE_CONTAINER::SetMinThickness(), ZONE_CONTAINER::SetPadConnection(), ZONE_CONTAINER::SetPriority(), ZONE_CONTAINER::SetThermalReliefCopperBridge(), ZONE_CONTAINER::SetThermalReliefGap(), EDA_ITEM::SetTimeStamp(), ZONE_CONTAINER::SetZoneClearance(), EPOLYGON::spacing, THERMAL, EPOLYGON::thermals, ECOORD::ToPcbUnits(), EAGLE_LAYER::TRESTRICT, EPOLYGON::width, wxPoint::x, EVERTEX::x, wxPoint::y, EVERTEX::y, and ZONE_THICKNESS_MIN_VALUE_MIL.

Referenced by loadPlain(), and loadSignals().

◆ loadSignals()

void EAGLE_PLUGIN::loadSignals ( wxXmlNode *  aSignals)
private

Definition at line 2061 of file eagle_plugin.cpp.

2062 {
2063  ZONES zones; // per net
2064 
2065  m_xpath->push( "signals.signal", "name" );
2066 
2067  int netCode = 1;
2068 
2069  // Get the first signal and iterate
2070  wxXmlNode* net = aSignals->GetChildren();
2071 
2072  while( net )
2073  {
2074  bool sawPad = false;
2075 
2076  zones.clear();
2077 
2078  const wxString& netName = escapeName( net->GetAttribute( "name" ) );
2079  m_board->Add( new NETINFO_ITEM( m_board, netName, netCode ) );
2080 
2081  m_xpath->Value( netName.c_str() );
2082 
2083  // Get the first net item and iterate
2084  wxXmlNode* netItem = net->GetChildren();
2085 
2086  // (contactref | polygon | wire | via)*
2087  while( netItem )
2088  {
2089  const wxString& itemName = netItem->GetName();
2090 
2091  if( itemName == "wire" )
2092  {
2093  m_xpath->push( "wire" );
2094 
2095  EWIRE w( netItem );
2096  PCB_LAYER_ID layer = kicad_layer( w.layer );
2097 
2098  if( IsCopperLayer( layer ) )
2099  {
2100  wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
2101  double angle = 0.0;
2102  double end_angle = 0.0;
2103  double radius = 0.0;
2104  double delta_angle = 0.0;
2105  wxPoint center;
2106 
2107  int width = w.width.ToPcbUnits();
2108  if( width < m_min_trace )
2109  m_min_trace = width;
2110 
2111  if( w.curve )
2112  {
2113  center = ConvertArcCenter(
2114  wxPoint( kicad_x( w.x1 ), kicad_y( w.y1 ) ),
2115  wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ),
2116  *w.curve );
2117 
2118  angle = DEG2RAD( *w.curve );
2119 
2120  end_angle = atan2( kicad_y( w.y2 ) - center.y,
2121  kicad_x( w.x2 ) - center.x );
2122 
2123  radius = sqrt( pow( center.x - kicad_x( w.x1 ), 2 ) +
2124  pow( center.y - kicad_y( w.y1 ), 2 ) );
2125 
2126  // If we are curving, we need at least 2 segments otherwise
2127  // delta_angle == angle
2128  int segments = std::max( 2, GetArcToSegmentCount( KiROUND( radius ),
2129  ARC_HIGH_DEF, *w.curve ) - 1 );
2130  delta_angle = angle / segments;
2131  }
2132 
2133  while( fabs( angle ) > fabs( delta_angle ) )
2134  {
2135  wxASSERT( radius > 0.0 );
2136  wxPoint end( KiROUND( radius * cos( end_angle + angle ) + center.x ),
2137  KiROUND( radius * sin( end_angle + angle ) + center.y ) );
2138 
2139  TRACK* t = new TRACK( m_board );
2140 
2141  t->SetTimeStamp( EagleTimeStamp( netItem ) + int( RAD2DEG( angle ) ) );
2142  t->SetPosition( start );
2143  t->SetEnd( end );
2144  t->SetWidth( width );
2145  t->SetLayer( layer );
2146  t->SetNetCode( netCode );
2147 
2148  m_board->Add( t );
2149 
2150  start = end;
2151  angle -= delta_angle;
2152  }
2153 
2154  TRACK* t = new TRACK( m_board );
2155 
2156  t->SetTimeStamp( EagleTimeStamp( netItem ) );
2157  t->SetPosition( start );
2158  t->SetEnd( wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ) );
2159  t->SetWidth( width );
2160  t->SetLayer( layer );
2161  t->SetNetCode( netCode );
2162 
2163  m_board->Add( t );
2164  }
2165  else
2166  {
2167  // put non copper wires where the sun don't shine.
2168  }
2169 
2170  m_xpath->pop();
2171  }
2172 
2173  else if( itemName == "via" )
2174  {
2175  m_xpath->push( "via" );
2176  EVIA v( netItem );
2177 
2178  PCB_LAYER_ID layer_front_most = kicad_layer( v.layer_front_most );
2179  PCB_LAYER_ID layer_back_most = kicad_layer( v.layer_back_most );
2180 
2181  if( IsCopperLayer( layer_front_most ) &&
2182  IsCopperLayer( layer_back_most ) )
2183  {
2184  int kidiam;
2185  int drillz = v.drill.ToPcbUnits();
2186  VIA* via = new VIA( m_board );
2187  m_board->Add( via );
2188 
2189  via->SetLayerPair( layer_front_most, layer_back_most );
2190 
2191  if( v.diam )
2192  {
2193  kidiam = v.diam->ToPcbUnits();
2194  via->SetWidth( kidiam );
2195  }
2196  else
2197  {
2198  double annulus = drillz * m_rules->rvViaOuter; // eagle "restring"
2199  annulus = eagleClamp( m_rules->rlMinViaOuter, annulus,
2201  kidiam = KiROUND( drillz + 2 * annulus );
2202  via->SetWidth( kidiam );
2203  }
2204 
2205  via->SetDrill( drillz );
2206 
2207  // make sure the via diameter respects the restring rules
2208 
2209  if( !v.diam || via->GetWidth() <= via->GetDrill() )
2210  {
2211  double annulus = eagleClamp( m_rules->rlMinViaOuter,
2212  (double)( via->GetWidth() / 2 - via->GetDrill() ),
2214  via->SetWidth( drillz + 2 * annulus );
2215  }
2216 
2217  if( kidiam < m_min_via )
2218  m_min_via = kidiam;
2219 
2220  if( drillz < m_min_via_hole )
2221  m_min_via_hole = drillz;
2222 
2223  if( layer_front_most == F_Cu && layer_back_most == B_Cu )
2224  via->SetViaType( VIATYPE::THROUGH );
2225  else if( layer_front_most == F_Cu || layer_back_most == B_Cu )
2226  via->SetViaType( VIATYPE::MICROVIA );
2227  else
2229 
2230  via->SetTimeStamp( EagleTimeStamp( netItem ) );
2231 
2232  wxPoint pos( kicad_x( v.x ), kicad_y( v.y ) );
2233 
2234  via->SetPosition( pos );
2235  via->SetEnd( pos );
2236 
2237  via->SetNetCode( netCode );
2238  }
2239 
2240  m_xpath->pop();
2241  }
2242 
2243  else if( itemName == "contactref" )
2244  {
2245  m_xpath->push( "contactref" );
2246  // <contactref element="RN1" pad="7"/>
2247 
2248  const wxString& reference = netItem->GetAttribute( "element" );
2249  const wxString& pad = netItem->GetAttribute( "pad" );
2250  wxString key = makeKey( reference, pad ) ;
2251 
2252  // D(printf( "adding refname:'%s' pad:'%s' netcode:%d netname:'%s'\n", reference.c_str(), pad.c_str(), netCode, netName.c_str() );)
2253 
2254  m_pads_to_nets[ key ] = ENET( netCode, netName );
2255 
2256  m_xpath->pop();
2257 
2258  sawPad = true;
2259  }
2260 
2261  else if( itemName == "polygon" )
2262  {
2263  m_xpath->push( "polygon" );
2264  auto* zone = loadPolygon( netItem );
2265 
2266  if( zone )
2267  {
2268  zones.push_back( zone );
2269 
2270  if( !zone->GetIsKeepout() )
2271  zone->SetNetCode( netCode );
2272  }
2273 
2274  m_xpath->pop(); // "polygon"
2275  }
2276 
2277  netItem = netItem->GetNext();
2278  }
2279 
2280  if( zones.size() && !sawPad )
2281  {
2282  // KiCad does not support an unconnected zone with its own non-zero netcode,
2283  // but only when assigned netcode = 0 w/o a name...
2284  for( ZONES::iterator it = zones.begin(); it != zones.end(); ++it )
2285  (*it)->SetNetCode( NETINFO_LIST::UNCONNECTED );
2286 
2287  // therefore omit this signal/net.
2288  }
2289  else
2290  netCode++;
2291 
2292  // Get next signal
2293  net = net->GetNext();
2294  }
2295 
2296  m_xpath->pop(); // "signals.signal"
2297 }
double rlMaxViaOuter
maximum copper annulus on via
Definition: eagle_plugin.h:75
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
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:187
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void SetPosition(const wxPoint &aPoint) override
Definition: class_track.h:310
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:105
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
void push(const char *aPathSegment, const char *aAttribute="")
Definition: eagle_parser.h:117
double RAD2DEG(double rad)
Definition: trigo.h:211
int m_min_via
smallest via we find on Load(), in BIU.
Definition: eagle_plugin.h:190
double rvViaOuter
copper annulus is this percent of via hole
Definition: eagle_plugin.h:73
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:174
void SetWidth(int aWidth)
Definition: class_track.h:102
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
PCB_LAYER_ID
A quick note on layer IDs:
int m_min_via_hole
smallest via diameter hole we find on Load(), in BIU.
Definition: eagle_plugin.h:191
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)
Translates Eagle special characters to their counterparts in KiCad.
int GetDrill() const
Function GetDrill returns the local drill setting for this VIA.
Definition: class_track.h:358
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Sets net using a net code.
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_Layer contains the top layer, the other layer is in m_BottomLayer.
timestamp_t EagleTimeStamp(wxXmlNode *aTree)
Make a unique time stamp
int m_min_trace
smallest trace we find on Load(), in BIU.
Definition: eagle_plugin.h:189
Eagle net.
Definition: eagle_parser.h:467
Eagle via.
Definition: eagle_parser.h:561
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
int GetWidth() const
Definition: class_track.h:103
double DEG2RAD(double deg)
Definition: trigo.h:210
void SetPosition(const wxPoint &aPos) override
Definition: class_track.h:99
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: class_track.h:351
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:61
NET_MAP m_pads_to_nets
net list
Definition: eagle_plugin.h:179
Eagle wire.
Definition: eagle_parser.h:505
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void pop()
Definition: eagle_parser.h:124
std::vector< ZONE_CONTAINER * > ZONES
Definition: eagle_plugin.h:39
void SetViaType(VIATYPE aViaType)
Definition: class_track.h:341
ZONE_CONTAINER * loadPolygon(wxXmlNode *aPolyNode)
Loads a copper or keepout polygon and adds it to the board.
double rlMinViaOuter
minimum copper annulus on via
Definition: eagle_plugin.h:74
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:463
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:202
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:127

References BOARD::Add(), PNS::angle(), B_Cu, BLIND_BURIED, ConvertArcCenter(), EWIRE::curve, DEG2RAD(), EVIA::diam, EVIA::drill, eagleClamp(), EagleTimeStamp(), escapeName(), F_Cu, GetArcToSegmentCount(), VIA::GetDrill(), TRACK::GetWidth(), IsCopperLayer(), kicad_layer(), kicad_x(), kicad_y(), KiROUND(), EWIRE::layer, EVIA::layer_back_most, EVIA::layer_front_most, loadPolygon(), m_board, m_min_trace, m_min_via, m_min_via_hole, m_pads_to_nets, m_rules, m_xpath, makeKey(), MICROVIA, XPATH::pop(), XPATH::push(), RAD2DEG(), ERULES::rlMaxViaOuter, ERULES::rlMinViaOuter, ERULES::rvViaOuter, VIA::SetDrill(), TRACK::SetEnd(), BOARD_ITEM::SetLayer(), VIA::SetLayerPair(), BOARD_CONNECTED_ITEM::SetNetCode(), TRACK::SetPosition(), VIA::SetPosition(), EDA_ITEM::SetTimeStamp(), VIA::SetViaType(), TRACK::SetWidth(), THROUGH, ECOORD::ToPcbUnits(), NETINFO_LIST::UNCONNECTED, XPATH::Value(), VIA, EWIRE::width, wxPoint::x, EVIA::x, EWIRE::x1, EWIRE::x2, wxPoint::y, EVIA::y, EWIRE::y1, and EWIRE::y2.

Referenced by loadAllSections().

◆ makeModule()

MODULE * EAGLE_PLUGIN::makeModule ( wxXmlNode *  aPackage,
const wxString &  aPkgName 
) const
private

Function makeModule creates a MODULE from an Eagle package.

Definition at line 1415 of file eagle_plugin.cpp.

1416 {
1417  std::unique_ptr<MODULE> m( new MODULE( m_board ) );
1418 
1419  LIB_ID fpID;
1420  fpID.Parse( aPkgName, LIB_ID::ID_PCB, true );
1421  m->SetFPID( fpID );
1422 
1423  // Get the first package item and iterate
1424  wxXmlNode* packageItem = aPackage->GetChildren();
1425 
1426  while( packageItem )
1427  {
1428  const wxString& itemName = packageItem->GetName();
1429 
1430  if( itemName == "description" )
1431  m->SetDescription( FROM_UTF8( packageItem->GetNodeContent().c_str() ) );
1432 
1433  else if( itemName == "wire" )
1434  packageWire( m.get(), packageItem );
1435 
1436  else if( itemName == "pad" )
1437  packagePad( m.get(), packageItem );
1438 
1439  else if( itemName == "text" )
1440  packageText( m.get(), packageItem );
1441 
1442  else if( itemName == "rectangle" )
1443  packageRectangle( m.get(), packageItem );
1444 
1445  else if( itemName == "polygon" )
1446  packagePolygon( m.get(), packageItem );
1447 
1448  else if( itemName == "circle" )
1449  packageCircle( m.get(), packageItem );
1450 
1451  else if( itemName == "hole" )
1452  packageHole( m.get(), packageItem, false );
1453 
1454  else if( itemName == "smd" )
1455  packageSMD( m.get(), packageItem );
1456 
1457  packageItem = packageItem->GetNext();
1458  }
1459 
1460  return m.release();
1461 }
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:187
void packageText(MODULE *aModule, wxXmlNode *aTree) const
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void packageHole(MODULE *aModule, wxXmlNode *aTree, bool aCenter) const
Function packageHole @parameter aModule - The KiCad module to which to assign the hole @parameter aTr...
void packagePad(MODULE *aModule, wxXmlNode *aTree) const
void packagePolygon(MODULE *aModule, wxXmlNode *aTree) const
void packageWire(MODULE *aModule, wxXmlNode *aTree) const
void packageRectangle(MODULE *aModule, wxXmlNode *aTree) const
void packageSMD(MODULE *aModule, wxXmlNode *aTree) const
int Parse(const UTF8 &aId, LIB_ID_TYPE aType, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
void packageCircle(MODULE *aModule, wxXmlNode *aTree) const

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

Referenced by loadLibrary().

◆ orientModuleAndText()

void EAGLE_PLUGIN::orientModuleAndText ( MODULE m,
const EELEMENT e,
const EATTR nameAttr,
const EATTR valueAttr 
)
private

Definition at line 1262 of file eagle_plugin.cpp.

1264 {
1265  if( e.rot )
1266  {
1267  if( e.rot->mirror )
1268  {
1269  double orientation = e.rot->degrees + 180.0;
1270  m->SetOrientation( orientation * 10 );
1271  m->Flip( m->GetPosition(), false );
1272  }
1273  else
1274  m->SetOrientation( e.rot->degrees * 10 );
1275  }
1276 
1277  orientModuleText( m, e, &m->Reference(), nameAttr );
1278  orientModuleText( m, e, &m->Value(), valueAttr );
1279 }
bool mirror
Definition: eagle_parser.h:486
TEXTE_MODULE & Reference()
Definition: class_module.h:477
opt_erot rot
Definition: eagle_parser.h:813
double degrees
Definition: eagle_parser.h:488
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:476
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Function Flip Flip this object, i.e.
void SetOrientation(double newangle)
const wxPoint GetPosition() const override
Definition: class_module.h:210
void orientModuleText(MODULE *m, const EELEMENT &e, TEXTE_MODULE *txt, const EATTR *a)

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

Referenced by loadElements().

◆ orientModuleText()

void EAGLE_PLUGIN::orientModuleText ( MODULE m,
const EELEMENT e,
TEXTE_MODULE txt,
const EATTR a 
)
private

Definition at line 1282 of file eagle_plugin.cpp.

1284 {
1285  // Smashed part ?
1286  if( aAttr )
1287  { // Yes
1288  const EATTR& a = *aAttr;
1289 
1290  if( a.value )
1291  {
1292  txt->SetText( FROM_UTF8( a.value->c_str() ) );
1293  }
1294 
1295  if( a.x && a.y ) // OPT
1296  {
1297  wxPoint pos( kicad_x( *a.x ), kicad_y( *a.y ) );
1298  txt->SetTextPos( pos );
1299  }
1300 
1301  // Even though size and ratio are both optional, I am not seeing
1302  // a case where ratio is present but size is not.
1303  double ratio = 8;
1304  wxSize fontz = txt->GetTextSize();
1305 
1306  if( a.size )
1307  {
1308  fontz = kicad_fontz( *a.size );
1309  txt->SetTextSize( fontz );
1310 
1311  if( a.ratio )
1312  ratio = *a.ratio;
1313  }
1314 
1315  int lw = int( fontz.y * ratio / 100 );
1316  txt->SetThickness( lw );
1317 
1318  int align = ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
1319 
1320  if( a.align )
1321  align = a.align;
1322 
1323  // The "rot" in a EATTR seems to be assumed to be zero if it is not
1324  // present, and this zero rotation becomes an override to the
1325  // package's text field. If they did not want zero, they specify
1326  // what they want explicitly.
1327  double degrees = a.rot ? a.rot->degrees : 0;
1328  double orient; // relative to parent
1329 
1330  int sign = 1;
1331  bool spin = false;
1332 
1333  if( a.rot )
1334  {
1335  spin = a.rot->spin;
1336  sign = a.rot->mirror ? -1 : 1;
1337  txt->SetMirrored( a.rot->mirror );
1338  }
1339 
1340  if( degrees == 90 || degrees == 0 || spin )
1341  {
1342  orient = degrees - m->GetOrientation() / 10;
1343  txt->SetTextAngle( sign * orient * 10 );
1344  }
1345  else if( degrees == 180 )
1346  {
1347  orient = 0 - m->GetOrientation() / 10;
1348  txt->SetTextAngle( sign * orient * 10 );
1349  align = -align;
1350  }
1351  else if( degrees == 270 )
1352  {
1353  orient = 90 - m->GetOrientation() / 10;
1354  align = -align;
1355  txt->SetTextAngle( sign * orient * 10 );
1356  }
1357  else
1358  {
1359  orient = 90 - degrees - m->GetOrientation() / 10;
1360  txt->SetTextAngle( sign * orient * 10 );
1361  }
1362 
1363  switch( align )
1364  {
1365  case ETEXT::TOP_RIGHT:
1368  break;
1369 
1370  case ETEXT::BOTTOM_LEFT:
1373  break;
1374 
1375  case ETEXT::TOP_LEFT:
1378  break;
1379 
1380  case ETEXT::BOTTOM_RIGHT:
1383  break;
1384 
1385  case ETEXT::TOP_CENTER:
1388  break;
1389 
1390  case ETEXT::BOTTOM_CENTER:
1393  break;
1394 
1395  default:
1396  ;
1397  }
1398  }
1399  else // Part is not smash so use Lib default for NAME/VALUE // the text is per the original package, sans <attribute>
1400  {
1401  double degrees = ( txt->GetTextAngle() + m->GetOrientation() ) / 10;
1402 
1403  // @todo there are a few more cases than these to contend with:
1404  if( (!txt->IsMirrored() && ( abs( degrees ) == 180 || abs( degrees ) == 270 ))
1405  || ( txt->IsMirrored() && ( degrees == 360 ) ) )
1406  {
1407  // ETEXT::TOP_RIGHT:
1410  }
1411  }
1412 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:172
int sign(T val)
Definition: util.h:90
bool mirror
Definition: eagle_parser.h:486
double GetOrientation() const
Definition: class_module.h:215
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
bool IsMirrored() const
Definition: eda_text.h:173
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:231
double GetTextAngle() const
Definition: eda_text.h:158
double degrees
Definition: eagle_parser.h:488
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
opt_erot rot
Definition: eagle_parser.h:617
opt_int align
Definition: eagle_parser.h:626
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:111
opt_ecoord y
Definition: eagle_parser.h:613
const wxSize & GetTextSize() const
Definition: eda_text.h:223
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:187
opt_wxString value
Definition: eagle_parser.h:611
EATTR parses an Eagle "attribute" XML element.
Definition: eagle_parser.h:608
opt_ecoord x
Definition: eagle_parser.h:612
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:186
opt_double ratio
Definition: eagle_parser.h:616
wxSize kicad_fontz(const ECOORD &d) const
create a font size (fontz) from an eagle font size scalar
void SetTextAngle(double aAngle)
bool spin
Definition: eagle_parser.h:487
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
void SetThickness(int aNewThickness)
Set the pen width.
Definition: eda_text.h:143
opt_ecoord size
Definition: eagle_parser.h:614

References EATTR::align, ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, EROT::degrees, FROM_UTF8(), MODULE::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_TOP, EDA_TEXT::IsMirrored(), kicad_fontz(), kicad_x(), kicad_y(), EROT::mirror, EATTR::ratio, EATTR::rot, EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetMirrored(), EDA_TEXT::SetText(), TEXTE_MODULE::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetThickness(), 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 orientModuleAndText().

◆ packageCircle()

void EAGLE_PLUGIN::packageCircle ( MODULE aModule,
wxXmlNode *  aTree 
) const
private

Definition at line 1852 of file eagle_plugin.cpp.

1853 {
1854  ECIRCLE e( aTree );
1855  PCB_LAYER_ID layer = kicad_layer( e.layer );
1856  EDGE_MODULE* gr = new EDGE_MODULE( aModule, S_CIRCLE );
1857  int width = e.width.ToPcbUnits();
1858  int radius = e.radius.ToPcbUnits();
1859 
1860  // with == 0 means filled circle
1861  if( width <= 0 )
1862  {
1863  width = radius;
1864  radius = radius / 2;
1865  }
1866 
1867  aModule->Add( gr );
1868  gr->SetWidth( width );
1869 
1870  switch ( (int) layer )
1871  {
1872  case UNDEFINED_LAYER:
1873  layer = Cmts_User;
1874  break;
1875  default:
1876  break;
1877  }
1878 
1879  gr->SetLayer( layer );
1880  gr->SetTimeStamp( EagleTimeStamp( aTree ) );
1881  gr->SetStart0( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
1882  gr->SetEnd0( wxPoint( kicad_x( e.x ) + radius, kicad_y( e.y ) ) );
1883  gr->SetDrawCoord();
1884 }
void SetEnd0(const wxPoint &aPoint)
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
PCB_LAYER_ID
A quick note on layer IDs:
Eagle circle.
Definition: eagle_parser.h:576
timestamp_t EagleTimeStamp(wxXmlNode *aTree)
Make a unique time stamp
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
void SetStart0(const wxPoint &aPoint)
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212
void SetWidth(int aWidth)

References MODULE::Add(), Cmts_User, EagleTimeStamp(), kicad_layer(), kicad_x(), kicad_y(), ECIRCLE::layer, ECIRCLE::radius, S_CIRCLE, EDGE_MODULE::SetDrawCoord(), EDGE_MODULE::SetEnd0(), BOARD_ITEM::SetLayer(), EDGE_MODULE::SetStart0(), EDA_ITEM::SetTimeStamp(), DRAWSEGMENT::SetWidth(), ECOORD::ToPcbUnits(), UNDEFINED_LAYER, ECIRCLE::width, ECIRCLE::x, and ECIRCLE::y.

Referenced by makeModule().

◆ packageHole()

void EAGLE_PLUGIN::packageHole ( MODULE aModule,
wxXmlNode *  aTree,
bool  aCenter 
) const
private

Function packageHole @parameter aModule - The KiCad module to which to assign the hole @parameter aTree - The Eagle XML node that is of type "hole" @parameter aCenter - If true, center the hole in the module and offset the module position.

Definition at line 1887 of file eagle_plugin.cpp.

1888 {
1889  EHOLE e( aTree );
1890 
1891  // we add a PAD_ATTRIB_HOLE_NOT_PLATED pad to this module.
1892  D_PAD* pad = new D_PAD( aModule );
1893  aModule->Add( pad );
1894 
1895  pad->SetShape( PAD_SHAPE_CIRCLE );
1897 
1898  // Mechanical purpose only:
1899  // no offset, no net name, no pad name allowed
1900  // pad->SetOffset( wxPoint( 0, 0 ) );
1901  // pad->SetName( wxEmptyString );
1902 
1903  wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) );
1904 
1905  if( aCenter )
1906  {
1907  pad->SetPos0( wxPoint( 0, 0 ) );
1908  aModule->SetPosition( padpos );
1909  pad->SetPosition( padpos );
1910  }
1911  else
1912  {
1913  pad->SetPos0( padpos );
1914  pad->SetPosition( padpos + aModule->GetPosition() );
1915  }
1916 
1917  wxSize sz( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() );
1918 
1919  pad->SetDrillSize( sz );
1920  pad->SetSize( sz );
1921 
1922  pad->SetLayerSet( LSET::AllCuMask().set( B_Mask ).set( F_Mask ) );
1923 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:686
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:240
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:305
Eagle hole element.
Definition: eagle_parser.h:792
void SetPos0(const wxPoint &aPos)
Definition: class_pad.h:293
void SetSize(const wxSize &aSize)
Definition: class_pad.h:299
void SetPosition(const wxPoint &aPos) override
void SetAttribute(PAD_ATTR_T aAttribute)
Definition: class_pad.cpp:423
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:441
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:238
const wxPoint GetPosition() const override
Definition: class_module.h:210
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202

References MODULE::Add(), LSET::AllCuMask(), B_Mask, EHOLE::drill, F_Mask, MODULE::GetPosition(), kicad_x(), kicad_y(), PAD_ATTRIB_HOLE_NOT_PLATED, PAD_SHAPE_CIRCLE, D_PAD::SetAttribute(), D_PAD::SetDrillSize(), D_PAD::SetLayerSet(), D_PAD::SetPos0(), MODULE::SetPosition(), D_PAD::SetPosition(), D_PAD::SetShape(), D_PAD::SetSize(), ECOORD::ToPcbUnits(), EHOLE::x, and EHOLE::y.

Referenced by loadPlain(), and makeModule().

◆ packagePad()

void EAGLE_PLUGIN::packagePad ( MODULE aModule,
wxXmlNode *  aTree 
) const
private

Definition at line 1533 of file eagle_plugin.cpp.

1534 {
1535  // this is thru hole technology here, no SMDs
1536  EPAD e( aTree );
1537  int shape = EPAD::UNDEF;
1538 
1539  D_PAD* pad = new D_PAD( aModule );
1540  aModule->Add( pad );
1541  transferPad( e, pad );
1542 
1543  if( e.first && *e.first && m_rules->psFirst != EPAD::UNDEF )
1544  shape = m_rules->psFirst;
1545  else if( aModule->GetLayer() == F_Cu && m_rules->psTop != EPAD::UNDEF )
1546  shape = m_rules->psTop;
1547  else if( aModule->GetLayer() == B_Cu && m_rules->psBottom != EPAD::UNDEF )
1548  shape = m_rules->psBottom;
1549 
1550  pad->SetDrillSize( wxSize( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() ) );
1551  pad->SetLayerSet( LSET::AllCuMask() );
1552 
1553  // Solder mask
1554  if( !e.stop || *e.stop == true ) // enabled by default
1555  pad->SetLayerSet( pad->GetLayerSet().set( B_Mask ).set( F_Mask ) );
1556 
1557  if( shape == EPAD::ROUND || shape == EPAD::SQUARE || shape == EPAD::OCTAGON )
1558  e.shape = shape;
1559 
1560  if( e.shape )
1561  {
1562  switch( *e.shape )
1563  {
1564  case EPAD::ROUND:
1565  pad->SetShape( PAD_SHAPE_CIRCLE );
1566  break;
1567 
1568  case EPAD::OCTAGON:
1569  // no KiCad octagonal pad shape, use PAD_CIRCLE for now.
1570  // pad->SetShape( PAD_OCTAGON );
1571  wxASSERT( pad->GetShape() == PAD_SHAPE_CIRCLE ); // verify set in D_PAD constructor
1574  pad->SetChamferRectRatio( 0.25 );
1575  break;
1576 
1577  case EPAD::LONG:
1578  pad->SetShape( PAD_SHAPE_OVAL );
1579  break;
1580 
1581  case EPAD::SQUARE:
1582  pad->SetShape( PAD_SHAPE_RECT );
1583  break;
1584 
1585  case EPAD::OFFSET:
1586  pad->SetShape( PAD_SHAPE_OVAL );
1587  break;
1588  }
1589  }
1590  else
1591  {
1592  // if shape is not present, our default is circle and that matches their default "round"
1593  }
1594 
1595  if( e.diameter )
1596  {
1597  int diameter = e.diameter->ToPcbUnits();
1598  pad->SetSize( wxSize( diameter, diameter ) );
1599  }
1600  else
1601  {
1602  double drillz = pad->GetDrillSize().x;
1603  double annulus = drillz * m_rules->rvPadTop; // copper annulus, eagle "restring"
1604  annulus = eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
1605  int diameter = KiROUND( drillz + 2 * annulus );
1606  pad->SetSize( wxSize( KiROUND( diameter ), KiROUND( diameter ) ) );
1607  }
1608 
1609  if( pad->GetShape() == PAD_SHAPE_OVAL )
1610  {
1611  // The Eagle "long" pad is wider than it is tall,
1612  // m_elongation is percent elongation
1613  wxSize sz = pad->GetSize();
1614  sz.x = ( sz.x * ( 100 + m_rules->psElongationLong ) ) / 100;
1615  pad->SetSize( sz );
1616 
1617  if( e.shape && *e.shape == EPAD::OFFSET )
1618  {
1619  int offset = KiROUND( ( sz.x - sz.y ) / 2.0 );
1620  pad->SetOffset( wxPoint( offset, 0 ) );
1621  }
1622  }
1623 
1624  if( e.rot )
1625  {
1626  pad->SetOrientation( e.rot->degrees * 10 );
1627  }
1628 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:686
static T eagleClamp(T aMin, T aValue, T aMax)
int psTop
Shape of the top pads.
Definition: eagle_plugin.h:59
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
double rlMaxPadTop
maximum copper annulus on through hole pads
Definition: eagle_plugin.h:71
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:305
Eagle thru hole pad.
Definition: eagle_parser.h:699
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:442
void SetSize(const wxSize &aSize)
Definition: class_pad.h:299
int psElongationLong
percent over 100%.
Definition: eagle_plugin.h:47
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
int psFirst
Shape of the first pads.
Definition: eagle_plugin.h:61
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:441
const wxSize & GetDrillSize() const
Definition: class_pad.h:306
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:61
void transferPad(const EPAD_COMMON &aEaglePad, D_PAD *aPad) const
Handles common pad properties
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:238
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:438
void SetChamferRectRatio(double aChamferScale)
has meaning only for chamfered rect pads Set the ratio between the smaller Y or Y size and the radius...
Definition: class_pad.h:708
double rvPadTop
top pad size as percent of drill size
Definition: eagle_plugin.h:67
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:237
const wxSize & GetSize() const
Definition: class_pad.h:300
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:308
int psBottom
Shape of the bottom pads.
Definition: eagle_plugin.h:60
double rlMinPadTop
minimum copper annulus on through hole pads
Definition: eagle_plugin.h:70
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void SetChamferPositions(int aChamferPositions)
has meaning only for chamfered rect pads set the position of the chamfer for a 0 orientation,...
Definition: class_pad.h:728

References MODULE::Add(), LSET::AllCuMask(), B_Cu, B_Mask, EROT::degrees, EPAD::diameter, EPAD::drill, eagleClamp(), F_Cu, F_Mask, EPAD::first, D_PAD::GetDrillSize(), BOARD_ITEM::GetLayer(), D_PAD::GetLayerSet(), D_PAD::GetShape(), D_PAD::GetSize(), KiROUND(), EPAD::LONG, m_rules, EPAD::OCTAGON, EPAD::OFFSET, PAD_SHAPE_CHAMFERED_RECT, PAD_SHAPE_CIRCLE, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, ERULES::psBottom, ERULES::psElongationLong, ERULES::psFirst, ERULES::psTop, RECT_CHAMFER_ALL, ERULES::rlMaxPadTop, ERULES::rlMinPadTop, EPAD_COMMON::rot, EPAD::ROUND, ERULES::rvPadTop, D_PAD::SetChamferPositions(), D_PAD::SetChamferRectRatio(), D_PAD::SetDrillSize(), D_PAD::SetLayerSet(), D_PAD::SetOffset(), D_PAD::SetOrientation(), D_PAD::SetShape(), D_PAD::SetSize(), EPAD::shape, EPAD::SQUARE, EPAD_COMMON::stop, ECOORD::ToPcbUnits(), transferPad(), and EPAD::UNDEF.

Referenced by makeModule().

◆ packagePolygon()

void EAGLE_PLUGIN::packagePolygon ( MODULE aModule,
wxXmlNode *  aTree 
) const
private

Definition at line 1772 of file eagle_plugin.cpp.

1773 {
1774  EPOLYGON p( aTree );
1775  PCB_LAYER_ID layer = kicad_layer( p.layer );
1776  EDGE_MODULE* dwg = new EDGE_MODULE( aModule, S_POLYGON );
1777 
1778  aModule->Add( dwg );
1779 
1780  dwg->SetWidth( 0 ); // it's filled, no need for boundary width
1781  dwg->SetLayer( layer );
1782  dwg->SetTimeStamp( EagleTimeStamp( aTree ) );
1783 
1784  std::vector<wxPoint> pts;
1785 
1786  // Get the first vertex and iterate
1787  wxXmlNode* vertex = aTree->GetChildren();
1788  std::vector<EVERTEX> vertices;
1789 
1790  // Create a circular vector of vertices
1791  // The "curve" parameter indicates a curve from the current
1792  // to the next vertex, so we keep the first at the end as well
1793  // to allow the curve to link back
1794  while( vertex )
1795  {
1796  if( vertex->GetName() == "vertex" )
1797  vertices.emplace_back( vertex );
1798 
1799  vertex = vertex->GetNext();
1800  }
1801 
1802  vertices.push_back( vertices[0] );
1803 
1804  for( size_t i = 0; i < vertices.size() - 1; i++ )
1805  {
1806  EVERTEX v1 = vertices[i];
1807 
1808  // Append the corner
1809  pts.emplace_back( kicad_x( v1.x ), kicad_y( v1.y ) );
1810 
1811  if( v1.curve )
1812  {
1813  EVERTEX v2 = vertices[i + 1];
1814  wxPoint center = ConvertArcCenter(
1815  wxPoint( kicad_x( v1.x ), kicad_y( v1.y ) ),
1816  wxPoint( kicad_x( v2.x ), kicad_y( v2.y ) ), *v1.curve );
1817  double angle = DEG2RAD( *v1.curve );
1818  double end_angle = atan2( kicad_y( v2.y ) - center.y,
1819  kicad_x( v2.x ) - center.x );
1820  double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
1821  + pow( center.y - kicad_y( v1.y ), 2 ) );
1822 
1823  // Don't allow a zero-radius curve
1824  if( KiROUND( radius ) == 0 )
1825  radius = 1.0;
1826 
1827  int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, *v1.curve ) - 1;
1828 
1829  // If we are curving, we need at least 2 segments otherwise delta == angle
1830  if( segCount < 2 )
1831  segCount = 2;
1832 
1833  double delta = angle / segCount;
1834 
1835  for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta ); a -= delta )
1836  {
1837  pts.push_back(
1838  wxPoint( KiROUND( radius * cos( a ) ),
1839  KiROUND( radius * sin( a ) ) ) + center );
1840  }
1841  }
1842  }
1843 
1844  dwg->SetPolyPoints( pts );
1845  dwg->SetStart0( *pts.begin() );
1846  dwg->SetEnd0( pts.back() );
1847  dwg->SetDrawCoord();
1848  dwg->GetPolyShape().Inflate( p.width.ToPcbUnits() / 2, 32,
1850 }
Eagle vertex.
Definition: eagle_parser.h:752
void SetEnd0(const wxPoint &aPoint)
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
ECOORD y
Definition: eagle_parser.h:755
polygon (not yet used for tracks, but could be in microwave apps)
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Performs outline inflation/deflation.
PCB_LAYER_ID
A quick note on layer IDs:
SHAPE_POLY_SET & GetPolyShape()
timestamp_t EagleTimeStamp(wxXmlNode *aTree)
Make a unique time stamp
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:756
void SetPolyPoints(const std::vector< wxPoint > &aPoints)
ECOORD x
Definition: eagle_parser.h:754
double DEG2RAD(double deg)
Definition: trigo.h:210
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
void SetStart0(const wxPoint &aPoint)
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:61
Eagle polygon, without vertices which are parsed as needed.
Definition: eagle_parser.h:763
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:202
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212
void SetWidth(int aWidth)

References MODULE::Add(), SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS, PNS::angle(), ConvertArcCenter(), EVERTEX::curve, DEG2RAD(), EagleTimeStamp(), GetArcToSegmentCount(), DRAWSEGMENT::GetPolyShape(), SHAPE_POLY_SET::Inflate(), kicad_layer(), kicad_x(), kicad_y(), KiROUND(), EPOLYGON::layer, S_POLYGON, EDGE_MODULE::SetDrawCoord(), EDGE_MODULE::SetEnd0(), BOARD_ITEM::SetLayer(), DRAWSEGMENT::SetPolyPoints(), EDGE_MODULE::SetStart0(), EDA_ITEM::SetTimeStamp(), DRAWSEGMENT::SetWidth(), ECOORD::ToPcbUnits(), EPOLYGON::width, wxPoint::x, EVERTEX::x, wxPoint::y, and EVERTEX::y.

Referenced by makeModule().

◆ packageRectangle()

void EAGLE_PLUGIN::packageRectangle ( MODULE aModule,
wxXmlNode *  aTree 
) const
private

Definition at line 1737 of file eagle_plugin.cpp.

1738 {
1739  ERECT r( aTree );
1740  PCB_LAYER_ID layer = kicad_layer( r.layer );
1741  EDGE_MODULE* dwg = new EDGE_MODULE( aModule, S_POLYGON );
1742 
1743  aModule->Add( dwg );
1744 
1745  dwg->SetLayer( layer );
1746  dwg->SetWidth( 0 );
1747 
1748  dwg->SetTimeStamp( EagleTimeStamp( aTree ) );
1749 
1750  std::vector<wxPoint> pts;
1751 
1752  wxPoint start( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ) );
1753  wxPoint end( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
1754 
1755  pts.push_back( start );
1756  pts.emplace_back( kicad_x( r.x2 ), kicad_y( r.y1 ) );
1757  pts.emplace_back( kicad_x( r.x2 ), kicad_y( r.y2 ) );
1758  pts.push_back( end );
1759 
1760  dwg->SetPolyPoints( pts );
1761 
1762  dwg->SetStart0( start );
1763  dwg->SetEnd0( end );
1764 
1765  if( r.rot )
1766  {
1767  dwg->Rotate( dwg->GetCenter(), r.rot->degrees * 10 );
1768  }
1769 }
void SetEnd0(const wxPoint &aPoint)
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
const wxPoint GetCenter() const override
Function GetCenter()
polygon (not yet used for tracks, but could be in microwave apps)
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
PCB_LAYER_ID
A quick note on layer IDs:
timestamp_t EagleTimeStamp(wxXmlNode *aTree)
Make a unique time stamp
Eagle XML rectangle in binary.
Definition: eagle_parser.h:589
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
void SetPolyPoints(const std::vector< wxPoint > &aPoints)
void SetStart0(const wxPoint &aPoint)
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212
void SetWidth(int aWidth)

References MODULE::Add(), EROT::degrees, EagleTimeStamp(), DRAWSEGMENT::GetCenter(), kicad_layer(), kicad_x(), kicad_y(), ERECT::layer, ERECT::rot, EDGE_MODULE::Rotate(), S_POLYGON, EDGE_MODULE::SetEnd0(), BOARD_ITEM::SetLayer(), DRAWSEGMENT::SetPolyPoints(), EDGE_MODULE::SetStart0(), EDA_ITEM::SetTimeStamp(), DRAWSEGMENT::SetWidth(), ERECT::x1, ERECT::x2, ERECT::y1, and ERECT::y2.

Referenced by makeModule().

◆ packageSMD()

void EAGLE_PLUGIN::packageSMD ( MODULE aModule,
wxXmlNode *  aTree 
) const
private

Definition at line 1926 of file eagle_plugin.cpp.

1927 {
1928  ESMD e( aTree );
1929  PCB_LAYER_ID layer = kicad_layer( e.layer );
1930 
1931  if( !IsCopperLayer( layer ) )
1932  return;
1933 
1934  bool shape_set = false;
1935  int shape = EPAD::UNDEF;
1936  D_PAD* pad = new D_PAD( aModule );
1937  aModule->Add( pad );
1938  transferPad( e, pad );
1939 
1940  if( pad->GetName() == wxT( "1" ) && m_rules->psFirst != EPAD::UNDEF )
1941  shape = m_rules->psFirst;
1942  else if( layer == F_Cu && m_rules->psTop != EPAD::UNDEF )
1943  shape = m_rules->psTop;
1944  else if( layer == B_Cu && m_rules->psBottom != EPAD::UNDEF )
1945  shape = m_rules->psBottom;
1946 
1947  switch( shape )
1948  {
1949  case EPAD::ROUND:
1950  case EPAD::OCTAGON:
1951  shape_set = true;
1952  pad->SetShape( PAD_SHAPE_CIRCLE );
1953  break;
1954 
1955  case EPAD::SQUARE:
1956  shape_set = true;
1957  pad->SetShape( PAD_SHAPE_RECT );
1958  break;
1959 
1960  default:
1961  pad->SetShape( PAD_SHAPE_RECT );
1962  }
1963 
1964  pad->SetAttribute( PAD_ATTRIB_SMD );
1965 
1966  wxSize padSize( e.dx.ToPcbUnits(), e.dy.ToPcbUnits() );
1967  pad->SetSize( padSize );
1968  pad->SetLayer( layer );
1969 
1970  const LSET front( 3, F_Cu, F_Paste, F_Mask );
1971  const LSET back( 3, B_Cu, B_Paste, B_Mask );
1972 
1973  if( layer == F_Cu )
1974  pad->SetLayerSet( front );
1975  else if( layer == B_Cu )
1976  pad->SetLayerSet( back );
1977 
1978  int minPadSize = std::min( padSize.x, padSize.y );
1979 
1980  // Rounded rectangle pads
1981  int roundRadius = eagleClamp( m_rules->srMinRoundness * 2,
1982  (int)( minPadSize * m_rules->srRoundness ), m_rules->srMaxRoundness * 2 );
1983 
1984  if( !shape_set && ( e.roundness || roundRadius > 0 ) )
1985  {
1986  double roundRatio = (double) roundRadius / minPadSize / 2.0;
1987 
1988  // Eagle uses a different definition of roundness, hence division by 200
1989  if( e.roundness )
1990  roundRatio = std::fmax( *e.roundness / 200.0, roundRatio );
1991 
1992  pad->SetShape( PAD_SHAPE_ROUNDRECT );
1993  pad->SetRoundRectRadiusRatio( roundRatio );
1994  }
1995 
1996  if( e.rot )
1997  {
1998  pad->SetOrientation( e.rot->degrees * 10 );
1999  }
2000 
2002  (int) ( m_rules->mvCreamFrame * minPadSize ),
2003  m_rules->mlMaxCreamFrame ) );
2004 
2005  // Solder mask
2006  if( e.stop && *e.stop == false ) // enabled by default
2007  {
2008  if( layer == F_Cu )
2009  pad->SetLayerSet( pad->GetLayerSet().set( F_Mask, false ) );
2010  else if( layer == B_Cu )
2011  pad->SetLayerSet( pad->GetLayerSet().set( B_Mask, false ) );
2012  }
2013 
2014  // Solder paste (only for SMD pads)
2015  if( e.cream && *e.cream == false ) // enabled by default
2016  {
2017  if( layer == F_Cu )
2018  pad->SetLayerSet( pad->GetLayerSet().set( F_Paste, false ) );
2019  else if( layer == B_Cu )
2020  pad->SetLayerSet( pad->GetLayerSet().set( B_Paste, false ) );
2021  }
2022 }
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.
int psTop
Shape of the top pads.
Definition: eagle_plugin.h:59
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:62
int srMinRoundness
corner rounding radius, minimum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:64
Eagle SMD pad.
Definition: eagle_parser.h:721
void SetRoundRectRadiusRatio(double aRadiusScale)
has meaning only for rounded rect pads Set the scaling factor between the smaller Y or Y size and the...
Definition: class_pad.h:683
PCB_LAYER_ID
A quick note on layer IDs:
LSET is a set of PCB_LAYER_IDs.
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:442
const wxString & GetName() const
Definition: class_pad.h:203
void SetSize(const wxSize &aSize)
Definition: class_pad.h:299
double srRoundness
corner rounding ratio for SMD pads (percentage)
Definition: eagle_plugin.h:63
void SetAttribute(PAD_ATTR_T aAttribute)
Definition: class_pad.cpp:423
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
int psFirst
Shape of the first pads.
Definition: eagle_plugin.h:61
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:441
int mlMinCreamFrame
solder paste mask, minimum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:56
void transferPad(const EPAD_COMMON &aEaglePad, D_PAD *aPad) const
Handles common pad properties
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:238
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:438
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_pad.h:464
int psBottom
Shape of the bottom pads.
Definition: eagle_plugin.h:60
int mlMaxCreamFrame
solder paste mask, maximum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:57
int srMaxRoundness
corner rounding radius, maximum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:65
double mvCreamFrame
solderpaste mask, expressed as percentage of the smaller pad/via dimension
Definition: eagle_plugin.h:53

References MODULE::Add(), B_Cu, B_Mask, B_Paste, ESMD::cream, EROT::degrees, ESMD::dx, ESMD::dy, eagleClamp(), F_Cu, F_Mask, F_Paste, D_PAD::GetLayerSet(), D_PAD::GetName(), IsCopperLayer(), kicad_layer(), ESMD::layer, m_rules, ERULES::mlMaxCreamFrame, ERULES::mlMinCreamFrame, ERULES::mvCreamFrame, EPAD::OCTAGON, PAD_ATTRIB_SMD, PAD_SHAPE_CIRCLE, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, ERULES::psBottom, ERULES::psFirst, ERULES::psTop, EPAD_COMMON::rot, EPAD::ROUND, ESMD::roundness, D_PAD::SetAttribute(), BOARD_ITEM::SetLayer(), D_PAD::SetLayerSet(), D_PAD::SetLocalSolderPasteMargin(), D_PAD::SetOrientation(), D_PAD::SetRoundRectRadiusRatio(), D_PAD::SetShape(), D_PAD::SetSize(), EPAD::SQUARE, ERULES::srMaxRoundness, ERULES::srMinRoundness, ERULES::srRoundness, EPAD_COMMON::stop, ECOORD::ToPcbUnits(), transferPad(), and EPAD::UNDEF.

Referenced by makeModule().

◆ packageText()

void EAGLE_PLUGIN::packageText ( MODULE aModule,
wxXmlNode *  aTree 
) const
private

Definition at line 1631 of file eagle_plugin.cpp.

1632 {
1633  ETEXT t( aTree );
1634  PCB_LAYER_ID layer = kicad_layer( t.layer );
1635 
1636  if( layer == UNDEFINED_LAYER )
1637  {
1638  layer = Cmts_User;
1639  }
1640 
1641  TEXTE_MODULE* txt;
1642 
1643  if( t.text == ">NAME" || t.text == ">name" )
1644  txt = &aModule->Reference();
1645  else if( t.text == ">VALUE" || t.text == ">value" )
1646  txt = &aModule->Value();
1647  else
1648  {
1649  // FIXME: graphical text items are rotated for some reason.
1650  txt = new TEXTE_MODULE( aModule );
1651  aModule->Add( txt );
1652  }
1653 
1654  txt->SetTimeStamp( EagleTimeStamp( aTree ) );
1655  txt->SetText( FROM_UTF8( t.text.c_str() ) );
1656 
1657  wxPoint pos( kicad_x( t.x ), kicad_y( t.y ) );
1658 
1659  txt->SetTextPos( pos );
1660  txt->SetPos0( pos - aModule->GetPosition() );
1661 
1662  txt->SetLayer( layer );
1663  txt->SetTextSize( kicad_fontz( t.size ) );
1664 
1665  double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
1666 
1667  txt->SetThickness( t.size.ToPcbUnits() * ratio / 100 );
1668 
1669  int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
1670 
1671  // An eagle package is never rotated, the DTD does not allow it.
1672  // angle -= aModule->GetOrienation();
1673 
1674  if( t.rot )
1675  {
1676  int sign = t.rot->mirror ? -1 : 1;
1677  txt->SetMirrored( t.rot->mirror );
1678 
1679  double degrees = t.rot->degrees;
1680 
1681  if( degrees == 90 || t.rot->spin )
1682  txt->SetTextAngle( sign * degrees * 10 );
1683  else if( degrees == 180 )
1684  align = ETEXT::TOP_RIGHT;
1685  else if( degrees == 270 )
1686  {
1687  align = ETEXT::TOP_RIGHT;
1688  txt->SetTextAngle( sign * 90 * 10 );
1689  }
1690  }
1691 
1692  switch( align )
1693  {
1694  case ETEXT::CENTER:
1695  // this was the default in pcbtxt's constructor
1696  break;
1697 
1698  case ETEXT::CENTER_LEFT:
1700  break;
1701 
1702  case ETEXT::CENTER_RIGHT:
1704  break;
1705 
1706  case ETEXT::TOP_CENTER:
1708  break;
1709 
1710  case ETEXT::TOP_LEFT:
1713  break;
1714 
1715  case ETEXT::TOP_RIGHT:
1718  break;
1719 
1720  case ETEXT::BOTTOM_CENTER:
1722  break;
1723 
1724  case ETEXT::BOTTOM_LEFT:
1727  break;
1728 
1729  case ETEXT::BOTTOM_RIGHT:
1732  break;
1733  }
1734 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:172
int sign(T val)
Definition: util.h:90
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
TEXTE_MODULE & Reference()
Definition: class_module.h:477
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:231
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
Eagle text element.
Definition: eagle_parser.h:651
PCB_LAYER_ID
A quick note on layer IDs:
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:111
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:476
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:187
timestamp_t EagleTimeStamp(wxXmlNode *aTree)
Make a unique time stamp
void SetPos0(const wxPoint &aPos)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:186
wxSize kicad_fontz(const ECOORD &d) const
create a font size (fontz) from an eagle font size scalar
void SetTextAngle(double aAngle)
const wxPoint GetPosition() const override
Definition: class_module.h:210
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
void SetThickness(int aNewThickness)
Set the pen width.
Definition: eda_text.h:143
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212

References MODULE::Add(), ETEXT::align, ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, ETEXT::CENTER, ETEXT::CENTER_LEFT, ETEXT::CENTER_RIGHT, Cmts_User, EROT::degrees, EagleTimeStamp(), FROM_UTF8(), MODULE::GetPosition(), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_TOP, kicad_fontz(), kicad_layer(), kicad_x(), kicad_y(), ETEXT::layer, EROT::mirror, ETEXT::ratio, MODULE::Reference(), ETEXT::rot, EDA_TEXT::SetHorizJustify(), BOARD_ITEM::SetLayer(), EDA_TEXT::SetMirrored(), TEXTE_MODULE::SetPos0(), EDA_TEXT::SetText(), TEXTE_MODULE::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetThickness(), EDA_ITEM::SetTimeStamp(), EDA_TEXT::SetVertJustify(), sign(), ETEXT::size, EROT::spin, ETEXT::text, ETEXT::TOP_CENTER, ETEXT::TOP_LEFT, ETEXT::TOP_RIGHT, ECOORD::ToPcbUnits(), UNDEFINED_LAYER, MODULE::Value(), ETEXT::x, and ETEXT::y.

Referenced by makeModule().

◆ packageWire()

void EAGLE_PLUGIN::packageWire ( MODULE aModule,
wxXmlNode *  aTree 
) const
private

Definition at line 1464 of file eagle_plugin.cpp.

1465 {
1466  EWIRE w( aTree );
1467  PCB_LAYER_ID layer = kicad_layer( w.layer );
1468  wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
1469  wxPoint end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
1470  int width = w.width.ToPcbUnits();
1471 
1472  // KiCad cannot handle zero or negative line widths which apparently have meaning in Eagle.
1473  if( width <= 0 )
1474  {
1475  BOARD* board = aModule->GetBoard();
1476 
1477  if( board )
1478  {
1479  width = board->GetDesignSettings().GetLineThickness( layer );
1480  }
1481  else
1482  {
1483  // When loading footprint libraries, there is no board so use the default KiCad
1484  // line widths.
1485  switch( layer )
1486  {
1487  case Edge_Cuts:
1488  width = Millimeter2iu( DEFAULT_EDGE_WIDTH );
1489  break;
1490  case F_SilkS:
1491  case B_SilkS:
1492  width = Millimeter2iu( DEFAULT_SILK_LINE_WIDTH );
1493  break;
1494  case F_CrtYd:
1495  case B_CrtYd:
1496  width = Millimeter2iu( DEFAULT_COURTYARD_WIDTH );
1497  break;
1498  default:
1499  width = Millimeter2iu( DEFAULT_LINE_WIDTH );
1500  }
1501  }
1502  }
1503 
1504  // FIXME: the cap attribute is ignored because KiCad can't create lines
1505  // with flat ends.
1506  EDGE_MODULE* dwg;
1507 
1508  if( !w.curve )
1509  {
1510  dwg = new EDGE_MODULE( aModule, S_SEGMENT );
1511 
1512  dwg->SetStart0( start );
1513  dwg->SetEnd0( end );
1514  }
1515  else
1516  {
1517  dwg = new EDGE_MODULE( aModule, S_ARC );
1518  wxPoint center = ConvertArcCenter( start, end, *w.curve );
1519 
1520  dwg->SetStart0( center );
1521  dwg->SetEnd0( start );
1522  dwg->SetAngle( *w.curve * -10.0 ); // KiCad rotates the other way
1523  }
1524 
1525  dwg->SetLayer( layer );
1526  dwg->SetWidth( width );
1527  dwg->SetDrawCoord();
1528 
1529  aModule->Add( dwg );
1530 }
#define DEFAULT_EDGE_WIDTH
void SetEnd0(const wxPoint &aPoint)
#define DEFAULT_COURTYARD_WIDTH
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
#define DEFAULT_LINE_WIDTH
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
usual segment : line with rounded ends
int GetLineThickness(PCB_LAYER_ID aLayer) const
Function GetLineThickness Returns the default graphic segment thickness from the layer class for the ...
PCB_LAYER_ID
A quick note on layer IDs:
#define DEFAULT_SILK_LINE_WIDTH
Arcs (with rounded ends)
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:160
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
void SetStart0(const wxPoint &aPoint)
Eagle wire.
Definition: eagle_parser.h:505
void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
void SetWidth(int aWidth)

References MODULE::Add(), B_CrtYd, B_SilkS, ConvertArcCenter(), EWIRE::curve, DEFAULT_COURTYARD_WIDTH, DEFAULT_EDGE_WIDTH, DEFAULT_LINE_WIDTH, DEFAULT_SILK_LINE_WIDTH, Edge_Cuts, F_CrtYd, F_SilkS, BOARD_ITEM::GetBoard(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetLineThickness(), kicad_layer(), kicad_x(), kicad_y(), EWIRE::layer, S_ARC, S_SEGMENT, DRAWSEGMENT::SetAngle(), EDGE_MODULE::SetDrawCoord(), EDGE_MODULE::SetEnd0(), BOARD_ITEM::SetLayer(), EDGE_MODULE::SetStart0(), DRAWSEGMENT::SetWidth(), ECOORD::ToPcbUnits(), EWIRE::width, EWIRE::x1, EWIRE::x2, EWIRE::y1, and EWIRE::y2.

Referenced by makeModule().

◆ PluginName()

const wxString EAGLE_PLUGIN::PluginName ( ) const
overridevirtual

Function PluginName returns a brief hard coded name for this PLUGIN.

Implements PLUGIN.

Definition at line 201 of file eagle_plugin.cpp.

202 {
203  return wxT( "Eagle" );
204 }

◆ PrefetchLib()

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

Function PrefetchLib 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.

Reimplemented in GITHUB_PLUGIN.

Definition at line 68 of file plugin.cpp.

69 {
70  (void) aLibraryPath;
71  (void) aProperties;
72 }

◆ Save()

void PLUGIN::Save ( const wxString &  aFileName,
BOARD aBoard,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Function Save will 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.

Parameters
aFileNameis the name of a file to save to on disk.
aBoardis the class BOARD in memory document tree from which to extract information when writing to aFileName. The caller continues to own the BOARD, and the plugin should refrain from modifying the BOARD if possible.
aPropertiesis an associative array that can be used to tell the saver how to save the file, 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 or exporting.

Reimplemented in PCB_IO, and CLIPBOARD_IO.

Definition at line 53 of file plugin.cpp.

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

References not_implemented().

Referenced by IO_MGR::Save().

◆ transferPad()

void EAGLE_PLUGIN::transferPad ( const EPAD_COMMON aEaglePad,
D_PAD aPad 
) const
private

Handles common pad properties

Definition at line 2025 of file eagle_plugin.cpp.

2026 {
2027  aPad->SetName( FROM_UTF8( aEaglePad.name.c_str() ) );
2028 
2029  // pad's "Position" is not relative to the module's,
2030  // whereas Pos0 is relative to the module's but is the unrotated coordinate.
2031  wxPoint padPos( kicad_x( aEaglePad.x ), kicad_y( aEaglePad.y ) );
2032  aPad->SetPos0( padPos );
2033 
2034  // Solder mask
2035  const wxSize& padSize( aPad->GetSize() );
2036 
2038  (int)( m_rules->mvStopFrame * std::min( padSize.x, padSize.y ) ),
2039  m_rules->mlMaxStopFrame ) );
2040 
2041  // Solid connection to copper zones
2042  if( aEaglePad.thermals && !*aEaglePad.thermals )
2044 
2045  MODULE* module = aPad->GetParent();
2046  wxCHECK( module, /* void */ );
2047  RotatePoint( &padPos, module->GetOrientation() );
2048  aPad->SetPosition( padPos + module->GetPosition() );
2049 }
double GetOrientation() const
Definition: class_module.h:215
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:203
static T eagleClamp(T aMin, T aValue, T aMax)
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:173
int mlMinStopFrame
solder mask, minimum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:54
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:240
wxString name
Definition: eagle_parser.h:688
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
opt_bool thermals
Definition: eagle_parser.h:692
pads are covered by copper
void SetName(const wxString &aName)
Set the pad name (sometimes called pad number, although it can be an array reference like AA12).
Definition: class_pad.h:187
void SetPos0(const wxPoint &aPos)
Definition: class_pad.h:293
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: class_pad.h:526
MODULE * GetParent() const
Definition: class_pad.h:167
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_pad.h:458
double mvStopFrame
solder mask, expressed as percentage of the smaller pad/via dimension
Definition: eagle_plugin.h:52
const wxSize & GetSize() const
Definition: class_pad.h:300
const wxPoint GetPosition() const override
Definition: class_module.h:210
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:202
int mlMaxStopFrame
solder mask, maximum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:55

References eagleClamp(), FROM_UTF8(), FULL, MODULE::GetOrientation(), D_PAD::GetParent(), MODULE::GetPosition(), D_PAD::GetSize(), kicad_x(), kicad_y(), m_rules, ERULES::mlMaxStopFrame, ERULES::mlMinStopFrame, ERULES::mvStopFrame, EPAD_COMMON::name, RotatePoint(), D_PAD::SetLocalSolderMaskMargin(), D_PAD::SetName(), D_PAD::SetPos0(), D_PAD::SetPosition(), D_PAD::SetZoneConnection(), EPAD_COMMON::thermals, EPAD_COMMON::x, and EPAD_COMMON::y.

Referenced by packagePad(), and packageSMD().

Member Data Documentation

◆ m_board

BOARD* EAGLE_PLUGIN::m_board
private

which BOARD is being worked on, no ownership here

Definition at line 187 of file eagle_plugin.h.

Referenced by centerBoard(), init(), Load(), loadElements(), loadLayerDefs(), loadPlain(), loadPolygon(), loadSignals(), and makeModule().

◆ m_cu_map

int EAGLE_PLUGIN::m_cu_map[17]
private

map eagle to kicad, cu layers only.

Definition at line 170 of file eagle_plugin.h.

Referenced by clear_cu_map(), kicad_layer(), and loadLayerDefs().

◆ m_eagleLayers

std::map<int, ELAYER> EAGLE_PLUGIN::m_eagleLayers
private

Eagle layers data stored by the layer number.

Definition at line 171 of file eagle_plugin.h.

Referenced by eagle_layer_name(), and loadLayerDefs().

◆ m_hole_count

int EAGLE_PLUGIN::m_hole_count
private

generates unique module names from eagle "hole"s.

Definition at line 177 of file eagle_plugin.h.

Referenced by init(), and loadPlain().

◆ m_lib_path

wxString EAGLE_PLUGIN::m_lib_path
private

Definition at line 193 of file eagle_plugin.h.

Referenced by cacheLib(), and loadLibrary().

◆ m_min_trace

int EAGLE_PLUGIN::m_min_trace
private

smallest trace we find on Load(), in BIU.

Definition at line 189 of file eagle_plugin.h.

Referenced by init(), Load(), and loadSignals().

◆ m_min_via

int EAGLE_PLUGIN::m_min_via
private

smallest via we find on Load(), in BIU.

Definition at line 190 of file eagle_plugin.h.

Referenced by init(), Load(), and loadSignals().

◆ m_min_via_hole

int EAGLE_PLUGIN::m_min_via_hole
private

smallest via diameter hole we find on Load(), in BIU.

Definition at line 191 of file eagle_plugin.h.

Referenced by init(), Load(), and loadSignals().

◆ m_mod_time

wxDateTime EAGLE_PLUGIN::m_mod_time
private

Definition at line 194 of file eagle_plugin.h.

Referenced by cacheLib().

◆ m_pads_to_nets

NET_MAP EAGLE_PLUGIN::m_pads_to_nets
private

net list

Definition at line 179 of file eagle_plugin.h.

Referenced by init(), loadElements(), and loadSignals().

◆ m_props

const PROPERTIES* EAGLE_PLUGIN::m_props
private

passed via Save() or Load(), no ownership, may be NULL.

Definition at line 186 of file eagle_plugin.h.

Referenced by centerBoard(), and init().

◆ m_rules

ERULES* EAGLE_PLUGIN::m_rules
private

Eagle design rules.

Definition at line 173 of file eagle_plugin.h.

Referenced by init(), Load(), loadDesignRules(), loadSignals(), packagePad(), packageSMD(), transferPad(), and ~EAGLE_PLUGIN().

◆ m_templates

MODULE_MAP EAGLE_PLUGIN::m_templates
private

is part of a MODULE factory that operates using copy construction.

lookup key is either libname.packagename or simply packagename if FootprintLoad() or FootprintEnumberate()

Definition at line 181 of file eagle_plugin.h.

Referenced by deleteTemplates(), FootprintEnumerate(), FootprintLoad(), loadElements(), and loadLibrary().

◆ m_xpath

XPATH* EAGLE_PLUGIN::m_xpath
private

keeps track of what we are working on within XML document during a Load().

Definition at line 174 of file eagle_plugin.h.

Referenced by cacheLib(), init(), Load(), loadAllSections(), loadDesignRules(), loadElements(), loadLibraries(), loadLibrary(), loadPlain(), loadSignals(), and ~EAGLE_PLUGIN().


The documentation for this class was generated from the following files: