KiCad PCB EDA Suite
export_idf.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2013 Cirilo Bernardo
5 * Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25
26#include <list>
27#include <locale_io.h>
28#include <macros.h>
29#include <pcb_edit_frame.h>
30#include <board.h>
32#include <footprint.h>
33#include <fp_lib_table.h>
34#include <fp_shape.h>
35#include <idf_parser.h>
36#include <pad.h>
37#include <build_version.h>
38#include <wx/msgdlg.h>
39#include "project.h"
40#include "kiway.h"
41#include "3d_cache/3d_cache.h"
42#include "filename_resolver.h"
43
44
45#include <base_units.h> // to define pcbIUScale.FromMillimeter(x)
46
47
48// assumed default graphical line thickness: == 0.1mm
49#define LINE_WIDTH (pcbIUScale.mmToIU( 0.1 ))
50
51
53
54
59static void idf_export_outline( BOARD* aPcb, IDF3_BOARD& aIDFBoard )
60{
61 double scale = aIDFBoard.GetUserScale();
62
63 PCB_SHAPE* graphic; // KiCad graphical item
64 IDF_POINT sp, ep; // start and end points from KiCad item
65
66 std::list< IDF_SEGMENT* > lines; // IDF intermediate form of KiCad graphical item
67 IDF_OUTLINE* outline = nullptr; // graphical items forming an outline or cutout
68
69 // NOTE: IMPLEMENTATION
70 // If/when component cutouts are allowed, we must implement them separately. Cutouts
71 // must be added to the board outline section and not to the Other Outline section.
72 // The footprint cutouts should be handled via the idf_export_footprint() routine.
73
74 double offX, offY;
75 aIDFBoard.GetUserOffset( offX, offY );
76
77 // Retrieve segments and arcs from the board
78 for( BOARD_ITEM* item : aPcb->Drawings() )
79 {
80 if( item->Type() != PCB_SHAPE_T || item->GetLayer() != Edge_Cuts )
81 continue;
82
83 graphic = (PCB_SHAPE*) item;
84
85 switch( graphic->GetShape() )
86 {
88 {
89 if( graphic->GetStart() == graphic->GetEnd() )
90 break;
91
92 sp.x = graphic->GetStart().x * scale + offX;
93 sp.y = -graphic->GetStart().y * scale + offY;
94 ep.x = graphic->GetEnd().x * scale + offX;
95 ep.y = -graphic->GetEnd().y * scale + offY;
96 IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep );
97
98 if( seg )
99 lines.push_back( seg );
100
101 break;
102 }
103
104 case SHAPE_T::RECT:
105 {
106 if( graphic->GetStart() == graphic->GetEnd() )
107 break;
108
109 double top = graphic->GetStart().y * scale + offY;
110 double left = graphic->GetStart().x * scale + offX;
111 double bottom = graphic->GetEnd().y * scale + offY;
112 double right = graphic->GetEnd().x * scale + offX;
113
114 IDF_POINT corners[4];
115 corners[0] = IDF_POINT( left, top );
116 corners[1] = IDF_POINT( right, top );
117 corners[2] = IDF_POINT( right, bottom );
118 corners[3] = IDF_POINT( left, bottom );
119
120 lines.push_back( new IDF_SEGMENT( corners[0], corners[1] ) );
121 lines.push_back( new IDF_SEGMENT( corners[1], corners[2] ) );
122 lines.push_back( new IDF_SEGMENT( corners[2], corners[3] ) );
123 lines.push_back( new IDF_SEGMENT( corners[3], corners[0] ) );
124 break;
125 }
126
127 case SHAPE_T::ARC:
128 {
129 if( graphic->GetCenter() == graphic->GetStart() )
130 break;
131
132 sp.x = graphic->GetCenter().x * scale + offX;
133 sp.y = -graphic->GetCenter().y * scale + offY;
134 ep.x = graphic->GetStart().x * scale + offX;
135 ep.y = -graphic->GetStart().y * scale + offY;
136 IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep, -graphic->GetArcAngle().AsDegrees(), true );
137
138 if( seg )
139 lines.push_back( seg );
140
141 break;
142 }
143
144 case SHAPE_T::CIRCLE:
145 {
146 if( graphic->GetRadius() == 0 )
147 break;
148
149 sp.x = graphic->GetCenter().x * scale + offX;
150 sp.y = -graphic->GetCenter().y * scale + offY;
151 ep.x = sp.x - graphic->GetRadius() * scale;
152 ep.y = sp.y;
153
154 // Circles must always have an angle of +360 deg. to appease
155 // quirky MCAD implementations of IDF.
156 IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep, 360.0, true );
157
158 if( seg )
159 lines.push_back( seg );
160
161 break;
162 }
163
164 default:
165 break;
166 }
167 }
168
169 // if there is no outline then use the bounding box
170 if( lines.empty() )
171 {
172 goto UseBoundingBox;
173 }
174
175 // get the board outline and write it out
176 // note: we do not use a try/catch block here since we intend
177 // to simply ignore unclosed loops and continue processing
178 // until we're out of segments to process
179 outline = new IDF_OUTLINE;
180 IDF3::GetOutline( lines, *outline );
181
182 if( outline->empty() )
183 goto UseBoundingBox;
184
185 aIDFBoard.AddBoardOutline( outline );
186 outline = nullptr;
187
188 // get all cutouts and write them out
189 while( !lines.empty() )
190 {
191 if( !outline )
192 outline = new IDF_OUTLINE;
193
194 IDF3::GetOutline( lines, *outline );
195
196 if( outline->empty() )
197 {
198 outline->Clear();
199 continue;
200 }
201
202 aIDFBoard.AddBoardOutline( outline );
203 outline = nullptr;
204 }
205
206 return;
207
208UseBoundingBox:
209
210 // clean up if necessary
211 while( !lines.empty() )
212 {
213 delete lines.front();
214 lines.pop_front();
215 }
216
217 if( outline )
218 outline->Clear();
219 else
220 outline = new IDF_OUTLINE;
221
222 // Fetch a rectangular bounding box for the board; there is always some uncertainty in the
223 // board dimensions computed via ComputeBoundingBox() since this depends on the individual
224 // footprint entities.
225 BOX2I bbbox = aPcb->GetBoardEdgesBoundingBox();
226
227 // convert to mm and compensate for an assumed LINE_WIDTH line thickness
228 double x = ( bbbox.GetOrigin().x + LINE_WIDTH / 2 ) * scale + offX;
229 double y = ( bbbox.GetOrigin().y + LINE_WIDTH / 2 ) * scale + offY;
230 double dx = ( bbbox.GetSize().x - LINE_WIDTH ) * scale;
231 double dy = ( bbbox.GetSize().y - LINE_WIDTH ) * scale;
232
233 double px[4], py[4];
234 px[0] = x;
235 py[0] = y;
236
237 px[1] = x;
238 py[1] = y + dy;
239
240 px[2] = x + dx;
241 py[2] = y + dy;
242
243 px[3] = x + dx;
244 py[3] = y;
245
246 IDF_POINT p1, p2;
247
248 p1.x = px[3];
249 p1.y = py[3];
250 p2.x = px[0];
251 p2.y = py[0];
252
253 outline->push( new IDF_SEGMENT( p1, p2 ) );
254
255 for( int i = 1; i < 4; ++i )
256 {
257 p1.x = px[i - 1];
258 p1.y = py[i - 1];
259 p2.x = px[i];
260 p2.y = py[i];
261
262 outline->push( new IDF_SEGMENT( p1, p2 ) );
263 }
264
265 aIDFBoard.AddBoardOutline( outline );
266}
267
268
274static void idf_export_footprint( BOARD* aPcb, FOOTPRINT* aFootprint, IDF3_BOARD& aIDFBoard )
275{
276 // Reference Designator
277 std::string crefdes = TO_UTF8( aFootprint->Reference().GetShownText() );
278
279 wxString libraryName = aFootprint->GetFPID().GetLibNickname();
280 wxString footprintBasePath = wxEmptyString;
281
282 if( aPcb->GetProject() )
283 {
284 const FP_LIB_TABLE_ROW* fpRow =
285 aPcb->GetProject()->PcbFootprintLibs()->FindRow( libraryName, false );
286
287 if( fpRow )
288 footprintBasePath = fpRow->GetFullURI( true );
289 }
290
291 if( crefdes.empty() || !crefdes.compare( "~" ) )
292 {
293 std::string cvalue = TO_UTF8( aFootprint->Value().GetShownText() );
294
295 // if both the RefDes and Value are empty or set to '~' the board owns the part,
296 // otherwise associated parts of the footprint must be marked NOREFDES.
297 if( cvalue.empty() || !cvalue.compare( "~" ) )
298 crefdes = "BOARD";
299 else
300 crefdes = "NOREFDES";
301 }
302
303 // TODO: If footprint cutouts are supported we must add code here
304 // for( EDA_ITEM* item = aFootprint->GraphicalItems(); item != NULL; item = item->Next() )
305 // {
306 // if( item->Type() != PCB_FP_SHAPE_T || item->GetLayer() != Edge_Cuts )
307 // continue;
308 // code to export cutouts
309 // }
310
311 // Export pads
312 double drill, x, y;
313 double scale = aIDFBoard.GetUserScale();
314 IDF3::KEY_PLATING kplate;
315 std::string pintype;
316 std::string tstr;
317
318 double dx, dy;
319
320 aIDFBoard.GetUserOffset( dx, dy );
321
322 for( auto pad : aFootprint->Pads() )
323 {
324 drill = (double) pad->GetDrillSize().x * scale;
325 x = pad->GetPosition().x * scale + dx;
326 y = -pad->GetPosition().y * scale + dy;
327
328 // Export the hole on the edge layer
329 if( drill > 0.0 )
330 {
331 // plating
332 if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
333 kplate = IDF3::NPTH;
334 else
335 kplate = IDF3::PTH;
336
337 // hole type
338 tstr = TO_UTF8( pad->GetNumber() );
339
340 if( tstr.empty() || !tstr.compare( "0" ) || !tstr.compare( "~" )
341 || ( kplate == IDF3::NPTH )
342 || ( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ) )
343 pintype = "MTG";
344 else
345 pintype = "PIN";
346
347 // fields:
348 // 1. hole dia. : float
349 // 2. X coord : float
350 // 3. Y coord : float
351 // 4. plating : PTH | NPTH
352 // 5. Assoc. part : BOARD | NOREFDES | PANEL | {"refdes"}
353 // 6. type : PIN | VIA | MTG | TOOL | { "other" }
354 // 7. owner : MCAD | ECAD | UNOWNED
355 if( ( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
356 && ( pad->GetDrillSize().x != pad->GetDrillSize().y ) )
357 {
358 // NOTE: IDF does not have direct support for slots;
359 // slots are implemented as a board cutout and we
360 // cannot represent plating or reference designators
361
362 double dlength = pad->GetDrillSize().y * scale;
363
364 // NOTE: The orientation of footprints and pads have
365 // the opposite sense due to KiCad drawing on a
366 // screen with a LH coordinate system
367 double angle = pad->GetOrientation().AsDegrees();
368
369 // NOTE: Since this code assumes the scenario where
370 // GetDrillSize().y is the length but idf_parser.cpp
371 // assumes a length along the X axis, the orientation
372 // must be shifted +90 deg when GetDrillSize().y is
373 // the major axis.
374
375 if( dlength < drill )
376 {
377 std::swap( drill, dlength );
378 }
379 else
380 {
381 angle += 90.0;
382 }
383
384 // NOTE: KiCad measures a slot's length from end to end
385 // rather than between the centers of the arcs
386 dlength -= drill;
387
388 aIDFBoard.AddSlot( drill, dlength, angle, x, y );
389 }
390 else
391 {
392 IDF_DRILL_DATA *dp = new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
393 pintype, IDF3::ECAD );
394
395 if( !aIDFBoard.AddDrill( dp ) )
396 {
397 delete dp;
398
399 std::ostringstream ostr;
400 ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__;
401 ostr << "(): could not add drill";
402
403 throw std::runtime_error( ostr.str() );
404 }
405 }
406 }
407 }
408
409 // add any valid models to the library item list
410 std::string refdes;
411
412 IDF3_COMPONENT* comp = nullptr;
413
414 auto sM = aFootprint->Models().begin();
415 auto eM = aFootprint->Models().end();
416 wxFileName idfFile;
417 wxString idfExt;
418
419 while( sM != eM )
420 {
421 if( !sM->m_Show )
422 {
423 ++sM;
424 continue;
425 }
426
427 idfFile.Assign( resolver->ResolvePath( sM->m_Filename, footprintBasePath ) );
428 idfExt = idfFile.GetExt();
429
430 if( idfExt.Cmp( wxT( "idf" ) ) && idfExt.Cmp( wxT( "IDF" ) ) )
431 {
432 ++sM;
433 continue;
434 }
435
436 if( refdes.empty() )
437 {
438 refdes = TO_UTF8( aFootprint->Reference().GetShownText() );
439
440 // NOREFDES cannot be used or else the software gets confused
441 // when writing out the placement data due to conflicting
442 // placement and layer specifications; to work around this we
443 // create a (hopefully) unique refdes for our exported part.
444 if( refdes.empty() || !refdes.compare( "~" ) )
445 refdes = aIDFBoard.GetNewRefDes();
446 }
447
448 IDF3_COMP_OUTLINE* outline;
449
450 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
451
452 if( !outline )
453 throw( std::runtime_error( aIDFBoard.GetError() ) );
454
455 double rotz = aFootprint->GetOrientation().AsDegrees();
456 double locx = sM->m_Offset.x * 25.4; // part offsets are in inches
457 double locy = sM->m_Offset.y * 25.4;
458 double locz = sM->m_Offset.z * 25.4;
459 double lrot = sM->m_Rotation.z;
460
461 bool top = ( aFootprint->GetLayer() == B_Cu ) ? false : true;
462
463 if( top )
464 {
465 locy = -locy;
466 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
467 locy = -locy;
468 }
469
470 if( !top )
471 {
472 lrot = -lrot;
473 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
474 locy = -locy;
475
476 rotz = 180.0 - rotz;
477
478 if( rotz >= 360.0 )
479 while( rotz >= 360.0 ) rotz -= 360.0;
480
481 if( rotz <= -360.0 )
482 while( rotz <= -360.0 ) rotz += 360.0;
483 }
484
485 if( comp == nullptr )
486 comp = aIDFBoard.FindComponent( refdes );
487
488 if( comp == nullptr )
489 {
490 comp = new IDF3_COMPONENT( &aIDFBoard );
491
492 if( comp == nullptr )
493 throw( std::runtime_error( aIDFBoard.GetError() ) );
494
495 comp->SetRefDes( refdes );
496
497 if( top )
498 {
499 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
500 -aFootprint->GetPosition().y * scale + dy,
501 rotz, IDF3::LYR_TOP );
502 }
503 else
504 {
505 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
506 -aFootprint->GetPosition().y * scale + dy,
507 rotz, IDF3::LYR_BOTTOM );
508 }
509
510 comp->SetPlacement( IDF3::PS_ECAD );
511
512 aIDFBoard.AddComponent( comp );
513 }
514 else
515 {
516 double refX, refY, refA;
517 IDF3::IDF_LAYER side;
518
519 if( ! comp->GetPosition( refX, refY, refA, side ) )
520 {
521 // place the item
522 if( top )
523 {
524 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
525 -aFootprint->GetPosition().y * scale + dy,
526 rotz, IDF3::LYR_TOP );
527 }
528 else
529 {
530 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
531 -aFootprint->GetPosition().y * scale + dy,
532 rotz, IDF3::LYR_BOTTOM );
533 }
534
535 comp->SetPlacement( IDF3::PS_ECAD );
536
537 }
538 else
539 {
540 // check that the retrieved component matches this one
541 refX = refX - ( aFootprint->GetPosition().x * scale + dx );
542 refY = refY - ( -aFootprint->GetPosition().y * scale + dy );
543 refA = refA - rotz;
544 refA *= refA;
545 refX *= refX;
546 refY *= refY;
547 refX += refY;
548
549 // conditions: same side, X,Y coordinates within 10 microns,
550 // angle within 0.01 degree
551 if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
552 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
553 {
554 comp->GetPosition( refX, refY, refA, side );
555
556 std::ostringstream ostr;
557 ostr << "* " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
558 ostr << "* conflicting Reference Designator '" << refdes << "'\n";
559 ostr << "* X loc: " << ( aFootprint->GetPosition().x * scale + dx);
560 ostr << " vs. " << refX << "\n";
561 ostr << "* Y loc: " << ( -aFootprint->GetPosition().y * scale + dy);
562 ostr << " vs. " << refY << "\n";
563 ostr << "* angle: " << rotz;
564 ostr << " vs. " << refA << "\n";
565
566 if( top )
567 ostr << "* TOP vs. ";
568 else
569 ostr << "* BOTTOM vs. ";
570
571 if( side == IDF3::LYR_TOP )
572 ostr << "TOP";
573 else
574 ostr << "BOTTOM";
575
576 throw( std::runtime_error( ostr.str() ) );
577 }
578 }
579 }
580
581 // create the local data ...
582 IDF3_COMP_OUTLINE_DATA* data = new IDF3_COMP_OUTLINE_DATA( comp, outline );
583
584 data->SetOffsets( locx, locy, locz, lrot );
585 comp->AddOutlineData( data );
586 ++sM;
587 }
588}
589
590
595bool PCB_EDIT_FRAME::Export_IDF3( BOARD* aPcb, const wxString& aFullFileName,
596 bool aUseThou, double aXRef, double aYRef )
597{
598 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
599
600 // Switch the locale to standard C (needed to print floating point numbers)
601 LOCALE_IO toggle;
602
603 resolver = Prj().Get3DCacheManager()->GetResolver();
604
605 bool ok = true;
606 double scale = pcbIUScale.MM_PER_IU; // we must scale internal units to mm for IDF
607 IDF3::IDF_UNIT idfUnit;
608
609 if( aUseThou )
610 {
611 idfUnit = IDF3::UNIT_THOU;
612 idfBoard.SetUserPrecision( 1 );
613 }
614 else
615 {
616 idfUnit = IDF3::UNIT_MM;
617 idfBoard.SetUserPrecision( 5 );
618 }
619
620 wxFileName brdName = aPcb->GetFileName();
621
622 idfBoard.SetUserScale( scale );
623 idfBoard.SetBoardThickness( aPcb->GetDesignSettings().GetBoardThickness() * scale );
624 idfBoard.SetBoardName( TO_UTF8( brdName.GetFullName() ) );
625 idfBoard.SetBoardVersion( 0 );
626 idfBoard.SetLibraryVersion( 0 );
627
628 std::ostringstream ostr;
629 ostr << "KiCad " << TO_UTF8( GetBuildVersion() );
630 idfBoard.SetIDFSource( ostr.str() );
631
632 try
633 {
634 // set up the board reference point
635 idfBoard.SetUserOffset( -aXRef, aYRef );
636
637 // Export the board outline
638 idf_export_outline( aPcb, idfBoard );
639
640 // Output the drill holes and footprint (library) data.
641 for( FOOTPRINT* footprint : aPcb->Footprints() )
642 idf_export_footprint( aPcb, footprint, idfBoard );
643
644 if( !idfBoard.WriteFile( aFullFileName, idfUnit, false ) )
645 {
646 wxString msg;
647 msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( idfBoard.GetError().c_str() );
648 wxMessageBox( msg );
649
650 ok = false;
651 }
652 }
653 catch( const IO_ERROR& ioe )
654 {
655 wxString msg;
656 msg << _( "IDF Export Failed:\n" ) << ioe.What();
657 wxMessageBox( msg );
658
659 ok = false;
660 }
661 catch( const std::exception& e )
662 {
663 wxString msg;
664 msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( e.what() );
665 wxMessageBox( msg );
666 ok = false;
667 }
668
669 return ok;
670}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
wxString GetBuildVersion()
Get the full KiCad version string.
int GetBoardThickness() const
The full thickness of the board including copper and masks.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:50
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:167
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
Definition: board.h:821
FOOTPRINTS & Footprints()
Definition: board.h:307
const wxString & GetFileName() const
Definition: board.h:302
DRAWINGS & Drawings()
Definition: board.h:310
PROJECT * GetProject() const
Definition: board.h:440
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:618
const Vec & GetOrigin() const
Definition: box2.h:183
const Vec & GetSize() const
Definition: box2.h:179
double AsDegrees() const
Definition: eda_angle.h:149
EDA_ANGLE GetArcAngle() const
Definition: eda_shape.cpp:538
int GetRadius() const
Definition: eda_shape.cpp:476
SHAPE_T GetShape() const
Definition: eda_shape.h:111
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:141
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:116
Provide an extensible class to resolve 3D model paths.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath)
Determines the full path of the given file name.
EDA_ANGLE GetOrientation() const
Definition: footprint.h:195
PADS & Pads()
Definition: footprint.h:174
const LIB_ID & GetFPID() const
Definition: footprint.h:207
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:555
std::vector< FP_3DMODEL > & Models()
Definition: footprint.h:188
VECTOR2I GetPosition() const override
Definition: footprint.h:192
FP_TEXT & Reference()
Definition: footprint.h:556
Hold a record identifying a library accessed by the appropriate footprint library PLUGIN object in th...
Definition: fp_lib_table.h:41
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an FP_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back table frag...
virtual wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: fp_text.cpp:412
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
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
bool Export_IDF3(BOARD *aPcb, const wxString &aFullFileName, bool aUseThou, double aXRef, double aYRef)
Create an IDF3 compliant BOARD (*.emn) and LIBRARY (*.emp) file.
Definition: export_idf.cpp:595
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:65
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:318
#define _(s)
static void idf_export_outline(BOARD *aPcb, IDF3_BOARD &aIDFBoard)
Retrieve line segment information from the edge layer and compiles the data into a form which can be ...
Definition: export_idf.cpp:59
#define LINE_WIDTH
Definition: export_idf.cpp:49
static void idf_export_footprint(BOARD *aPcb, FOOTPRINT *aFootprint, IDF3_BOARD &aIDFBoard)
Retrieve information from all board footprints, adds drill holes to the DRILLED_HOLES or BOARD_OUTLIN...
Definition: export_idf.cpp:274
static FILENAME_RESOLVER * resolver
Definition: export_idf.cpp:52
@ Edge_Cuts
Definition: layer_ids.h:113
@ B_Cu
Definition: layer_ids.h:95
This file contains miscellaneous commonly used macros and functions.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
@ NPTH
like PAD_PTH, but not plated
@ PAD_DRILL_SHAPE_OBLONG
Definition: pad_shapes.h:71
const int scale
const double MM_PER_IU
Definition: base_units.h:79
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
#define UNIT_MM
Definition: units_scales.h:34