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