KiCad PCB EDA Suite
EAGLE_PLUGIN Class Reference

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

#include <eagle_plugin.h>

Inheritance diagram for EAGLE_PLUGIN:
PLUGIN LAYER_REMAPPABLE_PLUGIN

Public Types

typedef int BIU
 

Public Member Functions

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

Protected Attributes

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

Private Types

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

Private Member Functions

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

Static Private Member Functions

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

Private Attributes

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

Detailed Description

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

Definition at line 129 of file eagle_plugin.h.

Member Typedef Documentation

◆ BIU

typedef int EAGLE_PLUGIN::BIU

Definition at line 161 of file eagle_plugin.h.

◆ EITER

typedef ELAYERS::const_iterator EAGLE_PLUGIN::EITER
private

Definition at line 315 of file eagle_plugin.h.

◆ ELAYERS

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

Definition at line 314 of file eagle_plugin.h.

Constructor & Destructor Documentation

◆ EAGLE_PLUGIN()

EAGLE_PLUGIN::EAGLE_PLUGIN ( )

Definition at line 220 of file eagle_plugin.cpp.

220 :
221 m_rules( new ERULES() ),
222 m_xpath( new XPATH() ),
223 m_progressReporter( nullptr ),
224 m_doneCount( 0 ),
226 m_totalCount( 0 ),
227 m_mod_time( wxDateTime::Now() )
228{
229 using namespace std::placeholders;
230
231 init( nullptr );
232 clear_cu_map();
234 this, _1 ) );
235}
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
Definition: eagle_plugin.h:328
void clear_cu_map()
unsigned m_totalCount
for progress reporting
Definition: eagle_plugin.h:346
ERULES * m_rules
Eagle design rules.
Definition: eagle_plugin.h:327
unsigned m_doneCount
Definition: eagle_plugin.h:344
wxDateTime m_mod_time
Definition: eagle_plugin.h:354
std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
Return the automapped layers.
void init(const STRING_UTF8_MAP *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
unsigned m_lastProgressCount
Definition: eagle_plugin.h:345
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
Definition: eagle_plugin.h:343
virtual void RegisterLayerMappingCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
Keep track of what we are working on within a PTREE.
Definition: eagle_parser.h:117
subset of eagle.drawing.board.designrules in the XML document
Definition: eagle_plugin.h:51

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

◆ ~EAGLE_PLUGIN()

EAGLE_PLUGIN::~EAGLE_PLUGIN ( )

Definition at line 238 of file eagle_plugin.cpp.

239{
241 delete m_rules;
242 delete m_xpath;
243}
void deleteTemplates()

References deleteTemplates(), m_rules, and m_xpath.

Member Function Documentation

◆ cacheLib()

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

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

Definition at line 3073 of file eagle_plugin.cpp.

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

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

Referenced by FootprintEnumerate(), and FootprintLoad().

◆ centerBoard()

void EAGLE_PLUGIN::centerBoard ( )
private

move the BOARD into the center of the page

Definition at line 3034 of file eagle_plugin.cpp.

3035{
3036 if( m_props )
3037 {
3038 UTF8 page_width;
3039 UTF8 page_height;
3040
3041 if( m_props->Value( "page_width", &page_width ) &&
3042 m_props->Value( "page_height", &page_height ) )
3043 {
3045
3046 int w = atoi( page_width.c_str() );
3047 int h = atoi( page_height.c_str() );
3048
3049 int desired_x = ( w - bbbox.GetWidth() ) / 2;
3050 int desired_y = ( h - bbbox.GetHeight() ) / 2;
3051
3052 m_board->Move( VECTOR2I( desired_x - bbbox.GetX(), desired_y - bbbox.GetY() ) );
3053 }
3054 }
3055}
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
Definition: board.h:823
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: board.cpp:383
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetY() const
Definition: box2.h:181
coord_type GetWidth() const
Definition: box2.h:187
coord_type GetX() const
Definition: box2.h:180
const STRING_UTF8_MAP * m_props
passed via Save() or Load(), no ownership, may be NULL.
Definition: eagle_plugin.h:340
BOARD * m_board
which BOARD is being worked on, no ownership here
Definition: eagle_plugin.h:341
bool Value(const char *aName, UTF8 *aFetchedValue=nullptr) const
Fetch a property by aName and returns true if that property was found, else false.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:71
const char * c_str() const
Definition: utf8.h:102
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References UTF8::c_str(), BOARD::GetBoardEdgesBoundingBox(), BOX2< Vec >::GetHeight(), BOX2< Vec >::GetWidth(), BOX2< Vec >::GetX(), BOX2< Vec >::GetY(), m_board, m_props, BOARD::Move(), and STRING_UTF8_MAP::Value().

Referenced by Load().

◆ checkpoint()

void EAGLE_PLUGIN::checkpoint ( )
private

Definition at line 258 of file eagle_plugin.cpp.

259{
260 const unsigned PROGRESS_DELTA = 50;
261
263 {
264 if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA )
265 {
267 / std::max( 1U, m_totalCount ) );
268
270 THROW_IO_ERROR( _( "Open cancelled by user." ) );
271
273 }
274 }
275}
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).

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

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

◆ clear_cu_map()

void EAGLE_PLUGIN::clear_cu_map ( )
private

Definition at line 439 of file eagle_plugin.cpp.

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

References arrayDim(), and m_cu_map.

Referenced by cacheLib(), and EAGLE_PLUGIN().

◆ defaultKicadLayer()

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

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

Note
The Eagle MILLING, TTEST, BTEST, and HOLES layers are set to UNDEFINED_LAYER for historical purposes. All other Eagle layers that do not directly map to KiCad layers will be set to UNDEFINED_LAYER when loading Eagle footprint libraries. This should be addressed in the future because in some cases this will cause data loss.
See also
EAGLE_LAYER and defaultKiCadLayer().
Parameters
aEagleLayeris the Eagle layer to map.
aIsLibraryCacheis a flag to indicate if the mapping is for board or footprint library cache objects.
Returns
a tuple containing the mapped layer.

Definition at line 2884 of file eagle_plugin.cpp.

2886{
2887 // eagle copper layer:
2888 if( aEagleLayer >= 1 && aEagleLayer < int( arrayDim( m_cu_map ) ) )
2889 {
2890 LSET copperLayers;
2891
2892 for( int copperLayer : m_cu_map )
2893 {
2894 if( copperLayer >= 0 )
2895 copperLayers[copperLayer] = true;
2896 }
2897
2898 return { PCB_LAYER_ID( m_cu_map[aEagleLayer] ), copperLayers, true };
2899 }
2900
2901 int kiLayer = UNSELECTED_LAYER;
2902 bool required = false;
2903 LSET permittedLayers;
2904
2905 permittedLayers.set();
2906
2907 // translate non-copper eagle layer to pcbnew layer
2908 switch( aEagleLayer )
2909 {
2910 // Eagle says "Dimension" layer, but it's for board perimeter
2912 kiLayer = Edge_Cuts;
2913 required = true;
2914 permittedLayers = LSET( 1, Edge_Cuts );
2915 break;
2916
2918 kiLayer = F_SilkS;
2919 break;
2921 kiLayer = B_SilkS;
2922 break;
2924 kiLayer = F_SilkS;
2925 break;
2927 kiLayer = B_SilkS;
2928 break;
2930 kiLayer = F_Fab;
2931 break;
2933 kiLayer = B_Fab;
2934 break;
2935 case EAGLE_LAYER::TSTOP:
2936 kiLayer = F_Mask;
2937 break;
2938 case EAGLE_LAYER::BSTOP:
2939 kiLayer = B_Mask;
2940 break;
2942 kiLayer = F_Paste;
2943 break;
2945 kiLayer = B_Paste;
2946 break;
2948 kiLayer = F_Mask;
2949 break;
2951 kiLayer = B_Mask;
2952 break;
2953 case EAGLE_LAYER::TGLUE:
2954 kiLayer = F_Adhes;
2955 break;
2956 case EAGLE_LAYER::BGLUE:
2957 kiLayer = B_Adhes;
2958 break;
2960 kiLayer = Cmts_User;
2961 break;
2963 kiLayer = Cmts_User;
2964 break;
2966 kiLayer = Cmts_User;
2967 break;
2968
2969 // Packages show the future chip pins on SMD parts using layer 51.
2970 // This is an area slightly smaller than the PAD/SMD copper area.
2971 // Carry those visual aids into the FOOTPRINT on the fabrication layer,
2972 // not silkscreen. This is perhaps not perfect, but there is not a lot
2973 // of other suitable paired layers
2974 case EAGLE_LAYER::TDOCU:
2975 kiLayer = F_Fab;
2976 break;
2977 case EAGLE_LAYER::BDOCU:
2978 kiLayer = B_Fab;
2979 break;
2980
2981 // these layers are defined as user layers. put them on ECO layers
2983 kiLayer = Eco1_User;
2984 break;
2986 kiLayer = Eco2_User;
2987 break;
2988
2989 // these will also appear in the ratsnest, so there's no need for a warning
2991 kiLayer = Dwgs_User;
2992 break;
2993
2995 kiLayer = F_CrtYd;
2996 break;
2998 kiLayer = B_CrtYd;
2999 break;
3000
3002 case EAGLE_LAYER::TTEST:
3003 case EAGLE_LAYER::BTEST:
3004 case EAGLE_LAYER::HOLES:
3005 default:
3006 if( aIsLibraryCache )
3007 kiLayer = UNDEFINED_LAYER;
3008 else
3009 kiLayer = UNSELECTED_LAYER;
3010
3011 break;
3012 }
3013
3014 return { PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3015}
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ F_CrtYd
Definition: layer_ids.h:117
@ B_Adhes
Definition: layer_ids.h:97
@ Edge_Cuts
Definition: layer_ids.h:113
@ Dwgs_User
Definition: layer_ids.h:109
@ F_Paste
Definition: layer_ids.h:101
@ Cmts_User
Definition: layer_ids.h:110
@ F_Adhes
Definition: layer_ids.h:98
@ B_Mask
Definition: layer_ids.h:106
@ Eco1_User
Definition: layer_ids.h:111
@ F_Mask
Definition: layer_ids.h:107
@ B_Paste
Definition: layer_ids.h:100
@ UNSELECTED_LAYER
Definition: layer_ids.h:61
@ F_Fab
Definition: layer_ids.h:120
@ F_SilkS
Definition: layer_ids.h:104
@ B_CrtYd
Definition: layer_ids.h:116
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
@ Eco2_User
Definition: layer_ids.h:112
@ B_SilkS
Definition: layer_ids.h:103
@ B_Fab
Definition: layer_ids.h:119

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

Referenced by DefaultLayerMappingCallback(), and mapEagleLayersToKicad().

◆ DefaultLayerMappingCallback()

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

Return the automapped layers.

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

Parameters
aInputLayerDescriptionVector
Returns
Auto-mapped layers

Definition at line 2832 of file eagle_plugin.cpp.

2834{
2835 std::map<wxString, PCB_LAYER_ID> layer_map;
2836
2837 for ( const INPUT_LAYER_DESC& layer : aInputLayerDescriptionVector )
2838 {
2839 PCB_LAYER_ID layerId = std::get<0>( defaultKicadLayer( eagle_layer_id( layer.Name ) ) );
2840 layer_map.emplace( layer.Name, layerId );
2841 }
2842
2843 return layer_map;
2844}
std::tuple< PCB_LAYER_ID, LSET, bool > defaultKicadLayer(int aEagleLayer, bool aIsLibraryCache=false) const
Get the default KiCad layer corresponding to an Eagle layer of the board, a set of sensible layer map...
int eagle_layer_id(const wxString &aLayerName) const
Get Eagle layer number by its name.
Describes an imported layer and how it could be mapped to KiCad Layers.

References defaultKicadLayer(), and eagle_layer_id().

Referenced by EAGLE_PLUGIN().

◆ deleteTemplates()

void EAGLE_PLUGIN::deleteTemplates ( )
private

Definition at line 2486 of file eagle_plugin.cpp.

2487{
2488 for( auto& t : m_templates )
2489 delete t.second;
2490
2491 m_templates.clear();
2492}
FOOTPRINT_MAP m_templates
is part of a FOOTPRINT factory that operates using copy construction.
Definition: eagle_plugin.h:335

References m_templates.

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

◆ eagle_layer_id()

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

Get Eagle layer number by its name.

Definition at line 3026 of file eagle_plugin.cpp.

3027{
3028 static const int unknown = -1;
3029 auto it = m_eagleLayersIds.find( aLayerName );
3030 return it == m_eagleLayersIds.end() ? unknown : it->second;
3031}
std::map< wxString, int > m_eagleLayersIds
Eagle layer ids stored by layer name.
Definition: eagle_plugin.h:319

References m_eagleLayersIds, and unknown.

Referenced by DefaultLayerMappingCallback().

◆ eagle_layer_name()

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

Get Eagle layer name by its number.

Definition at line 3018 of file eagle_plugin.cpp.

3019{
3020 static const wxString unknown( "unknown" );
3021 auto it = m_eagleLayers.find( aLayer );
3022 return it == m_eagleLayers.end() ? unknown : it->second.name;
3023}
std::map< int, ELAYER > m_eagleLayers
Eagle layer data stored by layer number.
Definition: eagle_plugin.h:318

References m_eagleLayers, and unknown.

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

◆ FootprintDelete()

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

Delete aFootprintName from the library at aLibraryPath.

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

Reimplemented in GPCB_PLUGIN, and PCB_PLUGIN.

Definition at line 114 of file plugin.cpp.

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

References not_implemented().

Referenced by FP_LIB_TABLE::FootprintDelete().

◆ FootprintEnumerate()

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

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

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

Reimplemented from PLUGIN.

Definition at line 3157 of file eagle_plugin.cpp.

3159{
3160 wxString errorMsg;
3161
3162 init( aProperties );
3163
3164 try
3165 {
3166 cacheLib( aLibraryPath );
3167 }
3168 catch( const IO_ERROR& ioe )
3169 {
3170 errorMsg = ioe.What();
3171 }
3172
3173 // Some of the files may have been parsed correctly so we want to add the valid files to
3174 // the library.
3175
3176 for( FOOTPRINT_MAP::const_iterator it = m_templates.begin(); it != m_templates.end(); ++it )
3177 aFootprintNames.Add( it->first );
3178
3179 if( !errorMsg.IsEmpty() && !aBestEfforts )
3180 THROW_IO_ERROR( errorMsg );
3181}
void cacheLib(const wxString &aLibraryPath)
This PLUGIN only caches one footprint library, this determines which one.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30

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

◆ FootprintExists()

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

Check for the existence of a footprint.

Reimplemented in PCB_PLUGIN.

Definition at line 89 of file plugin.cpp.

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

References PLUGIN::FootprintLoad().

Referenced by FP_LIB_TABLE::FootprintExists().

◆ FootprintLibCreate()

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

Create a new empty footprint library at aLibraryPath empty.

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

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

Reimplemented in PCB_PLUGIN.

Definition at line 122 of file plugin.cpp.

123{
124 // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
125 not_implemented( this, __FUNCTION__ );
126}

References not_implemented().

Referenced by PCB_BASE_EDIT_FRAME::createNewLibrary(), and FP_LIB_TABLE::FootprintLibCreate().

◆ FootprintLibDelete()

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

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

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

Reimplemented in GPCB_PLUGIN, PCB_PLUGIN, and LEGACY_PLUGIN.

Definition at line 129 of file plugin.cpp.

130{
131 // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
132 not_implemented( this, __FUNCTION__ );
133 return false;
134}

References not_implemented().

Referenced by PCB_BASE_EDIT_FRAME::createNewLibrary(), and FP_LIB_TABLE::FootprintLibDelete().

◆ FootprintLibOptions()

void EAGLE_PLUGIN::FootprintLibOptions ( STRING_UTF8_MAP aListToAppendTo) const
overridevirtual

Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions.

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

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

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

Reimplemented from PLUGIN.

Definition at line 3202 of file eagle_plugin.cpp.

3203{
3204 PLUGIN::FootprintLibOptions( aListToAppendTo );
3205}
virtual void FootprintLibOptions(STRING_UTF8_MAP *aListToAppendTo) const
Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions.
Definition: plugin.cpp:145

References PLUGIN::FootprintLibOptions().

◆ FootprintLoad()

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

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

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

Reimplemented from PLUGIN.

Definition at line 3184 of file eagle_plugin.cpp.

3187{
3188 init( aProperties );
3189 cacheLib( aLibraryPath );
3190 FOOTPRINT_MAP::const_iterator it = m_templates.find( aFootprintName );
3191
3192 if( it == m_templates.end() )
3193 return nullptr;
3194
3195 // Return a copy of the template
3196 FOOTPRINT* copy = (FOOTPRINT*) it->second->Duplicate();
3197 copy->SetParent( nullptr );
3198 return copy;
3199}

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

◆ FootprintSave()

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

Write aFootprint to an existing library located at aLibraryPath.

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

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

Reimplemented in PCB_PLUGIN.

Definition at line 106 of file plugin.cpp.

108{
109 // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
110 not_implemented( this, __FUNCTION__ );
111}

References not_implemented().

Referenced by PCB_EDIT_FRAME::ExportFootprintsToLibrary(), FP_LIB_TABLE::FootprintSave(), PCB_EDIT_FRAME::OpenProjectFiles(), and FOOTPRINT_EDIT_FRAME::SaveLibraryAs().

◆ GetEnumeratedFootprint()

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

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

Reimplemented in GPCB_PLUGIN, and PCB_PLUGIN.

Definition at line 80 of file plugin.cpp.

83{
84 // default implementation
85 return FootprintLoad( aLibraryPath, aFootprintName, false, aProperties );
86}

References PLUGIN::FootprintLoad().

Referenced by FP_LIB_TABLE::GetEnumeratedFootprint(), and FOOTPRINT_EDIT_FRAME::SaveLibraryAs().

◆ GetFileExtension()

const wxString EAGLE_PLUGIN::GetFileExtension ( ) const
overridevirtual

Returns the file extension for the PLUGIN.

Implements PLUGIN.

Definition at line 252 of file eagle_plugin.cpp.

253{
254 return wxT( "brd" );
255}

◆ GetImportedCachedLibraryFootprints()

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

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

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

Returns
Footprints (caller owns the objects)

Reimplemented from PLUGIN.

Definition at line 409 of file eagle_plugin.cpp.

410{
411 std::vector<FOOTPRINT*> retval;
412
413 for( std::pair<wxString, FOOTPRINT*> fp : m_templates )
414 retval.push_back( static_cast<FOOTPRINT*>( fp.second->Clone() ) );
415
416 return retval;
417}

References m_templates.

◆ GetLibraryTimestamp()

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

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

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

Implements PLUGIN.

Definition at line 149 of file eagle_plugin.h.

150 {
151 return getModificationTime( aLibraryPath ).GetValue().GetValue();
152 }

References getModificationTime().

◆ getMinimumCopperLayerCount()

int EAGLE_PLUGIN::getMinimumCopperLayerCount ( ) const
private

Determines the minimum copper layer stackup count that includes all mapped layers.

Definition at line 3207 of file eagle_plugin.cpp.

3208{
3209 int minLayerCount = 2;
3210
3211 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3212
3213 for( it = m_layer_map.begin(); it != m_layer_map.end(); ++it )
3214 {
3215 PCB_LAYER_ID layerId = it->second;
3216
3217 if( IsCopperLayer( layerId ) && layerId != F_Cu && layerId != B_Cu
3218 && ( layerId + 2 ) > minLayerCount )
3219 minLayerCount = layerId + 2;
3220 }
3221
3222 // Ensure the copper layers count is a multiple of 2
3223 // Pcbnew does not like boards with odd layers count
3224 // (these boards cannot exist. they actually have a even layers count)
3225 if( ( minLayerCount % 2 ) != 0 )
3226 minLayerCount++;
3227
3228 return minLayerCount;
3229}
std::map< wxString, PCB_LAYER_ID > m_layer_map
Map of Eagle layers to KiCad layers.
Definition: eagle_plugin.h:320
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:825
@ B_Cu
Definition: layer_ids.h:95
@ F_Cu
Definition: layer_ids.h:64

References B_Cu, F_Cu, IsCopperLayer(), and m_layer_map.

Referenced by Load().

◆ getModificationTime()

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

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

Definition at line 3058 of file eagle_plugin.cpp.

3059{
3060 // File hasn't been loaded yet.
3061 if( aPath.IsEmpty() )
3062 return wxDateTime::Now();
3063
3064 wxFileName fn( aPath );
3065
3066 if( fn.IsFileReadable() )
3067 return fn.GetModificationTime();
3068 else
3069 return wxDateTime( 0.0 );
3070}

Referenced by cacheLib(), and GetLibraryTimestamp().

◆ init()

void EAGLE_PLUGIN::init ( const STRING_UTF8_MAP aProperties)
private

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

Definition at line 420 of file eagle_plugin.cpp.

421{
422 m_hole_count = 0;
423 m_min_trace = 0;
424 m_min_hole = 0;
425 m_min_via = 0;
426 m_min_annulus = 0;
427 m_xpath->clear();
428 m_pads_to_nets.clear();
429
430 m_board = nullptr;
431 m_props = aProperties;
432
433
434 delete m_rules;
435 m_rules = new ERULES();
436}
int m_hole_count
generates unique footprint names from eagle "hole"s.
Definition: eagle_plugin.h:331
int m_min_annulus
smallest via annulus we find on Load(), in BIU.
Definition: eagle_plugin.h:351
NET_MAP m_pads_to_nets
net list
Definition: eagle_plugin.h:333
int m_min_trace
smallest trace we find on Load(), in BIU.
Definition: eagle_plugin.h:348
int m_min_via
smallest via we find on Load(), in BIU.
Definition: eagle_plugin.h:350
int m_min_hole
smallest diameter hole we find on Load(), in BIU.
Definition: eagle_plugin.h:349
void clear()
Definition: eagle_parser.h:126

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

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

◆ IsFootprintLibWritable()

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

Return true if the library at aLibraryPath is writable.

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

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

Reimplemented from PLUGIN.

Definition at line 154 of file eagle_plugin.h.

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

◆ kicad_fontz()

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

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

Definition at line 278 of file eagle_plugin.cpp.

279{
280 // Eagle includes stroke thickness in the text size, KiCAD does not
281 int kz = d.ToPcbUnits();
282 return wxSize( kz - aTextThickness, kz - aTextThickness );
283}
int ToPcbUnits() const
Definition: eagle_parser.h:436

References ECOORD::ToPcbUnits().

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

◆ kicad_layer()

PCB_LAYER_ID EAGLE_PLUGIN::kicad_layer ( int  aLayer) const
private

Convert an Eagle layer to a KiCad layer.

Definition at line 2877 of file eagle_plugin.cpp.

2878{
2879 auto result = m_layer_map.find( eagle_layer_name( aEagleLayer ) );
2880 return result == m_layer_map.end() ? UNDEFINED_LAYER : result->second;
2881}
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.

References eagle_layer_name(), m_layer_map, and UNDEFINED_LAYER.

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

◆ kicad_x()

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

◆ kicad_y()

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

Convert an Eagle distance to a KiCad distance.

Definition at line 188 of file eagle_plugin.h.

188{ return -y.ToPcbUnits(); }

References ECOORD::ToPcbUnits().

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

◆ Load()

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

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

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

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

Reimplemented from PLUGIN.

Definition at line 286 of file eagle_plugin.cpp.

289{
290 LOCALE_IO toggle; // toggles on, then off, the C locale.
291 wxXmlNode* doc;
292
293 init( aProperties );
294
295 m_board = aAppendToMe ? aAppendToMe : new BOARD();
296 m_progressReporter = aProgressReporter;
297
298 // Give the filename to the board if it's new
299 if( !aAppendToMe )
300 m_board->SetFileName( aFileName );
301
302 // delete on exception, if I own m_board, according to aAppendToMe
303 unique_ptr<BOARD> deleter( aAppendToMe ? nullptr : m_board );
304
305 try
306 {
308 {
309 m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
310
312 THROW_IO_ERROR( _( "Open cancelled by user." ) );
313 }
314
315 wxFileName fn = aFileName;
316
317 // Load the document
318 wxFFileInputStream stream( fn.GetFullPath() );
319 wxXmlDocument xmlDocument;
320
321 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
322 {
323 THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'" ),
324 fn.GetFullPath() ) );
325 }
326
327 doc = xmlDocument.GetRoot();
328
329 m_min_trace = INT_MAX;
330 m_min_hole = INT_MAX;
331 m_min_via = INT_MAX;
332 m_min_annulus = INT_MAX;
333
334 loadAllSections( doc );
335
337
338 if( m_min_trace < bds.m_TrackMinWidth )
340
341 if( m_min_via < bds.m_ViasMinSize )
343
344 if( m_min_hole < bds.m_MinThroughDrill )
346
349
350 if( m_rules->mdWireWire )
352
353 NETCLASS defaults( wxT( "dummy" ) );
354
355 auto finishNetclass =
356 [&]( std::shared_ptr<NETCLASS> netclass )
357 {
358 // If Eagle has a clearance matrix then we'll build custom rules from that.
359 // Netclasses should just be the board minimum clearance.
360 netclass->SetClearance( KiROUND( bds.m_MinClearance ) );
361
362 if( netclass->GetTrackWidth() == INT_MAX )
363 netclass->SetTrackWidth( defaults.GetTrackWidth() );
364
365 if( netclass->GetViaDiameter() == INT_MAX )
366 netclass->SetViaDiameter( defaults.GetViaDiameter() );
367
368 if( netclass->GetViaDrill() == INT_MAX )
369 netclass->SetViaDrill( defaults.GetViaDrill() );
370 };
371
372 std::shared_ptr<NET_SETTINGS>& netSettings = bds.m_NetSettings;
373
374 finishNetclass( netSettings->m_DefaultNetClass );
375
376 for( const auto& [ name, netclass ] : netSettings->m_NetClasses )
377 finishNetclass( netclass );
378
381
382 fn.SetExt( wxT( "kicad_dru" ) );
383 wxFile rulesFile( fn.GetFullPath(), wxFile::write );
384 rulesFile.Write( m_customRules );
385
386 // should be empty, else missing m_xpath->pop()
387 wxASSERT( m_xpath->Contents().size() == 0 );
388 }
389 catch( const XML_PARSER_ERROR &exc )
390 {
391 wxString errmsg = exc.what();
392
393 errmsg += wxT( "\[email protected] " );
394 errmsg += m_xpath->Contents();
395
396 THROW_IO_ERROR( errmsg );
397 }
398
399 // IO_ERROR exceptions are left uncaught, they pass upwards from here.
400
402 centerBoard();
403
404 deleter.release();
405 return m_board;
406}
const char * name
Definition: DXF_plotter.cpp:56
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: board.h:342
void SetFileName(const wxString &aFileName)
Definition: board.h:300
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
Definition: board.h:346
void SetCopperLayerCount(int aCount)
Definition: board.cpp:551
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:686
void loadAllSections(wxXmlNode *aDocument)
wxString m_customRules
Definition: eagle_plugin.h:325
void centerBoard()
move the BOARD into the center of the page
int getMinimumCopperLayerCount() const
Determines the minimum copper layer stackup count that includes all mapped layers.
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:47
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
wxString Contents()
return the contents of the XPATH as a single string
Definition: eagle_parser.h:143
double mdWireWire
wire to wire spacing I presume.
Definition: eagle_plugin.h:121
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
Definition: eagle_parser.h:75
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:85

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

◆ loadAllSections()

void EAGLE_PLUGIN::loadAllSections ( wxXmlNode *  aDocument)
private

Definition at line 448 of file eagle_plugin.cpp.

449{
450 wxXmlNode* drawing = MapChildren( aDoc )["drawing"];
451 NODE_MAP drawingChildren = MapChildren( drawing );
452
453 wxXmlNode* board = drawingChildren["board"];
454 NODE_MAP boardChildren = MapChildren( board );
455
456 auto count_children = [this]( wxXmlNode* aNode )
457 {
458 if( aNode )
459 {
460 wxXmlNode* child = aNode->GetChildren();
461
462 while( child )
463 {
464 m_totalCount++;
465 child = child->GetNext();
466 }
467 }
468 };
469
470 wxXmlNode* designrules = boardChildren["designrules"];
471 wxXmlNode* layers = drawingChildren["layers"];
472 wxXmlNode* plain = boardChildren["plain"];
473 wxXmlNode* classes = boardChildren["classes"];
474 wxXmlNode* signals = boardChildren["signals"];
475 wxXmlNode* libs = boardChildren["libraries"];
476 wxXmlNode* elems = boardChildren["elements"];
477
479 {
480 m_totalCount = 0;
481 m_doneCount = 0;
482
483 count_children( designrules );
484 count_children( layers );
485 count_children( plain );
486 count_children( signals );
487 count_children( elems );
488
489 while( libs )
490 {
491 count_children( MapChildren( libs )["packages"] );
492 libs = libs->GetNext();
493 }
494
495 // Rewind
496 libs = boardChildren["libraries"];
497 }
498
499 m_xpath->push( "eagle.drawing" );
500
501 {
502 m_xpath->push( "board" );
503
504 loadDesignRules( designrules );
505
506 m_xpath->pop();
507 }
508
509 {
510 m_xpath->push( "layers" );
511
512 loadLayerDefs( layers );
514
515 m_xpath->pop();
516 }
517
518 {
519 m_xpath->push( "board" );
520
521 loadPlain( plain );
522 loadClasses( classes );
523 loadSignals( signals );
524 loadLibraries( libs );
525 loadElements( elems );
526
527 m_xpath->pop();
528 }
529
530 m_xpath->pop(); // "eagle.drawing"
531}
void loadPlain(wxXmlNode *aPlain)
void loadLibraries(wxXmlNode *aLibs)
void loadDesignRules(wxXmlNode *aDesignRules)
void loadSignals(wxXmlNode *aSignals)
void loadClasses(wxXmlNode *aClasses)
void loadElements(wxXmlNode *aElements)

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

Referenced by Load().

◆ loadClasses()

void EAGLE_PLUGIN::loadClasses ( wxXmlNode *  aClasses)
private

Definition at line 2495 of file eagle_plugin.cpp.

2496{
2498
2499 m_xpath->push( "classes.class", "number" );
2500
2501 std::vector<ECLASS> eClasses;
2502 wxXmlNode* classNode = aClasses->GetChildren();
2503
2504 while( classNode )
2505 {
2506 checkpoint();
2507
2508 ECLASS eClass( classNode );
2509 std::shared_ptr<NETCLASS> netclass;
2510
2511 if( eClass.name.CmpNoCase( wxT( "default" ) ) == 0 )
2512 {
2513 netclass = bds.m_NetSettings->m_DefaultNetClass;
2514 }
2515 else
2516 {
2517 netclass.reset( new NETCLASS( eClass.name ) );
2518 bds.m_NetSettings->m_NetClasses[ eClass.name ] = netclass;
2519 }
2520
2521 netclass->SetTrackWidth( INT_MAX );
2522 netclass->SetViaDiameter( INT_MAX );
2523 netclass->SetViaDrill( INT_MAX );
2524
2525 eClasses.emplace_back( eClass );
2526 m_classMap[ eClass.number ] = netclass;
2527
2528 // Get next class
2529 classNode = classNode->GetNext();
2530 }
2531
2532 m_customRules = wxT( "(version 1)" );
2533
2534 for( ECLASS& eClass : eClasses )
2535 {
2536 for( std::pair<const wxString&, ECOORD> entry : eClass.clearanceMap )
2537 {
2538 if( m_classMap[ entry.first ] != nullptr )
2539 {
2540 wxString rule;
2541 rule.Printf( wxT( "(rule \"class %s:%s\"\n"
2542 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2543 " (constraint clearance (min %smm)))\n" ),
2544 eClass.number,
2545 entry.first,
2546 eClass.name,
2547 m_classMap[ entry.first ]->GetName(),
2549
2550 m_customRules += wxT( "\n" ) + rule;
2551 }
2552 }
2553 }
2554
2555 m_xpath->pop(); // "classes.class"
2556}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
std::map< wxString, std::shared_ptr< NETCLASS > > m_classMap
Definition: eagle_plugin.h:323
wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Returns the string from aValue according to aUnits (inch, mm ...) for display.
Definition: eda_units.cpp:236

References checkpoint(), BOARD::GetDesignSettings(), m_board, m_classMap, m_customRules, BOARD_DESIGN_SETTINGS::m_NetSettings, m_xpath, MILLIMETRES, ECLASS::name, ECLASS::number, pcbIUScale, XPATH::pop(), XPATH::push(), and EDA_UNIT_UTILS::UI::StringFromValue().

Referenced by loadAllSections().

◆ loadDesignRules()

void EAGLE_PLUGIN::loadDesignRules ( wxXmlNode *  aDesignRules)
private

Definition at line 534 of file eagle_plugin.cpp.

535{
536 if( aDesignRules )
537 {
538 m_xpath->push( "designrules" );
539 m_rules->parse( aDesignRules, [this](){ checkpoint(); } );
540 m_xpath->pop(); // "designrules"
541 }
542}
void parse(wxXmlNode *aRules, std::function< void()> aCheckpoint)
percent over 100%.

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

Referenced by loadAllSections().

◆ loadElements()

void EAGLE_PLUGIN::loadElements ( wxXmlNode *  aElements)
private

Definition at line 1141 of file eagle_plugin.cpp.

1142{
1143 if( !aElements )
1144 return;
1145
1146 m_xpath->push( "elements.element", "name" );
1147
1148 EATTR name;
1149 EATTR value;
1150 bool refanceNamePresetInPackageLayout;
1151 bool valueNamePresetInPackageLayout;
1152
1153 // Get the first element and iterate
1154 wxXmlNode* element = aElements->GetChildren();
1155
1156 while( element )
1157 {
1158 checkpoint();
1159
1160 if( element->GetName() != wxT( "element" ) )
1161 {
1162 // Get next item
1163 element = element->GetNext();
1164 continue;
1165 }
1166
1167 EELEMENT e( element );
1168
1169 // use "NULL-ness" as an indication of presence of the attribute:
1170 EATTR* nameAttr = nullptr;
1171 EATTR* valueAttr = nullptr;
1172
1173 m_xpath->Value( e.name.c_str() );
1174
1175 wxString pkg_key = makeKey( e.library, e.package );
1176
1177 FOOTPRINT_MAP::const_iterator it = m_templates.find( pkg_key );
1178
1179 if( it == m_templates.end() )
1180 {
1181 wxString emsg = wxString::Format( _( "No '%s' package in library '%s'." ),
1182 e.package, e.library );
1183 THROW_IO_ERROR( emsg );
1184 }
1185
1186 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( it->second->Duplicate() );
1187
1188 m_board->Add( footprint, ADD_MODE::APPEND );
1189
1190 // update the nets within the pads of the clone
1191 for( PAD* pad : footprint->Pads() )
1192 {
1193 wxString pn_key = makeKey( e.name, pad->GetNumber() );
1194
1195 NET_MAP_CITER ni = m_pads_to_nets.find( pn_key );
1196 if( ni != m_pads_to_nets.end() )
1197 {
1198 const ENET* enet = &ni->second;
1199 pad->SetNetCode( enet->netcode );
1200 }
1201 }
1202
1203 refanceNamePresetInPackageLayout = true;
1204 valueNamePresetInPackageLayout = true;
1205 footprint->SetPosition( VECTOR2I( kicad_x( e.x ), kicad_y( e.y ) ) );
1206
1207 // Is >NAME field set in package layout ?
1208 if( footprint->GetReference().size() == 0 )
1209 {
1210 footprint->Reference().SetVisible( false ); // No so no show
1211 refanceNamePresetInPackageLayout = false;
1212 }
1213
1214 // Is >VALUE field set in package layout
1215 if( footprint->GetValue().size() == 0 )
1216 {
1217 footprint->Value().SetVisible( false ); // No so no show
1218 valueNamePresetInPackageLayout = false;
1219 }
1220
1221 wxString reference = e.name;
1222
1223 // EAGLE allows references to be single digits. This breaks KiCad
1224 // netlisting, which requires parts to have non-digit + digit
1225 // annotation. If the reference begins with a number, we prepend
1226 // 'UNK' (unknown) for the symbol designator.
1227 if( reference.find_first_not_of( "0123456789" ) != 0 )
1228 reference.Prepend( "UNK" );
1229
1230 // EAGLE allows designator to start with # but that is used in KiCad
1231 // for symbols which do not have a footprint
1232 if( reference.find_first_not_of( "#" ) != 0 )
1233 reference.Prepend( "UNK" );
1234
1235 // reference must end with a number but EAGLE does not enforce this
1236 if( reference.find_last_not_of( "0123456789" ) == (reference.Length()-1) )
1237 reference.Append( "0" );
1238
1239 footprint->SetReference( reference );
1240 footprint->SetValue( e.value );
1241
1242 if( !e.smashed )
1243 {
1244 // Not smashed so show NAME & VALUE
1245 if( valueNamePresetInPackageLayout )
1246 footprint->Value().SetVisible( true ); // Only if place holder in package layout
1247
1248 if( refanceNamePresetInPackageLayout )
1249 footprint->Reference().SetVisible( true ); // Only if place holder in package layout
1250 }
1251 else if( *e.smashed == true )
1252 {
1253 // Smashed so set default to no show for NAME and VALUE
1254 footprint->Value().SetVisible( false );
1255 footprint->Reference().SetVisible( false );
1256
1257 // initialize these to default values in case the <attribute> elements are not present.
1258 m_xpath->push( "attribute", "name" );
1259
1260 // VALUE and NAME can have something like our text "effects" overrides
1261 // in SWEET and new schematic. Eagle calls these XML elements "attribute".
1262 // There can be one for NAME and/or VALUE both. Features present in the
1263 // EATTR override the ones established in the package only if they are
1264 // present here (except for rot, which if not present means angle zero).
1265 // So the logic is a bit different than in packageText() and in plain text.
1266
1267 // Get the first attribute and iterate
1268 wxXmlNode* attribute = element->GetChildren();
1269
1270 while( attribute )
1271 {
1272 if( attribute->GetName() != wxT( "attribute" ) )
1273 {
1274 attribute = attribute->GetNext();
1275 continue;
1276 }
1277
1278 EATTR a( attribute );
1279
1280 if( a.name == wxT( "NAME" ) )
1281 {
1282 name = a;
1283 nameAttr = &name;
1284
1285 // do we have a display attribute ?
1286 if( a.display )
1287 {
1288 // Yes!
1289 switch( *a.display )
1290 {
1291 case EATTR::VALUE :
1292 {
1293 nameAttr->name = reference;
1294
1295 if( refanceNamePresetInPackageLayout )
1296 footprint->Reference().SetVisible( true );
1297
1298 break;
1299 }
1300
1301 case EATTR::NAME :
1302 if( refanceNamePresetInPackageLayout )
1303 {
1304 footprint->SetReference( "NAME" );
1305 footprint->Reference().SetVisible( true );
1306 }
1307
1308 break;
1309
1310 case EATTR::BOTH :
1311 if( refanceNamePresetInPackageLayout )
1312 footprint->Reference().SetVisible( true );
1313
1314 nameAttr->name = nameAttr->name + wxT( " = " ) + e.name;
1315 footprint->SetReference( wxT( "NAME = " ) + e.name );
1316 break;
1317
1318 case EATTR::Off :
1319 footprint->Reference().SetVisible( false );
1320 break;
1321
1322 default:
1323 nameAttr->name = e.name;
1324
1325 if( refanceNamePresetInPackageLayout )
1326 footprint->Reference().SetVisible( true );
1327 }
1328 }
1329 else
1330 {
1331 // No display, so default is visible, and show value of NAME
1332 footprint->Reference().SetVisible( true );
1333 }
1334 }
1335 else if( a.name == wxT( "VALUE" ) )
1336 {
1337 value = a;
1338 valueAttr = &value;
1339
1340 if( a.display )
1341 {
1342 // Yes!
1343 switch( *a.display )
1344 {
1345 case EATTR::VALUE :
1346 valueAttr->value = opt_wxString( e.value );
1347 footprint->SetValue( e.value );
1348
1349 if( valueNamePresetInPackageLayout )
1350 footprint->Value().SetVisible( true );
1351
1352 break;
1353
1354 case EATTR::NAME :
1355 if( valueNamePresetInPackageLayout )
1356 footprint->Value().SetVisible( true );
1357
1358 footprint->SetValue( wxT( "VALUE" ) );
1359 break;
1360
1361 case EATTR::BOTH :
1362 if( valueNamePresetInPackageLayout )
1363 footprint->Value().SetVisible( true );
1364
1365 valueAttr->value = opt_wxString( wxT( "VALUE = " ) + e.value );
1366 footprint->SetValue( wxT( "VALUE = " ) + e.value );
1367 break;
1368
1369 case EATTR::Off :
1370 footprint->Value().SetVisible( false );
1371 break;
1372
1373 default:
1374 valueAttr->value = opt_wxString( e.value );
1375
1376 if( valueNamePresetInPackageLayout )
1377 footprint->Value().SetVisible( true );
1378 }
1379 }
1380 else
1381 {
1382 // No display, so default is visible, and show value of NAME
1383 footprint->Value().SetVisible( true );
1384 }
1385
1386 }
1387
1388 attribute = attribute->GetNext();
1389 }
1390
1391 m_xpath->pop(); // "attribute"
1392 }
1393
1394 orientFootprintAndText( footprint, e, nameAttr, valueAttr );
1395
1396 // Set the local coordinates for the footprint text items
1397 footprint->Reference().SetLocalCoord();
1398 footprint->Value().SetLocalCoord();
1399
1400 // Get next element
1401 element = element->GetNext();
1402 }
1403
1404 m_xpath->pop(); // "elements.element"
1405}
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:754
void orientFootprintAndText(FOOTPRINT *aFootprint, const EELEMENT &e, const EATTR *aNameAttr, const EATTR *aValueAttr)
int kicad_x(const ECOORD &x) const
Definition: eagle_plugin.h:189
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
Definition: eagle_plugin.h:188
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:217
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:1671
PADS & Pads()
Definition: footprint.h:170
void SetReference(const wxString &aReference)
Definition: footprint.h:528
void SetValue(const wxString &aValue)
Definition: footprint.h:555
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:567
const wxString & GetValue() const
Definition: footprint.h:547
const wxString & GetReference() const
Definition: footprint.h:519
FP_TEXT & Reference()
Definition: footprint.h:568
void SetLocalCoord()
Definition: fp_text.cpp:220
Definition: pad.h:59
void Value(const char *aValue)
modify the last path node's value
Definition: eagle_parser.h:131
OPTIONAL_XML_ATTRIBUTE< wxString > opt_wxString
Definition: eagle_parser.h:372
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.
NET_MAP::const_iterator NET_MAP_CITER
Definition: eagle_plugin.h:46
Parse an Eagle "attribute" XML element.
Definition: eagle_parser.h:599
opt_wxString value
Definition: eagle_parser.h:601
wxString name
Definition: eagle_parser.h:600
Eagle element element.
Definition: eagle_parser.h:815
Eagle net.
Definition: eagle_parser.h:460
int netcode
Definition: eagle_parser.h:461

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

Referenced by loadAllSections().

◆ loadLayerDefs()

void EAGLE_PLUGIN::loadLayerDefs ( wxXmlNode *  aLayers)
private

Definition at line 545 of file eagle_plugin.cpp.

546{
547 if( !aLayers )
548 return;
549
550 ELAYERS cu; // copper layers
551
552 // Get the first layer and iterate
553 wxXmlNode* layerNode = aLayers->GetChildren();
554
555 m_eagleLayers.clear();
556 m_eagleLayersIds.clear();
557
558 while( layerNode )
559 {
560 ELAYER elayer( layerNode );
561 m_eagleLayers.insert( std::make_pair( elayer.number, elayer ) );
562 m_eagleLayersIds.insert( std::make_pair( elayer.name, elayer.number ) );
563
564 // find the subset of layers that are copper and active
565 if( elayer.number >= 1 && elayer.number <= 16 && ( !elayer.active || *elayer.active ) )
566 cu.push_back( elayer );
567
568 layerNode = layerNode->GetNext();
569 }
570
571 // establish cu layer map:
572 int ki_layer_count = 0;
573
574 for( EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
575 {
576 if( ki_layer_count == 0 )
577 {
578 m_cu_map[it->number] = F_Cu;
579 }
580 else if( ki_layer_count == int( cu.size()-1 ) )
581 {
582 m_cu_map[it->number] = B_Cu;
583 }
584 else
585 {
586 // some eagle boards do not have contiguous layer number sequences.
587 m_cu_map[it->number] = ki_layer_count;
588 }
589 }
590
591 // Set the layer names and cu count if we're loading a board.
592 if( m_board )
593 {
594 m_board->SetCopperLayerCount( cu.size() );
595
596 for( EITER it = cu.begin(); it != cu.end(); ++it )
597 {
598 PCB_LAYER_ID layer = kicad_layer( it->number );
599
600 // these function provide their own protection against non enabled layers:
601 if( layer >= 0 && layer < PCB_LAYER_ID_COUNT ) // layer should be valid
602 {
603 m_board->SetLayerName( layer, it->name );
604 m_board->SetLayerType( layer, LT_SIGNAL );
605 }
606
607 // could map the colors here
608 }
609 }
610}
@ LT_SIGNAL
Definition: board.h:145
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition: board.cpp:472
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
Definition: board.cpp:502
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
std::vector< ELAYER > ELAYERS
Definition: eagle_plugin.h:314
ELAYERS::const_iterator EITER
Definition: eagle_plugin.h:315
@ PCB_LAYER_ID_COUNT
Definition: layer_ids.h:137

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

Referenced by cacheLib(), and loadAllSections().

◆ loadLibraries()

void EAGLE_PLUGIN::loadLibraries ( wxXmlNode *  aLibs)
private

Definition at line 1118 of file eagle_plugin.cpp.

1119{
1120 if( !aLibs )
1121 return;
1122
1123 m_xpath->push( "libraries.library", "name" );
1124
1125 // Get the first library and iterate
1126 wxXmlNode* library = aLibs->GetChildren();
1127
1128 while( library )
1129 {
1130 const wxString& lib_name = library->GetAttribute( "name" );
1131
1132 m_xpath->Value( lib_name.c_str() );
1133 loadLibrary( library, &lib_name );
1134 library = library->GetNext();
1135 }
1136
1137 m_xpath->pop();
1138}

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

Referenced by loadAllSections().

◆ loadLibrary()

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

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

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

Definition at line 1060 of file eagle_plugin.cpp.

1061{
1062 if( !aLib )
1063 return;
1064
1065 // library will have <xmlattr> node, skip that and get the single packages node
1066 wxXmlNode* packages = MapChildren( aLib )["packages"];
1067
1068 if( !packages )
1069 return;
1070
1071 m_xpath->push( "packages" );
1072
1073 // Create a FOOTPRINT for all the eagle packages, for use later via a copy constructor
1074 // to instantiate needed footprints in our BOARD. Save the FOOTPRINT templates in
1075 // a FOOTPRINT_MAP using a single lookup key consisting of libname+pkgname.
1076
1077 // Get the first package and iterate
1078 wxXmlNode* package = packages->GetChildren();
1079
1080 while( package )
1081 {
1082 checkpoint();
1083
1084 m_xpath->push( "package", "name" );
1085
1086 wxString pack_ref = package->GetAttribute( "name" );
1087 ReplaceIllegalFileNameChars( pack_ref, '_' );
1088
1089 m_xpath->Value( pack_ref.ToUTF8() );
1090
1091 wxString key = aLibName ? makeKey( *aLibName, pack_ref ) : pack_ref;
1092
1093 FOOTPRINT* footprint = makeFootprint( package, pack_ref );
1094
1095 // add the templating FOOTPRINT to the FOOTPRINT template factory "m_templates"
1096 std::pair<FOOTPRINT_MAP::iterator, bool> r = m_templates.insert( { key, footprint} );
1097
1098 if( !r.second /* && !( m_props && m_props->Value( "ignore_duplicates" ) ) */ )
1099 {
1100 wxString lib = aLibName ? *aLibName : m_lib_path;
1101 const wxString& pkg = pack_ref;
1102
1103 wxString emsg = wxString::Format( _( "<package> '%s' duplicated in <library> '%s'" ),
1104 pkg,
1105 lib );
1106 THROW_IO_ERROR( emsg );
1107 }
1108
1109 m_xpath->pop();
1110
1111 package = package->GetNext();
1112 }
1113
1114 m_xpath->pop(); // "packages"
1115}
FOOTPRINT * makeFootprint(wxXmlNode *aPackage, const wxString &aPkgName)
Create a FOOTPRINT from an Eagle package.
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.

References _, checkpoint(), Format(), m_lib_path, m_templates, m_xpath, makeFootprint(), makeKey(), 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 616 of file eagle_plugin.cpp.

617{
618 if( !aGraphics )
619 return;
620
621 m_xpath->push( "plain" );
622
623 // Get the first graphic and iterate
624 wxXmlNode* gr = aGraphics->GetChildren();
625
626 // (polygon | wire | text | circle | rectangle | frame | hole)*
627 while( gr )
628 {
629 checkpoint();
630
631 wxString grName = gr->GetName();
632
633 if( grName == wxT( "wire" ) )
634 {
635 m_xpath->push( "wire" );
636
637 EWIRE w( gr );
638 PCB_LAYER_ID layer = kicad_layer( w.layer );
639
640 VECTOR2I start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
641 VECTOR2I end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
642
643 if( layer != UNDEFINED_LAYER )
644 {
645 PCB_SHAPE* shape = new PCB_SHAPE( m_board );
646 int width = w.width.ToPcbUnits();
647
648 // KiCad cannot handle zero or negative line widths
649 if( width <= 0 )
650 width = m_board->GetDesignSettings().GetLineThickness( layer );
651
652 m_board->Add( shape, ADD_MODE::APPEND );
653
654 if( !w.curve )
655 {
656 shape->SetShape( SHAPE_T::SEGMENT );
657 shape->SetStart( start );
658 shape->SetEnd( end );
659 }
660 else
661 {
662 VECTOR2I center = ConvertArcCenter( start, end, *w.curve );
663
664 shape->SetShape( SHAPE_T::ARC );
665 shape->SetCenter( center );
666 shape->SetStart( start );
667 shape->SetArcAngleAndEnd( -EDA_ANGLE( *w.curve, DEGREES_T ), true ); // KiCad rotates the other way
668 }
669
670 shape->SetLayer( layer );
672 }
673
674 m_xpath->pop();
675 }
676 else if( grName == wxT( "text" ) )
677 {
678 m_xpath->push( "text" );
679
680 ETEXT t( gr );
681 PCB_LAYER_ID layer = kicad_layer( t.layer );
682
683 if( layer != UNDEFINED_LAYER )
684 {
685 PCB_TEXT* pcbtxt = new PCB_TEXT( m_board );
686 m_board->Add( pcbtxt, ADD_MODE::APPEND );
687
688 pcbtxt->SetLayer( layer );
689 wxString kicadText = interpretText( t.text );
690 pcbtxt->SetText( kicadText );
691 pcbtxt->SetTextPos( VECTOR2I( kicad_x( t.x ), kicad_y( t.y ) ) );
692
693 double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
694 int textThickness = KiROUND( t.size.ToPcbUnits() * ratio / 100 );
695 pcbtxt->SetTextThickness( textThickness );
696 pcbtxt->SetTextSize( kicad_fontz( t.size, textThickness ) );
697
698 int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;
699
700 if( t.rot )
701 {
702 int sign = t.rot->mirror ? -1 : 1;
703 pcbtxt->SetMirrored( t.rot->mirror );
704
705 double degrees = t.rot->degrees;
706
707 if( degrees == 90 || t.rot->spin )
708 {
709 pcbtxt->SetTextAngle( EDA_ANGLE( sign * t.rot->degrees, DEGREES_T ) );
710 }
711 else if( degrees == 180 )
712 {
713 align = -align;
714 }
715 else if( degrees == 270 )
716 {
717 pcbtxt->SetTextAngle( EDA_ANGLE( sign * 90, DEGREES_T ) );
718 align = -align;
719 }
720 else
721 {
722 // Ok so text is not at 90,180 or 270 so do some funny stuff to get
723 // placement right.
724 if( ( degrees > 0 ) && ( degrees < 90 ) )
725 {
726 pcbtxt->SetTextAngle( EDA_ANGLE( sign * t.rot->degrees, DEGREES_T ) );
727 }
728 else if( ( degrees > 90 ) && ( degrees < 180 ) )
729 {
730 pcbtxt->SetTextAngle( EDA_ANGLE( sign * ( t.rot->degrees + 180 ), DEGREES_T ) );
731 align = ETEXT::TOP_RIGHT;
732 }
733 else if( ( degrees > 180 ) && ( degrees < 270 ) )
734 {
735 pcbtxt->SetTextAngle( EDA_ANGLE( sign * ( t.rot->degrees - 180 ), DEGREES_T ) );
736 align = ETEXT::TOP_RIGHT;
737 }
738 else if( ( degrees > 270 ) && ( degrees < 360 ) )
739 {
740 pcbtxt->SetTextAngle( EDA_ANGLE( sign * t.rot->degrees, DEGREES_T ) );
741 align = ETEXT::BOTTOM_LEFT;
742 }
743 }
744 }
745
746 switch( align )
747 {
748 case ETEXT::CENTER:
751 break;
752
756 break;
757
761 break;
762
766 break;
767
768 case ETEXT::TOP_LEFT:
771 break;
772
773 case ETEXT::TOP_RIGHT:
776 break;
777
781 break;
782
786 break;
787
791 break;
792 }
793 }
794
795 m_xpath->pop();
796 }
797 else if( grName == wxT( "circle" ) )
798 {
799 m_xpath->push( "circle" );
800
801 ECIRCLE c( gr );
802
803 int width = c.width.ToPcbUnits();
804 int radius = c.radius.ToPcbUnits();
805
806 if( c.layer == EAGLE_LAYER::TRESTRICT || c.layer == EAGLE_LAYER::BRESTRICT
807 || c.layer == EAGLE_LAYER::VRESTRICT )
808 {
809 ZONE* zone = new ZONE( m_board );
810 m_board->Add( zone, ADD_MODE::APPEND );
811
812 setKeepoutSettingsToZone( zone, c.layer );
813
814 // approximate circle as polygon
815 VECTOR2I center( kicad_x( c.x ), kicad_y( c.y ) );
816 int outlineRadius = radius + ( width / 2 );
817 int segsInCircle = GetArcToSegmentCount( outlineRadius, ARC_HIGH_DEF, FULL_CIRCLE );
818 EDA_ANGLE delta = ANGLE_360 / segsInCircle;
819
821 {
822 VECTOR2I rotatedPoint( outlineRadius, 0 );
823 RotatePoint( rotatedPoint, angle );
824 zone->AppendCorner( center + rotatedPoint, -1 );
825 }
826
827 if( width > 0 )
828 {
829 zone->NewHole();
830 int innerRadius = radius - ( width / 2 );
831 segsInCircle = GetArcToSegmentCount( innerRadius, ARC_HIGH_DEF, FULL_CIRCLE );
832 delta = ANGLE_360 / segsInCircle;
833
835 {
836 VECTOR2I rotatedPoint( innerRadius, 0 );
837 RotatePoint( rotatedPoint, angle );
838 zone->AppendCorner( center + rotatedPoint, 0 );
839 }
840 }
841
844 }
845 else
846 {
847 PCB_LAYER_ID layer = kicad_layer( c.layer );
848
849 if( layer != UNDEFINED_LAYER ) // unsupported layer
850 {
852 m_board->Add( shape, ADD_MODE::APPEND );
853 shape->SetFilled( false );
854 shape->SetLayer( layer );
855 shape->SetStart( VECTOR2I( kicad_x( c.x ), kicad_y( c.y ) ) );
856 shape->SetEnd( VECTOR2I( kicad_x( c.x ) + radius, kicad_y( c.y ) ) );
858 }
859 }
860
861 m_xpath->pop();
862 }
863 else if( grName == wxT( "rectangle" ) )
864 {
865 // This seems to be a simplified rectangular [copper] zone, cannot find any
866 // net related info on it from the DTD.
867 m_xpath->push( "rectangle" );
868
869 ERECT r( gr );
870 PCB_LAYER_ID layer = kicad_layer( r.layer );
871
872 if( IsCopperLayer( layer ) )
873 {
874 // use a "netcode = 0" type ZONE:
875 ZONE* zone = new ZONE( m_board );
876 m_board->Add( zone, ADD_MODE::APPEND );
877
878 zone->SetLayer( layer );
880
882
883 const int outlineIdx = -1; // this is the id of the copper zone main outline
884 zone->AppendCorner( VECTOR2I( kicad_x( r.x1 ), kicad_y( r.y1 ) ), outlineIdx );
885 zone->AppendCorner( VECTOR2I( kicad_x( r.x2 ), kicad_y( r.y1 ) ), outlineIdx );
886 zone->AppendCorner( VECTOR2I( kicad_x( r.x2 ), kicad_y( r.y2 ) ), outlineIdx );
887 zone->AppendCorner( VECTOR2I( kicad_x( r.x1 ), kicad_y( r.y2 ) ), outlineIdx );
888
889 if( r.rot )
890 zone->Rotate( zone->GetPosition(), EDA_ANGLE( r.rot->degrees, DEGREES_T ) );
891
892 // this is not my fault:
894 true );
895 }
896
897 m_xpath->pop();
898 }
899 else if( grName == wxT( "hole" ) )
900 {
901 m_xpath->push( "hole" );
902
903 // Fabricate a FOOTPRINT with a single PAD_ATTRIB::NPTH pad.
904 // Use m_hole_count to gen up a unique name.
905
906 FOOTPRINT* footprint = new FOOTPRINT( m_board );
907 m_board->Add( footprint, ADD_MODE::APPEND );
908 footprint->SetReference( wxString::Format( wxT( "@HOLE%d" ), m_hole_count++ ) );
909 footprint->Reference().SetVisible( false );
910
911 packageHole( footprint, gr, true );
912
913 m_xpath->pop();
914 }
915 else if( grName == wxT( "frame" ) )
916 {
917 // picture this
918 }
919 else if( grName == wxT( "polygon" ) )
920 {
921 m_xpath->push( "polygon" );
922 loadPolygon( gr );
923 m_xpath->pop(); // "polygon"
924 }
925 else if( grName == wxT( "dimension" ) )
926 {
927 const BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
928
929 EDIMENSION d( gr );
930 PCB_LAYER_ID layer = kicad_layer( d.layer );
931 VECTOR2I pt1( kicad_x( d.x1 ), kicad_y( d.y1 ) );
932 VECTOR2I pt2( kicad_x( d.x2 ), kicad_y( d.y2 ) );
933 VECTOR2I pt3( kicad_x( d.x3 ), kicad_y( d.y3 ) );
934 wxSize textSize = designSettings.GetTextSize( layer );
935 int textThickness = designSettings.GetLineThickness( layer );
936
937 if( d.textsize )
938 {
939 double ratio = 8; // DTD says 8 is default
940 textThickness = KiROUND( d.textsize->ToPcbUnits() * ratio / 100 );
941 textSize = kicad_fontz( *d.textsize, textThickness );
942 }
943
944 if( layer != UNDEFINED_LAYER )
945 {
946 if( d.dimensionType == wxT( "angle" ) )
947 {
948 // Kicad doesn't (at present) support angle dimensions
949 }
950 else if( d.dimensionType == wxT( "radius" ) )
951 {
952 PCB_DIM_RADIAL* dimension = new PCB_DIM_RADIAL( m_board );
953 m_board->Add( dimension, ADD_MODE::APPEND );
954
955 dimension->SetLayer( layer );
956 dimension->SetPrecision( DIMENSION_PRECISION );
957
958 dimension->SetStart( pt1 );
959 dimension->SetEnd( pt2 );
960 dimension->Text().SetPosition( pt3 );
961 dimension->Text().SetTextSize( textSize );
962 dimension->Text().SetTextThickness( textThickness );
963 dimension->SetLineThickness( designSettings.GetLineThickness( layer ) );
964 dimension->SetUnits( EDA_UNITS::MILLIMETRES );
965 }
966 else if( d.dimensionType == wxT( "leader" ) )
967 {
968 PCB_DIM_LEADER* leader = new PCB_DIM_LEADER( m_board );
969 m_board->Add( leader, ADD_MODE::APPEND );
970
971 leader->SetLayer( layer );
973
974 leader->SetStart( pt1 );
975 leader->SetEnd( pt2 );
976 leader->Text().SetPosition( pt3 );
977 leader->Text().SetTextSize( textSize );
978 leader->Text().SetTextThickness( textThickness );
979 leader->SetText( wxEmptyString );
980 leader->SetLineThickness( designSettings.GetLineThickness( layer ) );
981 }
982 else // horizontal, vertical, <default>, diameter
983 {
985 m_board->Add( dimension, ADD_MODE::APPEND );
986
987 if( d.dimensionType )
988 {
989 // Eagle dimension graphic arms may have different lengths, but they look
990 // incorrect in KiCad (the graphic is tilted). Make them even length in
991 // such case.
992 if( *d.dimensionType == wxT( "horizontal" ) )
993 {
994 int newY = ( pt1.y + pt2.y ) / 2;
995 pt1.y = newY;
996 pt2.y = newY;
997 }
998 else if( *d.dimensionType == wxT( "vertical" ) )
999 {
1000 int newX = ( pt1.x + pt2.x ) / 2;
1001 pt1.x = newX;
1002 pt2.x = newX;
1003 }
1004 }
1005
1006 dimension->SetLayer( layer );
1007 dimension->SetPrecision( DIMENSION_PRECISION );
1008
1009 // The origin and end are assumed to always be in this order from eagle
1010 dimension->SetStart( pt1 );
1011 dimension->SetEnd( pt2 );
1012 dimension->Text().SetTextSize( textSize );
1013 dimension->Text().SetTextThickness( textThickness );
1014 dimension->SetLineThickness( designSettings.GetLineThickness( layer ) );
1015 dimension->SetUnits( EDA_UNITS::MILLIMETRES );
1016
1017 // check which axis the dimension runs in
1018 // because the "height" of the dimension is perpendicular to that axis
1019 // Note the check is just if two axes are close enough to each other
1020 // Eagle appears to have some rounding errors
1021 if( abs( pt1.x - pt2.x ) < 50000 ) // 50000 nm = 0.05 mm
1022 {
1023 int offset = pt3.x - pt1.x;
1024
1025 if( pt1.y > pt2.y )
1026 dimension->SetHeight( offset );
1027 else
1028 dimension->SetHeight( -offset );
1029 }
1030 else if( abs( pt1.y - pt2.y ) < 50000 )
1031 {
1032 int offset = pt3.y - pt1.y;
1033
1034 if( pt1.x > pt2.x )
1035 dimension->SetHeight( -offset );
1036 else
1037 dimension->SetHeight( offset );
1038 }
1039 else
1040 {
1041 int offset = GetLineLength( pt3, pt1 );
1042
1043 if( pt1.y > pt2.y )
1044 dimension->SetHeight( offset );
1045 else
1046 dimension->SetHeight( -offset );
1047 }
1048 }
1049 }
1050 }
1051
1052 // Get next graphic
1053 gr = gr->GetNext();
1054 }
1055
1056 m_xpath->pop();
1057}
constexpr int ARC_HIGH_DEF
Definition: base_units.h:121
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:214
void setKeepoutSettingsToZone(ZONE *aZone, int aLayer) const
wxSize kicad_fontz(const ECOORD &d, int aTextThickness) const
create a font size (fontz) from an eagle font size scalar and KiCad font thickness
void packageHole(FOOTPRINT *aFootprint, wxXmlNode *aTree, bool aCenter) const
ZONE * loadPolygon(wxXmlNode *aPolyNode)
Load a copper or keepout polygon and adds it to the board.
void SetCenter(const VECTOR2I &aCenter)
Definition: eda_shape.cpp:470
void SetFilled(bool aFlag)
Definition: eda_shape.h:95
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:124
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:112
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:149
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
Definition: eda_shape.cpp:596
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:371
void SetMirrored(bool isMirrored)
Definition: eda_text.cpp:224
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:248
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:185
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:163
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:193
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:240
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:382
void SetPrecision(int aPrecision)
void SetUnits(EDA_UNITS aUnits)
PCB_TEXT & Text()
void SetText(const wxString &aNewText)
Set the override text - has no effect if m_overrideValue == false.
void SetLineThickness(int aWidth)
virtual void SetEnd(const VECTOR2I &aPoint)
virtual void SetStart(const VECTOR2I &aPoint)
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
For better understanding of the points that make a dimension:
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
A leader is a dimension-like object pointing to a specific point.
A radial dimension indicates either the radius or diameter of an arc or circle.
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:72
virtual void SetPosition(const VECTOR2I &aPos) override
Definition: pcb_text.h:81
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderdHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:820
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:260
void NewHole()
Create a new hole on the zone; i.e., a new contour on the zone's outline.
Definition: zone.h:564
void Rotate(const VECTOR2I &aCentre, const EDA_ANGLE &aAngle) override
Rotate the outlines.
Definition: zone.cpp:684
VECTOR2I GetPosition() const override
Definition: zone.cpp:233
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition: zone.cpp:760
static int GetDefaultHatchPitch()
Definition: zone.cpp:985
wxString interpretText(const wxString &aText)
Translates Eagle special text reference to a KiCad variable reference.
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
#define DIMENSION_PRECISION
@ DEGREES_T
Definition: eda_angle.h:31
static constexpr EDA_ANGLE & ANGLE_360
Definition: eda_angle.h:429
static constexpr EDA_ANGLE & FULL_CIRCLE
Definition: eda_angle.h:421
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:423
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:412
Eagle circle.
Definition: eagle_parser.h:567
Eagle dimension element.
Definition: eagle_parser.h:625
Eagle XML rectangle in binary.
Definition: eagle_parser.h:580
Eagle text element.
Definition: eagle_parser.h:642
@ BOTTOM_CENTER
Definition: eagle_parser.h:661
@ BOTTOM_RIGHT
Definition: eagle_parser.h:663
@ TOP_CENTER
Definition: eagle_parser.h:655
@ TOP_LEFT
Definition: eagle_parser.h:656
@ TOP_RIGHT
Definition: eagle_parser.h:657
@ CENTER_RIGHT
Definition: eagle_parser.h:660
@ CENTER_LEFT
Definition: eagle_parser.h:654
@ BOTTOM_LEFT
Definition: eagle_parser.h:662
Eagle wire.
Definition: eagle_parser.h:498
constexpr int delta
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
double GetLineLength(const VECTOR2I &aPointA, const VECTOR2I &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:188
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:106
int sign(T val)
Definition: util.h:124
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
Definition: zone_settings.h:49

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

Referenced by loadAllSections().

◆ loadPolygon()

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

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

Returns
The loaded zone or nullptr if was not processed.

Definition at line 1408 of file eagle_plugin.cpp.

1409{
1410 EPOLYGON p( aPolyNode );
1411 PCB_LAYER_ID layer = kicad_layer( p.layer );
1412 ZONE* zone = nullptr;
1413 bool keepout = ( p.layer == EAGLE_LAYER::TRESTRICT
1414 || p.layer == EAGLE_LAYER::BRESTRICT
1415 || p.layer == EAGLE_LAYER::VRESTRICT );
1416
1417 if( layer == UNDEFINED_LAYER )
1418 {
1419 wxLogMessage( wxString::Format( _( "Ignoring a polygon since Eagle layer '%s' (%d) "
1420 "was not mapped" ),
1421 eagle_layer_name( p.layer ), p.layer ) );
1422 return nullptr;
1423 }
1424
1425 if( !IsCopperLayer( layer ) && !keepout )
1426 return nullptr;
1427
1428 // use a "netcode = 0" type ZONE:
1429 zone = new ZONE( m_board );
1430 m_board->Add( zone, ADD_MODE::APPEND );
1431
1432 if( !keepout )
1433 zone->SetLayer( layer );
1434 else
1435 setKeepoutSettingsToZone( zone, p.layer );
1436
1437 // Get the first vertex and iterate
1438 wxXmlNode* vertex = aPolyNode->GetChildren();
1439 std::vector<EVERTEX> vertices;
1440
1441 // Create a circular vector of vertices
1442 // The "curve" parameter indicates a curve from the current
1443 // to the next vertex, so we keep the first at the end as well
1444 // to allow the curve to link back
1445 while( vertex )
1446 {
1447 if( vertex->GetName() == wxT( "vertex" ) )
1448 vertices.emplace_back( vertex );
1449
1450 vertex = vertex->GetNext();
1451 }
1452
1453 // According to Eagle's doc, by default, the orphans (islands in KiCad parlance)
1454 // are always removed
1455 if( !p.orphans || !p.orphans.Get() )
1457 else
1459
1460 vertices.push_back( vertices[0] );
1461
1462 SHAPE_POLY_SET polygon;
1463 polygon.NewOutline();
1464
1465 for( size_t i = 0; i < vertices.size() - 1; i++ )
1466 {
1467 EVERTEX v1 = vertices[i];
1468
1469 // Append the corner
1470 polygon.Append( kicad_x( v1.x ), kicad_y( v1.y ) );
1471
1472 if( v1.curve )
1473 {
1474 EVERTEX v2 = vertices[i + 1];
1475 VECTOR2I center =
1477 VECTOR2I( kicad_x( v2.x ), kicad_y( v2.y ) ), *v1.curve );
1478 double angle = DEG2RAD( *v1.curve );
1479 double end_angle = atan2( kicad_y( v2.y ) - center.y, kicad_x( v2.x ) - center.x );
1480 double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
1481 + pow( center.y - kicad_y( v1.y ), 2 ) );
1482
1483 int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
1484 EDA_ANGLE( *v1.curve, DEGREES_T ) );
1485 double delta_angle = angle / segCount;
1486
1487 for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle );
1488 a -= delta_angle )
1489 {
1490 polygon.Append( KiROUND( radius * cos( a ) ) + center.x,
1491 KiROUND( radius * sin( a ) ) + center.y );
1492 }
1493 }
1494 }
1495
1496 // Eagle traces the zone such that half of the pen width is outside the polygon.
1497 // We trace the zone such that the copper is completely inside.
1498 if( p.width.ToPcbUnits() > 0 )
1499 {
1500 polygon.Inflate( p.width.ToPcbUnits() / 2, 32, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
1502 }
1503
1504 zone->AddPolygon( polygon.COutline( 0 ) );
1505
1506 // If the pour is a cutout it needs to be set to a keepout
1507 if( p.pour == EPOLYGON::CUTOUT )
1508 {
1509 zone->SetIsRuleArea( true );
1510 zone->SetDoNotAllowVias( false );
1511 zone->SetDoNotAllowTracks( false );
1512 zone->SetDoNotAllowPads( false );
1513 zone->SetDoNotAllowFootprints( false );
1514 zone->SetDoNotAllowCopperPour( true );
1516 }
1517 else if( p.pour == EPOLYGON::HATCH )
1518 {
1519 int spacing = p.spacing ? p.spacing->ToPcbUnits() : 50 * pcbIUScale.IU_PER_MILS;
1520
1522 zone->SetHatchThickness( p.width.ToPcbUnits() );
1523 zone->SetHatchGap( spacing - p.width.ToPcbUnits() );
1525 }
1526
1527 // We divide the thickness by half because we are tracing _inside_ the zone outline
1528 // This means the radius of curvature will be twice the size for an equivalent EAGLE zone
1530 p.width.ToPcbUnits() / 2 ) );
1531
1532 if( p.isolate )
1533 zone->SetLocalClearance( p.isolate->ToPcbUnits() );
1534 else
1535 zone->SetLocalClearance( 1 ); // @todo: set minimum clearance value based on board settings
1536
1537 // missing == yes per DTD.
1538 bool thermals = !p.thermals || *p.thermals;
1540
1541 if( thermals )
1542 {
1543 // FIXME: eagle calculates dimensions for thermal spokes
1544 // based on what the zone is connecting to.
1545 // (i.e. width of spoke is half of the smaller side of an smd pad)
1546 // This is a basic workaround
1547 zone->SetThermalReliefGap( p.width.ToPcbUnits() + 50000 ); // 50000nm == 0.05mm
1548 zone->SetThermalReliefSpokeWidth( p.width.ToPcbUnits() + 50000 );
1549 }
1550
1551 int rank = p.rank ? (p.max_priority - *p.rank) : p.max_priority;
1552 zone->SetAssignedPriority( rank );
1553
1554 return zone;
1555}
Represent a set of closed polygons.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
@ ALLOW_ACUTE_CORNERS
just inflate the polygon. Acute angles create spikes
void Inflate(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
int NewOutline()
Creates a new hole in a given outline.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
T y
Definition: vector3.h:62
T x
Definition: vector3.h:61
void SetHatchThickness(int aThickness)
Definition: zone.h:261
void SetDoNotAllowPads(bool aEnable)
Definition: zone.h:708
void AddPolygon(std::vector< VECTOR2I > &aPolygon)
Add a polygon to the zone outline.
Definition: zone.cpp:743
void SetMinThickness(int aMinThickness)
Definition: zone.h:252
void SetHatchOrientation(const EDA_ANGLE &aStep)
Definition: zone.h:267
void SetDoNotAllowCopperPour(bool aEnable)
Definition: zone.h:705
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
Definition: zone.h:187
void SetHatchStyle(ZONE_BORDER_DISPLAY_STYLE aStyle)
Definition: zone.h:581
void SetIsRuleArea(bool aEnable)
Definition: zone.h:704
void SetDoNotAllowTracks(bool aEnable)
Definition: zone.h:707
void SetFillMode(ZONE_FILL_MODE aFillMode)
Definition: zone.h:173
void SetDoNotAllowVias(bool aEnable)
Definition: zone.h:706
void SetLocalClearance(int aClearance)
Definition: zone.h:153
void SetThermalReliefGap(int aThermalReliefGap)
Definition: zone.h:176
void SetDoNotAllowFootprints(bool aEnable)
Definition: zone.h:709
void SetAssignedPriority(unsigned aPriority)
Definition: zone.h:107
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition: zone.h:249
void SetIslandRemovalMode(ISLAND_REMOVAL_MODE aRemove)
Definition: zone.h:712
void SetHatchGap(int aStep)
Definition: zone.h:264
const double IU_PER_MILS
Definition: base_units.h:78
Eagle polygon, without vertices which are parsed as needed.
Definition: eagle_parser.h:775
Eagle vertex.
Definition: eagle_parser.h:764
VECTOR3I v1(5, 5, 5)
VECTOR2I v2(1, 0)
Test suite for KiCad math code.
double DEG2RAD(double deg)
Definition: trigo.h:195
#define ZONE_THICKNESS_MIN_VALUE_MIL
Definition: zones.h:36
@ THERMAL
Use thermal relief for pads.
@ FULL
pads are covered by copper

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

Referenced by loadPlain(), and loadSignals().

◆ loadSignals()

void EAGLE_PLUGIN::loadSignals ( wxXmlNode *  aSignals)
private

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

Definition at line 2559 of file eagle_plugin.cpp.

2560{
2561 ZONES zones; // per net
2562 int netCode = 1;
2563
2564 m_xpath->push( "signals.signal", "name" );
2565
2566 // Get the first signal and iterate
2567 wxXmlNode* net = aSignals->GetChildren();
2568
2569 while( net )
2570 {
2571 checkpoint();
2572
2573 bool sawPad = false;
2574
2575 zones.clear();
2576
2577 const wxString& netName = escapeName( net->GetAttribute( "name" ) );
2578 NETINFO_ITEM* netInfo = new NETINFO_ITEM( m_board, netName, netCode );
2579 std::shared_ptr<NETCLASS> netclass;
2580
2581 if( net->HasAttribute( "class" ) )
2582 {
2583 netclass = m_classMap[ net->GetAttribute( "class" ) ];
2584
2585 m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back(
2586 {
2587 std::make_unique<EDA_COMBINED_MATCHER>( netName, CTX_NETCLASS ),
2588 netclass->GetName()
2589 } );
2590
2591 netInfo->SetNetClass( netclass );
2592 }
2593
2594 m_board->Add( netInfo );
2595
2596 m_xpath->Value( netName.c_str() );
2597
2598 // Get the first net item and iterate
2599 wxXmlNode* netItem = net->GetChildren();
2600
2601 // (contactref | polygon | wire | via)*
2602 while( netItem )
2603 {
2604 const wxString& itemName = netItem->GetName();
2605
2606 if( itemName == wxT( "wire" ) )
2607 {
2608 m_xpath->push( "wire" );
2609
2610 EWIRE w( netItem );
2611 PCB_LAYER_ID layer = kicad_layer( w.layer );
2612
2613 if( IsCopperLayer( layer ) )
2614 {
2615 VECTOR2I start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
2616 double angle = 0.0;
2617 double end_angle = 0.0;
2618 double radius = 0.0;
2619 double delta_angle = 0.0;
2620 VECTOR2I center;
2621
2622 int width = w.width.ToPcbUnits();
2623
2624 if( width < m_min_trace )
2625 m_min_trace = width;
2626
2627 if( netclass && width < netclass->GetTrackWidth() )
2628 netclass->SetTrackWidth( width );
2629
2630 if( w.curve )
2631 {
2632 center = ConvertArcCenter( VECTOR2I( kicad_x( w.x1 ), kicad_y( w.y1 ) ),
2633 VECTOR2I( kicad_x( w.x2 ), kicad_y( w.y2 ) ),
2634 *w.curve );
2635
2636 angle = DEG2RAD( *w.curve );
2637
2638 end_angle = atan2( kicad_y( w.y2 ) - center.y,
2639 kicad_x( w.x2 ) - center.x );
2640
2641 radius = sqrt( pow( center.x - kicad_x( w.x1 ), 2 ) +
2642 pow( center.y - kicad_y( w.y1 ), 2 ) );
2643
2644 int segs = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
2645 EDA_ANGLE( *w.curve, DEGREES_T ) );
2646 delta_angle = angle / segs;
2647 }
2648
2649 while( fabs( angle ) > fabs( delta_angle ) )
2650 {
2651 wxASSERT( radius > 0.0 );
2652 VECTOR2I end( KiROUND( radius * cos( end_angle + angle ) + center.x ),
2653 KiROUND( radius * sin( end_angle + angle ) + center.y ) );
2654
2655 PCB_TRACK* t = new PCB_TRACK( m_board );
2656
2657 t->SetPosition( start );
2658 t->SetEnd( end );
2659 t->SetWidth( width );
2660 t->SetLayer( layer );
2661 t->SetNetCode( netCode );
2662
2663 m_board->Add( t );
2664
2665 start = end;
2666 angle -= delta_angle;
2667 }
2668
2669 PCB_TRACK* t = new PCB_TRACK( m_board );
2670
2671 t->SetPosition( start );
2672 t->SetEnd( VECTOR2I( kicad_x( w.x2 ), kicad_y( w.y2 ) ) );
2673 t->SetWidth( width );
2674 t->SetLayer( layer );
2675 t->SetNetCode( netCode );
2676
2677 m_board->Add( t );
2678 }
2679 else
2680 {
2681 // put non copper wires where the sun don't shine.
2682 }
2683
2684 m_xpath->pop();
2685 }
2686 else if( itemName == wxT( "via" ) )
2687 {
2688 m_xpath->push( "via" );
2689 EVIA v( netItem );
2690
2691 if( v.layer_front_most > v.layer_back_most )
2692 std::swap( v.layer_front_most, v.layer_back_most );
2693
2694 PCB_LAYER_ID layer_front_most = kicad_layer( v.layer_front_most );
2695 PCB_LAYER_ID layer_back_most = kicad_layer( v.layer_back_most );
2696
2697 if( IsCopperLayer( layer_front_most ) && IsCopperLayer( layer_back_most )
2698 && layer_front_most != layer_back_most )
2699 {
2700 int kidiam;
2701 int drillz = v.drill.ToPcbUnits();
2702 PCB_VIA* via = new PCB_VIA( m_board );
2703 m_board->Add( via );
2704
2705 if( v.diam )
2706 {
2707 kidiam = v.diam->ToPcbUnits();
2708 via->SetWidth( kidiam );
2709 }
2710 else
2711 {
2712 double annulus = drillz * m_rules->rvViaOuter; // eagle "restring"
2713 annulus = eagleClamp( m_rules->rlMinViaOuter, annulus,
2715 kidiam = KiROUND( drillz + 2 * annulus );
2716 via->SetWidth( kidiam );
2717 }
2718
2719 via->SetDrill( drillz );
2720
2721 // make sure the via diameter respects the restring rules
2722
2723 if( !v.diam || via->GetWidth() <= via->GetDrill() )
2724 {
2725 double annulus =
2727 (double) ( via->GetWidth() / 2 - via->GetDrill() ),
2729 via->SetWidth( drillz + 2 * annulus );
2730 }
2731
2732 if( kidiam < m_min_via )
2733 m_min_via = kidiam;
2734
2735 if( netclass && kidiam < netclass->GetViaDiameter() )
2736 netclass->SetViaDiameter( kidiam );
2737
2738 if( drillz < m_min_hole )
2739 m_min_hole = drillz;
2740
2741 if( netclass && drillz < netclass->GetViaDrill() )
2742 netclass->SetViaDrill( drillz );
2743
2744 if( ( kidiam - drillz ) / 2 < m_min_annulus )
2745 m_min_annulus = ( kidiam - drillz ) / 2;
2746
2747 if( layer_front_most == F_Cu && layer_back_most == B_Cu )
2748 {
2749 via->SetViaType( VIATYPE::THROUGH );
2750 }
2754 else if( v.layer_back_most - v.layer_front_most == 1 )
2755 {
2756 via->SetViaType( VIATYPE::MICROVIA );
2757 }
2758 else
2759 {
2760 via->SetViaType( VIATYPE::BLIND_BURIED );
2761 }
2762
2763 VECTOR2I pos( kicad_x( v.x ), kicad_y( v.y ) );
2764
2765 via->SetLayerPair( layer_front_most, layer_back_most );
2766 via->SetPosition( pos );
2767 via->SetEnd( pos );
2768
2769 via->SetNetCode( netCode );
2770 }
2771
2772 m_xpath->pop();
2773 }
2774
2775 else if( itemName == wxT( "contactref" ) )
2776 {
2777 m_xpath->push( "contactref" );
2778 // <contactref element="RN1" pad="7"/>
2779
2780 const wxString& reference = netItem->GetAttribute( "element" );
2781 const wxString& pad = netItem->GetAttribute( "pad" );
2782 wxString key = makeKey( reference, pad ) ;
2783
2784 m_pads_to_nets[ key ] = ENET( netCode, netName );
2785
2786 m_xpath->pop();
2787
2788 sawPad = true;
2789 }
2790
2791 else if( itemName == wxT( "polygon" ) )
2792 {
2793 m_xpath->push( "polygon" );
2794 auto* zone = loadPolygon( netItem );
2795
2796 if( zone )
2797 {
2798 zones.push_back( zone );
2799
2800 if( !zone->GetIsRuleArea() )
2801 zone->SetNetCode( netCode );
2802 }
2803
2804 m_xpath->pop(); // "polygon"
2805 }
2806
2807 netItem = netItem->GetNext();
2808 }
2809
2810 if( zones.size() && !sawPad )
2811 {
2812 // KiCad does not support an unconnected zone with its own non-zero netcode,
2813 // but only when assigned netcode = 0 w/o a name...
2814 for( ZONE* zone : zones )
2815 zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
2816
2817 // therefore omit this signal/net.
2818 }
2819 else
2820 {
2821 netCode++;
2822 }
2823
2824 // Get next signal
2825 net = net->GetNext();
2826 }
2827
2828 m_xpath->pop(); // "signals.signal"
2829}
Handle the data for a net.
Definition: netinfo.h:67
void SetNetClass(const std::shared_ptr< NETCLASS > &aNetClass)
void SetWidth(int aWidth)
Definition: pcb_track.h:106
void SetEnd(const VECTOR2I &aEnd)
Definition: pcb_track.h:109
void SetPosition(const VECTOR2I &aPos) override
Definition: pcb_track.h:102
wxString escapeName(const wxString &aNetName)
Interprets special characters in Eagle text and converts them to KiCAD notation.
static T eagleClamp(T aMin, T aValue, T aMax)
std::vector< ZONE * > ZONES
Definition: eagle_plugin.h:44
@ CTX_NETCLASS
@ BLIND_BURIED
double rlMinViaOuter
minimum copper annulus on via
Definition: eagle_plugin.h:119
double rlMaxViaOuter
maximum copper annulus on via
Definition: eagle_plugin.h:120
double rvViaOuter
copper annulus is this percent of via hole
Definition: eagle_plugin.h:118
Eagle via.
Definition: eagle_parser.h:552

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

Referenced by loadAllSections().

◆ makeFootprint()

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

Create a FOOTPRINT from an Eagle package.

Definition at line 1732 of file eagle_plugin.cpp.

1733{
1734 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>( m_board );
1735
1736 LIB_ID fpID;
1737 fpID.Parse( aPkgName, true );
1738 m->SetFPID( fpID );
1739
1740 // Get the first package item and iterate
1741 wxXmlNode* packageItem = aPackage->GetChildren();
1742
1743 // layer 27 is default layer for tValues
1744 // set default layer for created footprint
1745 PCB_LAYER_ID layer = kicad_layer( 27 );
1746 m.get()->Value().SetLayer( layer );
1747
1748 while( packageItem )
1749 {
1750 const wxString& itemName = packageItem->GetName();
1751
1752 if( itemName == wxT( "description" ) )
1753 m->SetDescription( packageItem->GetNodeContent() );
1754 else if( itemName == wxT( "wire" ) )
1755 packageWire( m.get(), packageItem );
1756 else if( itemName == wxT( "pad" ) )
1757 packagePad( m.get(), packageItem );
1758 else if( itemName == wxT( "text" ) )
1759 packageText( m.get(), packageItem );
1760 else if( itemName == wxT( "rectangle" ) )
1761 packageRectangle( m.get(), packageItem );
1762 else if( itemName == wxT( "polygon" ) )
1763 packagePolygon( m.get(), packageItem );
1764 else if( itemName == wxT( "circle" ) )
1765 packageCircle( m.get(), packageItem );
1766 else if( itemName == wxT( "hole" ) )
1767 packageHole( m.get(), packageItem, false );
1768 else if( itemName == wxT( "smd" ) )
1769 packageSMD( m.get(), packageItem );
1770
1771 packageItem = packageItem->GetNext();
1772 }
1773
1774 return m.release();
1775}
void packageCircle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void packageSMD(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
Handles common pad properties.
void packagePolygon(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void packageText(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void packagePad(FOOTPRINT *aFootprint, wxXmlNode *aTree)
void packageWire(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void packageRectangle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:50

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

Referenced by loadLibrary().

◆ mapEagleLayersToKicad()

void EAGLE_PLUGIN::mapEagleLayersToKicad ( bool  aIsLibraryCache = false)
private

Generate mapping between Eagle and KiCad layers.

Warning
It is imperative that this gets called correctly because footprint libraries do not get remapped by the user on load. Otherwise, Pcbnew will crash when attempting to load footprint libraries that contain layers that do not exist in the EAGLE_LAYER definitions.
Parameters
aIsLibraryCacheis the flag to indicate when mapping the footprint library cache layers rather than the board layers.

Definition at line 2847 of file eagle_plugin.cpp.

2848{
2849 std::vector<INPUT_LAYER_DESC> inputDescs;
2850
2851 for ( const std::pair<const int, ELAYER>& layerPair : m_eagleLayers )
2852 {
2853 const ELAYER& eLayer = layerPair.second;
2854
2855 INPUT_LAYER_DESC layerDesc;
2856 std::tie( layerDesc.AutoMapLayer, layerDesc.PermittedLayers, layerDesc.Required ) =
2857 defaultKicadLayer( eLayer.number, aIsLibraryCache );
2858
2859 if( layerDesc.AutoMapLayer == UNDEFINED_LAYER )
2860 continue; // Ignore unused copper layers
2861
2862 layerDesc.Name = eLayer.name;
2863
2864 inputDescs.push_back( layerDesc );
2865 }
2866
2867 if( m_progressReporter && dynamic_cast<wxWindow*>( m_progressReporter ) )
2868 dynamic_cast<wxWindow*>( m_progressReporter )->Hide();
2869
2870 m_layer_map = m_layer_mapping_handler( inputDescs );
2871
2872 if( m_progressReporter && dynamic_cast<wxWindow*>( m_progressReporter ))
2873 dynamic_cast<wxWindow*>( m_progressReporter )->Show();
2874}
LAYER_MAPPING_HANDLER m_layer_mapping_handler
Callback to get layer mapping.
wxString name
Definition: eagle_parser.h:833
int number
Definition: eagle_parser.h:832
PCB_LAYER_ID AutoMapLayer
Best guess as to what the equivalent KiCad layer might be.
bool Required
Should we require the layer to be assigned?
LSET PermittedLayers
KiCad layers that the imported layer can be mapped onto.
wxString Name
Imported layer name as displayed in original application.

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

Referenced by cacheLib(), and loadAllSections().

◆ orientFootprintAndText()

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

Definition at line 1558 of file eagle_plugin.cpp.

1560{
1561 if( e.rot )
1562 {
1563 if( e.rot->mirror )
1564 {
1565 aFootprint->SetOrientation( EDA_ANGLE( e.rot->degrees + 180.0, DEGREES_T ) );
1566 aFootprint->Flip( aFootprint->GetPosition(), false );
1567 }
1568 else
1569 {
1570 aFootprint->SetOrientation( EDA_ANGLE( e.rot->degrees, DEGREES_T ) );
1571 }
1572 }
1573
1574 orientFPText( aFootprint, e, &aFootprint->Reference(), aNameAttr );
1575 orientFPText( aFootprint, e, &aFootprint->Value(), aValueAttr );
1576}
void orientFPText(FOOTPRINT *aFootprint, const EELEMENT &e, FP_TEXT *aFPText, const EATTR *aAttr)
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:1803
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: footprint.cpp:1587
VECTOR2I GetPosition() const override
Definition: footprint.h:188
opt_erot rot
Definition: eagle_parser.h:824
double degrees
Definition: eagle_parser.h:480
bool mirror
Definition: eagle_parser.h:478

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

Referenced by loadElements().

◆ orientFPText()

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

Definition at line 1579 of file eagle_plugin.cpp.

1581{
1582 // Smashed part ?
1583 if( aAttr )
1584 {
1585 // Yes
1586 const EATTR& a = *aAttr;
1587
1588 if( a.value )
1589 {
1590 aFPText->SetText( *a.value );
1591 }
1592
1593 if( a.x && a.y ) // std::optional
1594 {
1595 VECTOR2I pos( kicad_x( *a.x ), kicad_y( *a.y ) );
1596 aFPText->SetTextPos( pos );
1597 }
1598
1599 // Even though size and ratio are both optional, I am not seeing
1600 // a case where ratio is present but size is not.
1601 double ratio = 8;
1602
1603 if( a.ratio )
1604 ratio = *a.ratio;
1605
1606 VECTOR2I fontz = aFPText->GetTextSize();
1607 int textThickness = KiROUND( fontz.y * ratio / 100 );
1608
1609 aFPText->SetTextThickness( textThickness );
1610 if( a.size )
1611 {
1612 fontz = kicad_fontz( *a.size, textThickness );
1613 aFPText->SetTextSize( fontz );
1614 }
1615
1616
1617 int align = ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
1618
1619 if( a.align )
1620 align = a.align;
1621
1622 // The "rot" in a EATTR seems to be assumed to be zero if it is not
1623 // present, and this zero rotation becomes an override to the
1624 // package's text field. If they did not want zero, they specify
1625 // what they want explicitly.
1626 double degrees = a.rot ? a.rot->degrees : 0.0;
1627 double orient; // relative to parent
1628
1629 int sign = 1;
1630 bool spin = false;
1631
1632 if( a.rot )
1633 {
1634 spin = a.rot->spin;
1635 sign = a.rot->mirror ? -1 : 1;
1636 aFPText->SetMirrored( a.rot->mirror );
1637 }
1638
1639 if( degrees == 90 || degrees == 0 || spin )
1640 {
1641 orient = degrees - aFootprint->GetOrientation().AsDegrees();
1642 aFPText->SetTextAngle( EDA_ANGLE( sign * orient, DEGREES_T ) );
1643 }
1644 else if( degrees == 180 )
1645 {
1646 orient = 0 - aFootprint->GetOrientation().AsDegrees();
1647 aFPText->SetTextAngle( EDA_ANGLE( sign * orient, DEGREES_T ) );
1648 align = -align;
1649 }
1650 else if( degrees == 270 )
1651 {
1652 orient = 90 - aFootprint->GetOrientation().AsDegrees();
1653 align = -align;
1654 aFPText->SetTextAngle( EDA_ANGLE( sign * orient, DEGREES_T ) );
1655 }
1656 else
1657 {
1658 orient = 90 - degrees - aFootprint->GetOrientation().AsDegrees();
1659 aFPText->SetTextAngle( EDA_ANGLE( sign * orient, DEGREES_T ) );
1660 }
1661
1662 switch( align )
1663 {
1664 case ETEXT::TOP_RIGHT:
1667 break;
1668
1669 case ETEXT::BOTTOM_LEFT:
1672 break;
1673
1674 case ETEXT::TOP_LEFT:
1677 break;
1678
1682 break;
1683
1684 case ETEXT::TOP_CENTER:
1687 break;
1688
1692 break;
1693
1694 case ETEXT::CENTER:
1697 break;
1698
1699 case ETEXT::CENTER_LEFT:
1702 break;
1703
1707 break;
1708
1709 default:
1710 ;
1711 }
1712 }
1713 else
1714 {
1715 // Part is not smash so use Lib default for NAME/VALUE
1716 // the text is per the original package, sans <attribute>.
1717 double degrees = aFPText->GetTextAngle().AsDegrees()
1718 + aFootprint->GetOrientation().AsDegrees();
1719
1720 // @todo there are a few more cases than these to contend with:
1721 if( ( !aFPText->IsMirrored() && ( abs( degrees ) == 180 || abs( degrees ) == 270 ) )
1722 || ( aFPText->IsMirrored() && ( degrees == 360 ) ) )
1723 {
1724 // ETEXT::TOP_RIGHT:
1727 }
1728 }
1729}
double AsDegrees() const
Definition: eda_angle.h:149
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:120
bool IsMirrored() const
Definition: eda_text.h:139
VECTOR2I GetTextSize() const
Definition: eda_text.h:196
EDA_ANGLE GetOrientation() const
Definition: footprint.h:191
opt_double ratio
Definition: eagle_parser.h:606
opt_ecoord size
Definition: eagle_parser.h:604
opt_ecoord y
Definition: eagle_parser.h:603
opt_erot rot
Definition: eagle_parser.h:607
opt_int align
Definition: eagle_parser.h:616
opt_ecoord x
Definition: eagle_parser.h:602
bool spin
Definition: eagle_parser.h:479

References std::abs(), EATTR::align, EDA_ANGLE::AsDegrees(), ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, ETEXT::CENTER, ETEXT::CENTER_LEFT, ETEXT::CENTER_RIGHT, EROT::degrees, DEGREES_T, FOOTPRINT::GetOrientation(), EDA_TEXT::GetTextAngle(), EDA_TEXT::GetTextSize(), GR_TEXT_H_ALIGN_CENTER, GR_TEXT_H_ALIGN_LEFT, GR_TEXT_H_ALIGN_RIGHT, GR_TEXT_V_ALIGN_BOTTOM, GR_TEXT_V_ALIGN_CENTER, GR_TEXT_V_ALIGN_TOP, EDA_TEXT::IsMirrored(), kicad_fontz(), kicad_x(), kicad_y(), KiROUND(), EROT::mirror, EATTR::ratio, EATTR::rot, EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetMirrored(), EDA_TEXT::SetText(), EDA_TEXT::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetVertJustify(), sign(), EATTR::size, EROT::spin, ETEXT::TOP_CENTER, ETEXT::TOP_LEFT, ETEXT::TOP_RIGHT, EATTR::value, EATTR::x, EATTR::y, and VECTOR2< T >::y.

Referenced by orientFootprintAndText().

◆ packageCircle()

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

Definition at line 2250 of file eagle_plugin.cpp.

2251{
2252 ECIRCLE e( aTree );
2253
2254 int width = e.width.ToPcbUnits();
2255 int radius = e.radius.ToPcbUnits();
2256
2257 if( e.layer == EAGLE_LAYER::TRESTRICT
2258 || e.layer == EAGLE_LAYER::BRESTRICT
2259 || e.layer == EAGLE_LAYER::VRESTRICT )
2260 {
2261 FP_ZONE* zone = new FP_ZONE( aFootprint );
2262 aFootprint->Add( zone, ADD_MODE::APPEND );
2263
2264 setKeepoutSettingsToZone( zone, e.layer );
2265
2266 // approximate circle as polygon
2267 VECTOR2I center( kicad_x( e.x ), kicad_y( e.y ) );
2268 int outlineRadius = radius + ( width / 2 );
2269 int segsInCircle = GetArcToSegmentCount( outlineRadius, ARC_HIGH_DEF, FULL_CIRCLE );
2270 EDA_ANGLE delta = ANGLE_360 / segsInCircle;
2271
2273 {
2274 VECTOR2I rotatedPoint( outlineRadius, 0 );
2275 RotatePoint( rotatedPoint, angle );
2276 zone->AppendCorner( center + rotatedPoint, -1 );
2277 }
2278
2279 if( width > 0 )
2280 {
2281 zone->NewHole();
2282 int innerRadius = radius - ( width / 2 );
2283 segsInCircle = GetArcToSegmentCount( innerRadius, ARC_HIGH_DEF, FULL_CIRCLE );
2284 delta = ANGLE_360 / segsInCircle;
2285
2287 {
2288 VECTOR2I rotatedPoint( innerRadius, 0 );
2289 RotatePoint( rotatedPoint, angle );
2290 zone->AppendCorner( center + rotatedPoint, 0 );
2291 }
2292 }
2293
2296 }
2297 else
2298 {
2299 PCB_LAYER_ID layer = kicad_layer( e.layer );
2300
2301 if( layer == UNDEFINED_LAYER )
2302 {
2303 wxLogMessage( wxString::Format( _( "Ignoring a circle since Eagle layer '%s' (%d) "
2304 "was not mapped" ),
2305 eagle_layer_name( e.layer ), e.layer ) );
2306 return;
2307 }
2308
2309 FP_SHAPE* gr = new FP_SHAPE( aFootprint, SHAPE_T::CIRCLE );
2310
2311 // width == 0 means filled circle
2312 if( width <= 0 )
2313 {
2314 width = radius;
2315 radius = radius / 2;
2316 gr->SetFilled( true );
2317 }
2318
2319 aFootprint->Add( gr );
2321
2322 switch( (int) layer )
2323 {
2324 case UNDEFINED_LAYER:
2325 layer = Cmts_User;
2326 break;
2327 default:
2328 break;
2329 }
2330
2331 gr->SetLayer( layer );
2332 gr->SetStart0( VECTOR2I( kicad_x( e.x ), kicad_y( e.y ) ) );
2333 gr->SetEnd0( VECTOR2I( kicad_x( e.x ) + radius, kicad_y( e.y ) ) );
2334 gr->SetDrawCoord();
2335 }
2336}
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: footprint.cpp:567
void SetEnd0(const VECTOR2I &aPoint)
Definition: fp_shape.h:94
void SetStart0(const VECTOR2I &aPoint)
Definition: fp_shape.h:91
virtual void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:80
A specialization of ZONE for use in footprints.
Definition: zone.h:910

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

Referenced by makeFootprint().

◆ packageHole()

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

Definition at line 2339 of file eagle_plugin.cpp.

2340{
2341 EHOLE e( aTree );
2342
2343 if( e.drill.value == 0 )
2344 return;
2345
2346 // we add a PAD_ATTRIB::NPTH pad to this footprint.
2347 PAD* pad = new PAD( aFootprint );
2348 aFootprint->Add( pad );
2349
2350 pad->SetKeepTopBottom( false ); // TODO: correct? This seems to be KiCad default on import
2351
2352 pad->SetShape( PAD_SHAPE::CIRCLE );
2353 pad->SetAttribute( PAD_ATTRIB::NPTH );
2354
2355 // Mechanical purpose only:
2356 // no offset, no net name, no pad name allowed
2357 // pad->SetOffset( VECTOR2I( 0, 0 ) );
2358 // pad->SetNumber( wxEmptyString );
2359
2360 VECTOR2I padpos( kicad_x( e.x ), kicad_y( e.y ) );
2361
2362 if( aCenter )
2363 {
2364 pad->SetPos0( VECTOR2I( 0, 0 ) );
2365 aFootprint->SetPosition( padpos );
2366 pad->SetPosition( padpos );
2367 }
2368 else
2369 {
2370 pad->SetPos0( padpos );
2371 pad->SetPosition( padpos + aFootprint->GetPosition() );
2372 }
2373
2374 wxSize sz( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() );
2375
2376 pad->SetDrillSize( sz );
2377 pad->SetSize( sz );
2378
2379 pad->SetLayerSet( LSET::AllCuMask().set( B_Mask ).set( F_Mask ) );
2380}
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
@ NPTH
like PAD_PTH, but not plated
Eagle hole element.
Definition: eagle_parser.h:804

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

Referenced by loadPlain(), and makeFootprint().

◆ packagePad()

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

Definition at line 1850 of file eagle_plugin.cpp.

1851{
1852 // this is thru hole technology here, no SMDs
1853 EPAD e( aTree );
1854 int shape = EPAD::UNDEF;
1855 int eagleDrillz = e.drill.ToPcbUnits();
1856
1857 std::unique_ptr<PAD> pad = std::make_unique<PAD>( aFootprint );
1858 transferPad( e, pad.get() );
1859
1860 if( e.first && *e.first && m_rules->psFirst != EPAD::UNDEF )
1861 shape = m_rules->psFirst;
1862 else if( aFootprint->GetLayer() == F_Cu && m_rules->psTop != EPAD::UNDEF )
1863 shape = m_rules->psTop;
1864 else if( aFootprint->GetLayer() == B_Cu && m_rules->psBottom != EPAD::UNDEF )
1865 shape = m_rules->psBottom;
1866
1867 pad->SetDrillSize( wxSize( eagleDrillz, eagleDrillz ) );
1868 pad->SetLayerSet( LSET::AllCuMask() );
1869
1870 if( eagleDrillz < m_min_hole )
1871 m_min_hole = eagleDrillz;
1872
1873 // Solder mask
1874 if( !e.stop || *e.stop == true ) // enabled by default
1875 pad->SetLayerSet( pad->GetLayerSet().set( B_Mask ).set( F_Mask ) );
1876
1877 if( shape == EPAD::ROUND || shape == EPAD::SQUARE || shape == EPAD::OCTAGON )
1878 e.shape = shape;
1879
1880 if( e.shape )
1881 {
1882 switch( *e.shape )
1883 {
1884 case EPAD::ROUND:
1885 pad->SetShape( PAD_SHAPE::CIRCLE );
1886 break;
1887
1888 case EPAD::OCTAGON:
1889 pad->SetShape( PAD_SHAPE::CHAMFERED_RECT );
1890 pad->SetChamferPositions( RECT_CHAMFER_ALL );
1891 pad->SetChamferRectRatio( 1 - M_SQRT1_2 ); // Regular polygon
1892 break;
1893
1894 case EPAD::LONG:
1895 pad->SetShape( PAD_SHAPE::OVAL );
1896 break;
1897
1898 case EPAD::SQUARE:
1899 pad->SetShape( PAD_SHAPE::RECT );
1900 break;
1901
1902 case EPAD::OFFSET:
1903 pad->SetShape( PAD_SHAPE::OVAL );
1904 break;
1905 }
1906 }
1907 else
1908 {
1909 // if shape is not present, our default is circle and that matches their default "round"
1910 }
1911
1912 if( e.diameter && e.diameter->value > 0 )
1913 {
1914 int diameter = e.diameter->ToPcbUnits();
1915 pad->SetSize( wxSize( diameter, diameter ) );
1916 }
1917 else
1918 {
1919 double drillz = pad->GetDrillSize().x;
1920 double annulus = drillz * m_rules->rvPadTop; // copper annulus, eagle "restring"
1921 annulus = eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
1922 int diameter = KiROUND( drillz + 2 * annulus );
1923 pad->SetSize( wxSize( KiROUND( diameter ), KiROUND( diameter ) ) );
1924 }
1925
1926 if( pad->GetShape() == PAD_SHAPE::OVAL )
1927 {
1928 // The Eagle "long" pad is wider than it is tall; m_elongation is percent elongation
1929 VECTOR2I sz = pad->GetSize();
1930 sz.x = ( sz.x * ( 100 + m_rules->psElongationLong ) ) / 100;
1931 pad->SetSize( sz );
1932
1933 if( e.shape && *e.shape == EPAD::OFFSET )
1934 {
1935 int offset = KiROUND( ( sz.x - sz.y ) / 2.0 );
1936 pad->SetOffset( VECTOR2I( offset, 0 ) );
1937 }
1938 }
1939
1940 if( e.rot )
1941 pad->SetOrientation( EDA_ANGLE( e.rot->degrees, DEGREES_T ) );
1942
1943 if( pad->GetSizeX() > 0 && pad->GetSizeY() > 0 )
1944 {
1945 aFootprint->Add( pad.release() );
1946 }
1947 else
1948 {
1949 wxLogError( _( "Invalid zero-sized pad ignored in\nfile: %s" ), m_board->GetFileName() );
1950 }
1951}
const wxString & GetFileName() const
Definition: board.h:302
void transferPad(const EPAD_COMMON &aEaglePad, PAD *aPad) const
Deletes the footprint templates list.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: footprint.h:200
Eagle thru hole pad.
Definition: eagle_parser.h:711
@ OCTAGON
Definition: eagle_parser.h:720
@ SQUARE
Definition: eagle_parser.h:718
@ OFFSET
Definition: eagle_parser.h:722
int psBottom
Shape of the bottom pads.
Definition: eagle_plugin.h:101
int psElongationLong
Definition: eagle_plugin.h:86
int psTop
Shape of the top pads.
Definition: eagle_plugin.h:100
double rvPadTop
top pad size as percent of drill size
Definition: eagle_plugin.h:112
double rlMinPadTop
minimum copper annulus on through hole pads
Definition: eagle_plugin.h:115
double rlMaxPadTop
maximum copper annulus on through hole pads
Definition: eagle_plugin.h:116
int psFirst
Shape of the first pads.
Definition: eagle_plugin.h:102

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

Referenced by makeFootprint().

◆ packagePolygon()

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

Definition at line 2146 of file eagle_plugin.cpp.

2147{
2148 EPOLYGON p( aTree );
2149
2150 std::vector<VECTOR2I> pts;
2151
2152 // Get the first vertex and iterate
2153 wxXmlNode* vertex = aTree->GetChildren();
2154 std::vector<EVERTEX> vertices;
2155
2156 // Create a circular vector of vertices
2157 // The "curve" parameter indicates a curve from the current
2158 // to the next vertex, so we keep the first at the end as well
2159 // to allow the curve to link back
2160 while( vertex )
2161 {
2162 if( vertex->GetName() == wxT( "vertex" ) )
2163 vertices.emplace_back( vertex );
2164
2165 vertex = vertex->GetNext();
2166 }
2167
2168 vertices.push_back( vertices[0] );
2169
2170 for( size_t i = 0; i < vertices.size() - 1; i++ )
2171 {
2172 EVERTEX v1 = vertices[i];
2173
2174 // Append the corner
2175 pts.emplace_back( kicad_x( v1.x ), kicad_y( v1.y ) );
2176
2177 if( v1.curve )
2178 {
2179 EVERTEX v2 = vertices[i + 1];
2180 VECTOR2I center =
2182 VECTOR2I( kicad_x( v2.x ), kicad_y( v2.y ) ), *v1.curve );
2183 double angle = DEG2RAD( *v1.curve );
2184 double end_angle = atan2( kicad_y( v2.y ) - center.y, kicad_x( v2.x ) - center.x );
2185 double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
2186 + pow( center.y - kicad_y( v1.y ), 2 ) );
2187
2188 // Don't allow a zero-radius curve
2189 if( KiROUND( radius ) == 0 )
2190 radius = 1.0;
2191
2192 int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
2193 EDA_ANGLE( *v1.curve, DEGREES_T ) );
2194 double delta = angle / segCount;
2195
2196 for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta ); a -= delta )
2197 {
2198 pts.push_back(
2199 VECTOR2I( KiROUND( radius * cos( a ) ), KiROUND( radius * sin( a ) ) )
2200 + center );
2201 }
2202 }
2203 }
2204
2205 if( p.pour == EPOLYGON::CUTOUT
2206 || p.layer == EAGLE_LAYER::TRESTRICT
2207 || p.layer == EAGLE_LAYER::BRESTRICT
2208 || p.layer == EAGLE_LAYER::VRESTRICT )
2209 {
2210 FP_ZONE* zone = new FP_ZONE( aFootprint );
2211 aFootprint->Add( zone, ADD_MODE::APPEND );
2212
2213 setKeepoutSettingsToZone( zone, p.layer );
2214
2215 SHAPE_LINE_CHAIN outline( pts );
2216 outline.SetClosed( true );
2217 zone->Outline()->AddOutline( outline );
2218
2221 }
2222 else
2223 {
2224 PCB_LAYER_ID layer = kicad_layer( p.layer );
2225
2226 if( layer == UNDEFINED_LAYER )
2227 {
2228 wxLogMessage( wxString::Format( _( "Ignoring a polygon since Eagle layer '%s' (%d) "
2229 "was not mapped" ),
2230 eagle_layer_name( p.layer ), p.layer ) );
2231 return;
2232 }
2233
2234 FP_SHAPE* dwg = new FP_SHAPE( aFootprint, SHAPE_T::POLY );
2235
2236 aFootprint->Add( dwg );
2237
2238 dwg->SetStroke( STROKE_PARAMS( 0 ) );
2239 dwg->SetFilled( true );
2240 dwg->SetLayer( layer );
2241
2242 dwg->SetPolyPoints( pts );
2243 dwg->SetDrawCoord();
2244 dwg->GetPolyShape().Inflate( p.width.ToPcbUnits() / 2, 32,
2246 }
2247}
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:247
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
Definition: eda_shape.cpp:1121
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
SHAPE_POLY_SET * Outline()
Definition: zone.h:312

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

Referenced by makeFootprint().

◆ packageRectangle()

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

Definition at line 2080 of file eagle_plugin.cpp.

2081{
2082 ERECT r( aTree );
2083
2084 if( r.layer == EAGLE_LAYER::TRESTRICT || r.layer == EAGLE_LAYER::BRESTRICT
2085 || r.layer == EAGLE_LAYER::VRESTRICT )
2086 {
2087 FP_ZONE* zone = new FP_ZONE( aFootprint );
2088 aFootprint->Add( zone, ADD_MODE::APPEND );
2089
2090 setKeepoutSettingsToZone( zone, r.layer );
2091
2092 const int outlineIdx = -1; // this is the id of the copper zone main outline
2093 zone->AppendCorner( VECTOR2I( kicad_x( r.x1 ), kicad_y( r.y1 ) ), outlineIdx );
2094 zone->AppendCorner( VECTOR2I( kicad_x( r.x2 ), kicad_y( r.y1 ) ), outlineIdx );
2095 zone->AppendCorner( VECTOR2I( kicad_x( r.x2 ), kicad_y( r.y2 ) ), outlineIdx );
2096 zone->AppendCorner( VECTOR2I( kicad_x( r.x1 ), kicad_y( r.y2 ) ), outlineIdx );
2097
2098 if( r.rot )
2099 {
2100 VECTOR2I center( ( kicad_x( r.x1 ) + kicad_x( r.x2 ) ) / 2,
2101 ( kicad_y( r.y1 ) + kicad_y( r.y2 ) ) / 2 );
2102 zone->Rotate( center, EDA_ANGLE( r.rot->degrees, DEGREES_T ) );
2103 }
2104
2107 }
2108 else
2109 {
2110 PCB_LAYER_ID layer = kicad_layer( r.layer );
2111
2112 if( layer == UNDEFINED_LAYER )
2113 {
2114 wxLogMessage( wxString::Format( _( "Ignoring a rectangle since Eagle layer '%s' (%d) "
2115 "was not mapped" ),
2116 eagle_layer_name( r.layer ), r.layer ) );
2117 return;
2118 }
2119
2120 FP_SHAPE* dwg = new FP_SHAPE( aFootprint, SHAPE_T::POLY );
2121
2122 aFootprint->Add( dwg );
2123
2124 dwg->SetLayer( layer );
2125 dwg->SetStroke( STROKE_PARAMS( 0 ) );
2126 dwg->SetFilled( true );
2127
2128 std::vector<VECTOR2I> pts;
2129
2130 VECTOR2I start( VECTOR2I( kicad_x( r.x1 ), kicad_y( r.y1 ) ) );
2131 VECTOR2I end( VECTOR2I( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
2132
2133 pts.push_back( start );
2134 pts.emplace_back( kicad_x( r.x2 ), kicad_y( r.y1 ) );
2135 pts.emplace_back( kicad_x( r.x2 ), kicad_y( r.y2 ) );
2136 pts.push_back( end );
2137
2138 dwg->SetPolyPoints( pts );
2139
2140 if( r.rot )
2141 dwg->Rotate( dwg->GetCenter(), EDA_ANGLE( r.rot->degrees, DEGREES_T ) );
2142 }
2143}
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: fp_shape.cpp:343
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:67

References _, FOOTPRINT::Add(), APPEND, ZONE::AppendCorner(), EAGLE_LAYER::BRESTRICT, EROT::degrees, DEGREES_T, DIAGONAL_EDGE, eagle_layer_name(), Format(), PCB_SHAPE::GetCenter(), ZONE::GetDefaultHatchPitch(), kicad_layer(), kicad_x(), kicad_y(), ERECT::layer, POLY, ERECT::rot, ZONE::Rotate(), FP_SHAPE::Rotate(), ZONE::SetBorderDisplayStyle(), EDA_SHAPE::SetFilled(), setKeepoutSettingsToZone(), BOARD_ITEM::SetLayer(), EDA_SHAPE::SetPolyPoints(), PCB_SHAPE::SetStroke(), EAGLE_LAYER::TRESTRICT, UNDEFINED_LAYER, EAGLE_LAYER::VRESTRICT, ERECT::x1, ERECT::x2, ERECT::y1, and ERECT::y2.

Referenced by makeFootprint().

◆ packageSMD()

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

Handles common pad properties.

Definition at line 2383 of file eagle_plugin.cpp.

2384{
2385 ESMD e( aTree );
2386 PCB_LAYER_ID layer = kicad_layer( e.layer );
2387
2388 if( !IsCopperLayer( layer ) || e.dx.value == 0 || e.dy.value == 0 )
2389 return;
2390
2391 PAD* pad = new PAD( aFootprint );
2392 aFootprint->Add( pad );
2393 transferPad( e, pad );
2394
2395 pad->SetKeepTopBottom( false ); // TODO: correct? This seems to be KiCad default on import
2396
2397 pad->SetShape( PAD_SHAPE::RECT );
2398 pad->SetAttribute( PAD_ATTRIB::SMD );
2399
2400 wxSize padSize( e.dx.ToPcbUnits(), e.dy.ToPcbUnits() );
2401 pad->SetSize( padSize );
2402 pad->SetLayer( layer );
2403
2404 const LSET front( 3, F_Cu, F_Paste, F_Mask );
2405 const LSET back( 3, B_Cu, B_Paste, B_Mask );
2406
2407 if( layer == F_Cu )
2408 pad->SetLayerSet( front );
2409 else if( layer == B_Cu )
2410 pad->SetLayerSet( back );
2411
2412 int minPadSize = std::min( padSize.x, padSize.y );
2413
2414 // Rounded rectangle pads
2415 int roundRadius =
2416 eagleClamp( m_rules->srMinRoundness * 2, (int) ( minPadSize * m_rules->srRoundness ),
2417 m_rules->srMaxRoundness * 2 );
2418
2419 if( e.roundness || roundRadius > 0 )
2420 {
2421 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2422
2423 // Eagle uses a different definition of roundness, hence division by 200
2424 if( e.roundness )
2425 roundRatio = std::fmax( *e.roundness / 200.0, roundRatio );
2426
2427 pad->SetShape( PAD_SHAPE::ROUNDRECT );
2428 pad->SetRoundRectRadiusRatio( roundRatio );
2429 }
2430
2431 if( e.rot )
2432 pad->SetOrientation( EDA_ANGLE( e.rot->degrees, DEGREES_T ) );
2433
2434 pad->SetLocalSolderPasteMargin( -eagleClamp( m_rules->mlMinCreamFrame,
2435 (int) ( m_rules->mvCreamFrame * minPadSize ),
2437
2438 // Solder mask
2439 if( e.stop && *e.stop == false ) // enabled by default
2440 {
2441 if( layer == F_Cu )
2442 pad->SetLayerSet( pad->GetLayerSet().set( F_Mask, false ) );
2443 else if( layer == B_Cu )
2444 pad->SetLayerSet( pad->GetLayerSet().set( B_Mask, false ) );
2445 }
2446
2447 // Solder paste (only for SMD pads)
2448 if( e.cream && *e.cream == false ) // enabled by default
2449 {
2450 if( layer == F_Cu )
2451 pad->SetLayerSet( pad->GetLayerSet().set( F_Paste, false ) );
2452 else if( layer == B_Cu )
2453 pad->SetLayerSet( pad->GetLayerSet().set( B_Paste, false ) );
2454 }
2455}
@ SMD
Smd pad, appears on the solder paste layer (default)
double srRoundness
corner rounding ratio for SMD pads (percentage)
Definition: eagle_plugin.h:104
int mlMaxCreamFrame
solder paste mask, maximum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:98
int mlMinCreamFrame
solder paste mask, minimum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:97
int srMaxRoundness
Definition: eagle_plugin.h:110
double mvCreamFrame
Definition: eagle_plugin.h:94
int srMinRoundness
corner rounding radius, maximum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:107
Eagle SMD pad.
Definition: eagle_parser.h:733

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

Referenced by makeFootprint().

◆ packageText()

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

Definition at line 1954 of file eagle_plugin.cpp.

1955{
1956 ETEXT t( aTree );
1957 PCB_LAYER_ID layer = kicad_layer( t.layer );
1958
1959 if( layer == UNDEFINED_LAYER )
1960 {
1961 wxLogMessage( wxString::Format( _( "Ignoring a text since Eagle layer '%s' (%d) "
1962 "was not mapped" ),
1963 eagle_layer_name( t.layer ), t.layer ) );
1964 return;
1965 }
1966
1967 FP_TEXT* textItem;
1968
1969 if( t.text.Upper() == wxT( ">NAME" ) && aFootprint->GetReference().IsEmpty() )
1970 {
1971 textItem = &aFootprint->Reference();
1972
1973 textItem->SetText( wxT( "REF**" ) );
1974 }
1975 else if( t.text.Upper() == wxT( ">VALUE" ) && aFootprint->GetValue().IsEmpty() )
1976 {
1977 textItem = &aFootprint->Value();
1978
1979 textItem->SetText( aFootprint->GetFPID().GetLibItemName() );
1980 }
1981 else
1982 {
1983 // FIXME: graphical text items are rotated for some reason.
1984 textItem = new FP_TEXT( aFootprint );
1985 aFootprint->Add( textItem );
1986
1987 textItem->SetText( interpretText( t.text ) );
1988 }
1989
1990 VECTOR2I pos( kicad_x( t.x ), kicad_y( t.y ) );
1991
1992 textItem->SetTextPos( pos );
1993 textItem->SetPos0( pos - aFootprint->GetPosition() );
1994
1995 textItem->SetLayer( layer );
1996
1997 double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
1998 int textThickness = KiROUND( t.size.ToPcbUnits() * ratio / 100 );
1999
2000 textItem->SetTextThickness( textThickness );
2001 textItem->SetTextSize( kicad_fontz( t.size, textThickness ) );
2002
2003 int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
2004
2005 // An eagle package is never rotated, the DTD does not allow it.
2006 // angle -= aFootprint->GetOrienation();
2007
2008 if( t.rot )
2009 {
2010 int sign = t.rot->mirror ? -1 : 1;
2011 textItem->SetMirrored( t.rot->mirror );
2012
2013 double degrees = t.rot->degrees;
2014
2015 if( degrees == 90 || t.rot->spin )
2016 {
2017 textItem->SetTextAngle( EDA_ANGLE( sign * degrees, DEGREES_T ) );
2018 }
2019 else if( degrees == 180 )
2020 {
2021 align = ETEXT::TOP_RIGHT;
2022 }
2023 else if( degrees == 270 )
2024 {
2025 align = ETEXT::TOP_RIGHT;
2026 textItem->SetTextAngle( EDA_ANGLE( sign * 90, DEGREES_T ) );
2027 }
2028 }
2029
2030 switch( align )
2031 {
2032 case ETEXT::CENTER:
2035 break;
2036
2037 case ETEXT::CENTER_LEFT:
2040 break;
2041
2045 break;
2046
2047 case ETEXT::TOP_CENTER:
2050 break;
2051
2052 case ETEXT::TOP_LEFT:
2055 break;
2056
2057 case ETEXT::TOP_RIGHT:
2060 break;
2061
2065 break;
2066
2067 case ETEXT::BOTTOM_LEFT:
2070 break;
2071
2075 break;
2076 }
2077}
const LIB_ID & GetFPID() const
Definition: footprint.h:212
void SetPos0(const VECTOR2I &aPos)
Definition: fp_text.h:123
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102

References _, FOOTPRINT::Add(), ETEXT::align, ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, ETEXT::CENTER, ETEXT::CENTER_LEFT, ETEXT::CENTER_RIGHT, EROT::degrees, DEGREES_T, eagle_layer_name(), Format(), FOOTPRINT::GetFPID(), LIB_ID::GetLibItemName(), FOOTPRINT::GetPosition(), FOOTPRINT::GetReference(), FOOTPRINT::GetValue(), GR_TEXT_H_ALIGN_CENTER, GR_TEXT_H_ALIGN_LEFT, GR_TEXT_H_ALIGN_RIGHT, GR_TEXT_V_ALIGN_BOTTOM, GR_TEXT_V_ALIGN_CENTER, GR_TEXT_V_ALIGN_TOP, interpretText(), kicad_fontz(), kicad_layer(), kicad_x(), kicad_y(), KiROUND(), ETEXT::layer, EROT::mirror, ETEXT::ratio, FOOTPRINT::Reference(), ETEXT::rot, EDA_TEXT::SetHorizJustify(), BOARD_ITEM::SetLayer(), EDA_TEXT::SetMirrored(), FP_TEXT::SetPos0(), EDA_TEXT::SetText(), EDA_TEXT::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetVertJustify(), sign(), ETEXT::size, EROT::spin, ETEXT::text, ETEXT::TOP_CENTER, ETEXT::TOP_LEFT, ETEXT::TOP_RIGHT, ECOORD::ToPcbUnits(), UNDEFINED_LAYER, FOOTPRINT::Value(), ETEXT::x, and ETEXT::y.

Referenced by makeFootprint().

◆ packageWire()

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

Definition at line 1778 of file eagle_plugin.cpp.

1779{
1780 EWIRE w( aTree );
1781 PCB_LAYER_ID layer = kicad_layer( w.layer );
1782 VECTOR2I start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
1783 VECTOR2I end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
1784 int width = w.width.ToPcbUnits();
1785
1786 if( layer == UNDEFINED_LAYER )
1787 {
1788 wxLogMessage( wxString::Format( _( "Ignoring a wire since Eagle layer '%s' (%d) "
1789 "was not mapped" ),
1790 eagle_layer_name( w.layer ), w.layer ) );
1791 return;
1792 }
1793
1794 // KiCad cannot handle zero or negative line widths which apparently have meaning in Eagle.
1795 if( width <= 0 )
1796 {
1797 BOARD* board = aFootprint->GetBoard();
1798
1799 if( board )
1800 {
1801 width = board->GetDesignSettings().GetLineThickness( layer );
1802 }
1803 else
1804 {
1805 // When loading footprint libraries, there is no board so use the default KiCad
1806 // line widths.
1807 switch( layer )
1808 {
1809 case Edge_Cuts: width = pcbIUScale.mmToIU( DEFAULT_EDGE_WIDTH ); break;
1810
1811 case F_SilkS:
1812 case B_SilkS: width = pcbIUScale.mmToIU( DEFAULT_SILK_LINE_WIDTH ); break;
1813
1814 case F_CrtYd:
1815 case B_CrtYd: width = pcbIUScale.mmToIU( DEFAULT_COURTYARD_WIDTH ); break;
1816
1817 default: width = pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ); break;
1818 }
1819 }
1820 }
1821
1822 // FIXME: the cap attribute is ignored because KiCad can't create lines with flat ends.
1823 FP_SHAPE* dwg;
1824
1825 if( !w.curve )
1826 {
1827 dwg = new FP_SHAPE( aFootprint, SHAPE_T::SEGMENT );
1828
1829 dwg->SetStart0( start );
1830 dwg->SetEnd0( end );
1831 }
1832 else
1833 {
1834 dwg = new FP_SHAPE( aFootprint, SHAPE_T::ARC );
1835 VECTOR2I center = ConvertArcCenter( start, end, *w.curve );
1836
1837 dwg->SetCenter0( center );
1838 dwg->SetStart0( start );
1839 dwg->SetArcAngleAndEnd0( -EDA_ANGLE( *w.curve, DEGREES_T ), true ); // KiCad rotates the other way
1840 }
1841
1842 dwg->SetLayer( layer );
1844 dwg->SetDrawCoord();
1845
1846 aFootprint->Add( dwg );
1847}
#define DEFAULT_SILK_LINE_WIDTH
#define DEFAULT_EDGE_WIDTH
#define DEFAULT_LINE_WIDTH
#define DEFAULT_COURTYARD_WIDTH
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:43
void SetArcAngleAndEnd0(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: fp_shape.cpp:193
void SetCenter0(const VECTOR2I &aPt)
Definition: fp_shape.cpp:161
constexpr int mmToIU(double mm) const
Definition: base_units.h:89

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

Referenced by makeFootprint().

◆ PluginName()

const wxString EAGLE_PLUGIN::PluginName ( ) const
overridevirtual

Return a brief hard coded name for this PLUGIN.

Implements PLUGIN.

Definition at line 246 of file eagle_plugin.cpp.

247{
248 return wxT( "Eagle" );
249}

◆ PrefetchLib()

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

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

performing downloads). Does not parse. Threadsafe.

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

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the plugin anything needed about how to perform with respect to aLibraryPath. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is an error prefetching the library.

Definition at line 75 of file plugin.cpp.

76{
77}

Referenced by FP_LIB_TABLE::PrefetchLib().

◆ RegisterLayerMappingCallback()

virtual void LAYER_REMAPPABLE_PLUGIN::RegisterLayerMappingCallback ( LAYER_MAPPING_HANDLER  aLayerMappingHandler)
inlinevirtualinherited

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

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

Parameters
aLayerMappingHandler

Reimplemented in CADSTAR_PCB_ARCHIVE_PLUGIN.

Definition at line 73 of file plugin_common_layer_mapping.h.

74 {
75 m_layer_mapping_handler = aLayerMappingHandler;
76 }

References LAYER_REMAPPABLE_PLUGIN::m_layer_mapping_handler.

Referenced by CADSTAR_PCB_ARCHIVE_PLUGIN::CADSTAR_PCB_ARCHIVE_PLUGIN(), EAGLE_PLUGIN(), PCB_EDIT_FRAME::OpenProjectFiles(), and CADSTAR_PCB_ARCHIVE_PLUGIN::RegisterLayerMappingCallback().

◆ Save()

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

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 CLIPBOARD_IO, and PCB_PLUGIN.

Definition at line 60 of file plugin.cpp.

61{
62 // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
63 not_implemented( this, __FUNCTION__ );
64}

References not_implemented().

Referenced by IO_MGR::Save(), PCB_EDIT_FRAME::SavePcbCopy(), and PCB_EDIT_FRAME::SavePcbFile().

◆ setKeepoutSettingsToZone()

void EAGLE_PLUGIN::setKeepoutSettingsToZone ( ZONE aZone,
int  aLayer 
) const
private

Definition at line 117 of file eagle_plugin.cpp.

118{
119 if( aLayer == EAGLE_LAYER::TRESTRICT || aLayer == EAGLE_LAYER::BRESTRICT )
120 {
121 aZone->SetIsRuleArea( true );
122 aZone->SetDoNotAllowVias( true );
123 aZone->SetDoNotAllowTracks( true );
124 aZone->SetDoNotAllowCopperPour( true );
125 aZone->SetDoNotAllowPads( true );
126 aZone->SetDoNotAllowFootprints( false );
127
128 if( aLayer == EAGLE_LAYER::TRESTRICT ) // front layer keepout
129 aZone->SetLayer( F_Cu );
130 else // bottom layer keepout
131 aZone->SetLayer( B_Cu );
132 }
133 else if( aLayer == EAGLE_LAYER::VRESTRICT )
134 {
135 aZone->SetIsRuleArea( true );
136 aZone->SetDoNotAllowVias( true );
137 aZone->SetDoNotAllowTracks( false );
138 aZone->SetDoNotAllowCopperPour( false );
139 aZone->SetDoNotAllowPads( false );
140 aZone->SetDoNotAllowFootprints( false );
141
142 aZone->SetLayerSet( LSET::AllCuMask() );
143 }
144 else // copper pour cutout
145 {
146 aZone->SetIsRuleArea( true );
147 aZone->SetDoNotAllowVias( false );
148 aZone->SetDoNotAllowTracks( false );
149 aZone->SetDoNotAllowCopperPour( true );
150 aZone->SetDoNotAllowPads( false );
151 aZone->SetDoNotAllowFootprints( false );
152
153 aZone->SetLayerSet( kicad_layer( aLayer ) );
154 }
155}
void SetLayerSet(LSET aLayerSet) override
Definition: zone.cpp:266

References LSET::AllCuMask(), B_Cu, EAGLE_LAYER::BRESTRICT, F_Cu, kicad_layer(), ZONE::SetDoNotAllowCopperPour(), ZONE::SetDoNotAllowFootprints(), ZONE::SetDoNotAllowPads(), ZONE::SetDoNotAllowTracks(), ZONE::SetDoNotAllowVias(), ZONE::SetIsRuleArea(), ZONE::SetLayer(), ZONE::SetLayerSet(), EAGLE_LAYER::TRESTRICT, and EAGLE_LAYER::VRESTRICT.

Referenced by loadPlain(), loadPolygon(), packageCircle(), packagePolygon(), and packageRectangle().

◆ SetQueryUserCallback()

virtual void PLUGIN::SetQueryUserCallback ( std::function< bool(wxString aTitle, int aIcon, wxString aMessage, wxString aAction)>  aCallback)
inlinevirtualinherited

Registers a KIDIALOG callback for collecting info from the user.

Definition at line 285 of file io_mgr.h.

288 { }

Referenced by PCB_CONTROL::AppendBoard(), and PCB_EDIT_FRAME::OpenProjectFiles().

◆ transferPad()

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

Deletes the footprint templates list.

Definition at line 2458 of file eagle_plugin.cpp.

2459{
2460 aPad->SetNumber( aEaglePad.name );
2461
2462 // pad's "Position" is not relative to the footprint's,
2463 // whereas Pos0 is relative to the footprint's but is the unrotated coordinate.
2464 VECTOR2I padPos( kicad_x( aEaglePad.x ), kicad_y( aEaglePad.y ) );
2465 aPad->SetPos0( padPos );
2466
2467 // Solder mask
2468 const VECTOR2I& padSize( aPad->GetSize() );
2469
2472 (int) ( m_rules->mvStopFrame * std::min( padSize.x, padSize.y ) ),
2474
2475 // Solid connection to copper zones
2476 if( aEaglePad.thermals && !*aEaglePad.thermals )
2478
2479 FOOTPRINT* footprint = aPad->GetParent();
2480 wxCHECK( footprint, /* void */ );
2481 RotatePoint( padPos, footprint->GetOrientation() );
2482 aPad->SetPosition( padPos + footprint->GetPosition() );
2483}
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
Definition: pad.h:134
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: pad.h:521
FOOTPRINT * GetParent() const
Definition: pad.cpp:1486
void SetPosition(const VECTOR2I &aPos) override
Definition: pad.h:196
void SetPos0(const VECTOR2I &aPos)
Definition: pad.h:250
void SetLocalSolderMaskMargin(int aMargin)
Definition: pad.h:416
const VECTOR2I & GetSize() const
Definition: pad.h:257
opt_bool thermals
Definition: eagle_parser.h:703
wxString name
Definition: eagle_parser.h:699
double mvStopFrame
solderpaste mask, expressed as percentage of the smaller pad/via dimension
Definition: eagle_plugin.h:91
int mlMinStopFrame
solder mask, minimum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:95
int mlMaxStopFrame
solder mask, maximum size (Eagle mils, here nanometers)
Definition: eagle_plugin.h:96

References eagleClamp(), FULL, FOOTPRINT::GetOrientation(), PAD::GetParent(), FOOTPRINT::GetPosition(), PAD::GetSize(), kicad_x(), kicad_y(), m_rules, ERULES::mlMaxStopFrame, ERULES::mlMinStopFrame, ERULES::mvStopFrame, EPAD_COMMON::name, RotatePoint(), PAD::SetLocalSolderMaskMargin(), PAD::SetNumber(), PAD::SetPos0(), PAD::SetPosition(), PAD::SetZoneConnection(), EPAD_COMMON::thermals, EPAD_COMMON::x, VECTOR2< T >::x, EPAD_COMMON::y, and VECTOR2< T >::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 341 of file eagle_plugin.h.

Referenced by centerBoard(), init(), Load(), loadClasses(), loadElements(), loadLayerDefs(), loadPlain(), loadPolygon(), loadSignals(), makeFootprint(), and packagePad().

◆ m_classMap

std::map<wxString, std::shared_ptr<NETCLASS> > EAGLE_PLUGIN::m_classMap
private

Definition at line 323 of file eagle_plugin.h.

Referenced by loadClasses(), and loadSignals().

◆ m_cu_map

int EAGLE_PLUGIN::m_cu_map[17]
private

map eagle to KiCad, cu layers only.

Definition at line 317 of file eagle_plugin.h.

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

◆ m_customRules

wxString EAGLE_PLUGIN::m_customRules
private

Definition at line 325 of file eagle_plugin.h.

Referenced by Load(), and loadClasses().

◆ m_doneCount

unsigned EAGLE_PLUGIN::m_doneCount
private

Definition at line 344 of file eagle_plugin.h.

Referenced by checkpoint(), and loadAllSections().

◆ m_eagleLayers

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

Eagle layer data stored by layer number.

Definition at line 318 of file eagle_plugin.h.

Referenced by eagle_layer_name(), loadLayerDefs(), and mapEagleLayersToKicad().

◆ m_eagleLayersIds

std::map<wxString, int> EAGLE_PLUGIN::m_eagleLayersIds
private

Eagle layer ids stored by layer name.

Definition at line 319 of file eagle_plugin.h.

Referenced by eagle_layer_id(), and loadLayerDefs().

◆ m_hole_count

int EAGLE_PLUGIN::m_hole_count
private

generates unique footprint names from eagle "hole"s.

Definition at line 331 of file eagle_plugin.h.

Referenced by init(), and loadPlain().

◆ m_lastProgressCount

unsigned EAGLE_PLUGIN::m_lastProgressCount
private

Definition at line 345 of file eagle_plugin.h.

Referenced by checkpoint().

◆ m_layer_map

std::map<wxString, PCB_LAYER_ID> EAGLE_PLUGIN::m_layer_map
private

Map of Eagle layers to KiCad layers.

Eagle class number to KiCad netclass

Definition at line 320 of file eagle_plugin.h.

Referenced by getMinimumCopperLayerCount(), kicad_layer(), and mapEagleLayersToKicad().

◆ m_layer_mapping_handler

LAYER_MAPPING_HANDLER LAYER_REMAPPABLE_PLUGIN::m_layer_mapping_handler
protectedinherited

◆ m_lib_path

wxString EAGLE_PLUGIN::m_lib_path
private

Definition at line 353 of file eagle_plugin.h.

Referenced by cacheLib(), and loadLibrary().

◆ m_min_annulus

int EAGLE_PLUGIN::m_min_annulus
private

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

Definition at line 351 of file eagle_plugin.h.

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

◆ m_min_hole

int EAGLE_PLUGIN::m_min_hole
private

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

Definition at line 349 of file eagle_plugin.h.

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

◆ m_min_trace

int EAGLE_PLUGIN::m_min_trace
private

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

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

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

◆ m_mod_time

wxDateTime EAGLE_PLUGIN::m_mod_time
private

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

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

◆ m_progressReporter

PROGRESS_REPORTER* EAGLE_PLUGIN::m_progressReporter
private

optional; may be nullptr

Definition at line 343 of file eagle_plugin.h.

Referenced by checkpoint(), Load(), loadAllSections(), and mapEagleLayersToKicad().

◆ m_props

const STRING_UTF8_MAP* EAGLE_PLUGIN::m_props
private

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

Definition at line 340 of file eagle_plugin.h.

Referenced by centerBoard(), and init().

◆ m_rules

ERULES* EAGLE_PLUGIN::m_rules
private

Eagle design rules.

Definition at line 327 of file eagle_plugin.h.

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

◆ m_templates

FOOTPRINT_MAP EAGLE_PLUGIN::m_templates
private

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

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

Definition at line 335 of file eagle_plugin.h.

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

◆ m_totalCount

unsigned EAGLE_PLUGIN::m_totalCount
private

for progress reporting

Definition at line 346 of file eagle_plugin.h.

Referenced by checkpoint(), and loadAllSections().

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

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


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