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