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 bool aIncludeUnspecified, bool aIncludeDNP )
274{
275 // Reference Designator
276 std::string crefdes = TO_UTF8( aFootprint->Reference().GetShownText( false ) );
277
278 wxString libraryName = aFootprint->GetFPID().GetLibNickname();
279 wxString footprintBasePath = wxEmptyString;
280
281 if( aPcb->GetProject() )
282 {
283 const FP_LIB_TABLE_ROW* fpRow = nullptr;
284
285 try
286 {
287 fpRow = PROJECT_PCB::PcbFootprintLibs( aPcb->GetProject() )->FindRow( libraryName, false );
288 }
289 catch( ... )
290 {
291 // Not found: do nothing
292 }
293
294 if( fpRow )
295 footprintBasePath = fpRow->GetFullURI( true );
296 }
297
298 if( crefdes.empty() || !crefdes.compare( "~" ) )
299 {
300 std::string cvalue = TO_UTF8( aFootprint->Value().GetShownText( false ) );
301
302 // if both the RefDes and Value are empty or set to '~' the board owns the part,
303 // otherwise associated parts of the footprint must be marked NOREFDES.
304 if( cvalue.empty() || !cvalue.compare( "~" ) )
305 crefdes = "BOARD";
306 else
307 crefdes = "NOREFDES";
308 }
309
310 // TODO: If footprint cutouts are supported we must add code here
311 // for( EDA_ITEM* item = aFootprint->GraphicalItems(); item != NULL; item = item->Next() )
312 // {
313 // if( item->Type() != PCB_SHAPE_T || item->GetLayer() != Edge_Cuts )
314 // continue;
315 // code to export cutouts
316 // }
317
318 // Export pads
319 double drill, x, y;
320 double scale = aIDFBoard.GetUserScale();
321 IDF3::KEY_PLATING kplate;
322 std::string pintype;
323 std::string tstr;
324
325 double dx, dy;
326
327 aIDFBoard.GetUserOffset( dx, dy );
328
329 for( auto pad : aFootprint->Pads() )
330 {
331 drill = (double) pad->GetDrillSize().x * scale;
332 x = pad->GetPosition().x * scale + dx;
333 y = -pad->GetPosition().y * scale + dy;
334
335 // Export the hole on the edge layer
336 if( drill > 0.0 )
337 {
338 // plating
339 if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
340 kplate = IDF3::NPTH;
341 else
342 kplate = IDF3::PTH;
343
344 // hole type
345 tstr = TO_UTF8( pad->GetNumber() );
346
347 if( tstr.empty() || !tstr.compare( "0" ) || !tstr.compare( "~" )
348 || ( kplate == IDF3::NPTH )
349 || ( pad->GetDrillShape() == PAD_DRILL_SHAPE::OBLONG ) )
350 pintype = "MTG";
351 else
352 pintype = "PIN";
353
354 // fields:
355 // 1. hole dia. : float
356 // 2. X coord : float
357 // 3. Y coord : float
358 // 4. plating : PTH | NPTH
359 // 5. Assoc. part : BOARD | NOREFDES | PANEL | {"refdes"}
360 // 6. type : PIN | VIA | MTG | TOOL | { "other" }
361 // 7. owner : MCAD | ECAD | UNOWNED
362 if( ( pad->GetDrillShape() == PAD_DRILL_SHAPE::OBLONG )
363 && ( pad->GetDrillSize().x != pad->GetDrillSize().y ) )
364 {
365 // NOTE: IDF does not have direct support for slots;
366 // slots are implemented as a board cutout and we
367 // cannot represent plating or reference designators
368
369 double dlength = pad->GetDrillSize().y * scale;
370
371 // NOTE: The orientation of footprints and pads have
372 // the opposite sense due to KiCad drawing on a
373 // screen with a LH coordinate system
374 double angle = pad->GetOrientation().AsDegrees();
375
376 // NOTE: Since this code assumes the scenario where
377 // GetDrillSize().y is the length but idf_parser.cpp
378 // assumes a length along the X axis, the orientation
379 // must be shifted +90 deg when GetDrillSize().y is
380 // the major axis.
381
382 if( dlength < drill )
383 {
384 std::swap( drill, dlength );
385 }
386 else
387 {
388 angle += 90.0;
389 }
390
391 // NOTE: KiCad measures a slot's length from end to end
392 // rather than between the centers of the arcs
393 dlength -= drill;
394
395 aIDFBoard.AddSlot( drill, dlength, angle, x, y );
396 }
397 else
398 {
399 IDF_DRILL_DATA *dp = new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
400 pintype, IDF3::ECAD );
401
402 if( !aIDFBoard.AddDrill( dp ) )
403 {
404 delete dp;
405
406 std::ostringstream ostr;
407 ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__;
408 ostr << "(): could not add drill";
409
410 throw std::runtime_error( ostr.str() );
411 }
412 }
413 }
414 }
415
416 if( ( !(aFootprint->GetAttributes() & (FP_THROUGH_HOLE|FP_SMD)) ) && !aIncludeUnspecified )
417 return;
418
419 if( aFootprint->IsDNP() && !aIncludeDNP )
420 return;
421
422 // add any valid models to the library item list
423 std::string refdes;
424
425 IDF3_COMPONENT* comp = nullptr;
426
427 auto sM = aFootprint->Models().begin();
428 auto eM = aFootprint->Models().end();
429 wxFileName idfFile;
430 wxString idfExt;
431
432 while( sM != eM )
433 {
434 if( !sM->m_Show )
435 {
436 ++sM;
437 continue;
438 }
439
440 idfFile.Assign( resolver->ResolvePath( sM->m_Filename, footprintBasePath, aFootprint ) );
441 idfExt = idfFile.GetExt();
442
443 if( idfExt.Cmp( wxT( "idf" ) ) && idfExt.Cmp( wxT( "IDF" ) ) )
444 {
445 ++sM;
446 continue;
447 }
448
449 if( refdes.empty() )
450 {
451 refdes = TO_UTF8( aFootprint->Reference().GetShownText( false ) );
452
453 // NOREFDES cannot be used or else the software gets confused
454 // when writing out the placement data due to conflicting
455 // placement and layer specifications; to work around this we
456 // create a (hopefully) unique refdes for our exported part.
457 if( refdes.empty() || !refdes.compare( "~" ) )
458 refdes = aIDFBoard.GetNewRefDes();
459 }
460
461 IDF3_COMP_OUTLINE* outline;
462
463 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
464
465 if( !outline )
466 throw( std::runtime_error( aIDFBoard.GetError() ) );
467
468 double rotz = aFootprint->GetOrientation().AsDegrees();
469 double locx = sM->m_Offset.x; // part offsets are in mm
470 double locy = sM->m_Offset.y;
471 double locz = sM->m_Offset.z;
472 double lrot = sM->m_Rotation.z;
473
474 bool top = ( aFootprint->GetLayer() == B_Cu ) ? false : true;
475
476 if( top )
477 {
478 locy = -locy;
479 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
480 locy = -locy;
481 }
482
483 if( !top )
484 {
485 lrot = -lrot;
486 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
487 locy = -locy;
488
489 rotz = 180.0 - rotz;
490
491 if( rotz >= 360.0 )
492 while( rotz >= 360.0 ) rotz -= 360.0;
493
494 if( rotz <= -360.0 )
495 while( rotz <= -360.0 ) rotz += 360.0;
496 }
497
498 if( comp == nullptr )
499 comp = aIDFBoard.FindComponent( refdes );
500
501 if( comp == nullptr )
502 {
503 comp = new IDF3_COMPONENT( &aIDFBoard );
504
505 if( comp == nullptr )
506 throw( std::runtime_error( aIDFBoard.GetError() ) );
507
508 comp->SetRefDes( refdes );
509
510 if( top )
511 {
512 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
513 -aFootprint->GetPosition().y * scale + dy,
514 rotz, IDF3::LYR_TOP );
515 }
516 else
517 {
518 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
519 -aFootprint->GetPosition().y * scale + dy,
520 rotz, IDF3::LYR_BOTTOM );
521 }
522
523 comp->SetPlacement( IDF3::PS_ECAD );
524
525 aIDFBoard.AddComponent( comp );
526 }
527 else
528 {
529 double refX, refY, refA;
530 IDF3::IDF_LAYER side;
531
532 if( ! comp->GetPosition( refX, refY, refA, side ) )
533 {
534 // place the item
535 if( top )
536 {
537 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
538 -aFootprint->GetPosition().y * scale + dy,
539 rotz, IDF3::LYR_TOP );
540 }
541 else
542 {
543 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
544 -aFootprint->GetPosition().y * scale + dy,
545 rotz, IDF3::LYR_BOTTOM );
546 }
547
548 comp->SetPlacement( IDF3::PS_ECAD );
549
550 }
551 else
552 {
553 // check that the retrieved component matches this one
554 refX = refX - ( aFootprint->GetPosition().x * scale + dx );
555 refY = refY - ( -aFootprint->GetPosition().y * scale + dy );
556 refA = refA - rotz;
557 refA *= refA;
558 refX *= refX;
559 refY *= refY;
560 refX += refY;
561
562 // conditions: same side, X,Y coordinates within 10 microns,
563 // angle within 0.01 degree
564 if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
565 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
566 {
567 comp->GetPosition( refX, refY, refA, side );
568
569 std::ostringstream ostr;
570 ostr << "* " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
571 ostr << "* conflicting Reference Designator '" << refdes << "'\n";
572 ostr << "* X loc: " << ( aFootprint->GetPosition().x * scale + dx);
573 ostr << " vs. " << refX << "\n";
574 ostr << "* Y loc: " << ( -aFootprint->GetPosition().y * scale + dy);
575 ostr << " vs. " << refY << "\n";
576 ostr << "* angle: " << rotz;
577 ostr << " vs. " << refA << "\n";
578
579 if( top )
580 ostr << "* TOP vs. ";
581 else
582 ostr << "* BOTTOM vs. ";
583
584 if( side == IDF3::LYR_TOP )
585 ostr << "TOP";
586 else
587 ostr << "BOTTOM";
588
589 throw( std::runtime_error( ostr.str() ) );
590 }
591 }
592 }
593
594 // create the local data ...
595 IDF3_COMP_OUTLINE_DATA* data = new IDF3_COMP_OUTLINE_DATA( comp, outline );
596
597 data->SetOffsets( locx, locy, locz, lrot );
598 comp->AddOutlineData( data );
599 ++sM;
600 }
601}
602
603
608bool PCB_EDIT_FRAME::Export_IDF3( BOARD* aPcb, const wxString& aFullFileName,
609 bool aUseThou, double aXRef, double aYRef,
610 bool aIncludeUnspecified, bool aIncludeDNP )
611{
612 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
613
614 // Switch the locale to standard C (needed to print floating point numbers)
615 LOCALE_IO toggle;
616
618
619 bool ok = true;
620 double scale = pcbIUScale.MM_PER_IU; // we must scale internal units to mm for IDF
621 IDF3::IDF_UNIT idfUnit;
622
623 if( aUseThou )
624 {
625 idfUnit = IDF3::UNIT_THOU;
626 idfBoard.SetUserPrecision( 1 );
627 }
628 else
629 {
630 idfUnit = IDF3::UNIT_MM;
631 idfBoard.SetUserPrecision( 5 );
632 }
633
634 wxFileName brdName = aPcb->GetFileName();
635
636 idfBoard.SetUserScale( scale );
637 idfBoard.SetBoardThickness( aPcb->GetDesignSettings().GetBoardThickness() * scale );
638 idfBoard.SetBoardName( TO_UTF8( brdName.GetFullName() ) );
639 idfBoard.SetBoardVersion( 0 );
640 idfBoard.SetLibraryVersion( 0 );
641
642 std::ostringstream ostr;
643 ostr << "KiCad " << TO_UTF8( GetBuildVersion() );
644 idfBoard.SetIDFSource( ostr.str() );
645
646 try
647 {
648 // set up the board reference point
649 idfBoard.SetUserOffset( -aXRef, aYRef );
650
651 // Export the board outline
652 idf_export_outline( aPcb, idfBoard );
653
654 // Output the drill holes and footprint (library) data.
655 for( FOOTPRINT* footprint : aPcb->Footprints() )
656 idf_export_footprint( aPcb, footprint, idfBoard, aIncludeUnspecified, aIncludeDNP );
657
658 if( !idfBoard.WriteFile( aFullFileName, idfUnit, false ) )
659 {
660 wxString msg;
661 msg << _( "IDF Export Failed:\n" ) << From_UTF8( idfBoard.GetError().c_str() );
662 wxMessageBox( msg );
663
664 ok = false;
665 }
666 }
667 catch( const IO_ERROR& ioe )
668 {
669 wxString msg;
670 msg << _( "IDF Export Failed:\n" ) << ioe.What();
671 wxMessageBox( msg );
672
673 ok = false;
674 }
675 catch( const std::exception& e )
676 {
677 wxString msg;
678 msg << _( "IDF Export Failed:\n" ) << From_UTF8( e.what() );
679 wxMessageBox( msg );
680 ok = false;
681 }
682
683 return ok;
684}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
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:79
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:290
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
Definition: board.h:929
const FOOTPRINTS & Footprints() const
Definition: board.h:331
const wxString & GetFileName() const
Definition: board.h:327
PROJECT * GetProject() const
Definition: board.h:491
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:892
const DRAWINGS & Drawings() const
Definition: board.h:333
constexpr const Vec & GetOrigin() const
Definition: box2.h:210
constexpr const SizeVec & GetSize() const
Definition: box2.h:206
double AsDegrees() const
Definition: eda_angle.h:113
EDA_ANGLE GetArcAngle() const
Definition: eda_shape.cpp:645
int GetRadius() const
Definition: eda_shape.cpp:575
SHAPE_T GetShape() const
Definition: eda_shape.h:125
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:167
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:130
Provide an extensible class to resolve 3D model paths.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath, const EMBEDDED_FILES *aFiles)
Determines the full path of the given file name.
bool IsDNP() const
Definition: footprint.h:768
EDA_ANGLE GetOrientation() const
Definition: footprint.h:227
PCB_FIELD & Value()
read/write accessors:
Definition: footprint.h:638
std::deque< PAD * > & Pads()
Definition: footprint.h:206
int GetAttributes() const
Definition: footprint.h:290
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: footprint.h:236
const LIB_ID & GetFPID() const
Definition: footprint.h:248
PCB_FIELD & Reference()
Definition: footprint.h:639
std::vector< FP_3DMODEL > & Models()
Definition: footprint.h:220
VECTOR2I GetPosition() const override
Definition: footprint.h:224
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, bool aIncludeUnspecified, bool aIncludeDNP)
Create an IDF3 compliant BOARD (*.emn) and LIBRARY (*.emp) file.
Definition: export_idf.cpp:608
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:79
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:186
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:511
#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 FILENAME_RESOLVER * resolver
Definition: export_idf.cpp:53
static void idf_export_footprint(BOARD *aPcb, FOOTPRINT *aFootprint, IDF3_BOARD &aIDFBoard, bool aIncludeUnspecified, bool aIncludeDNP)
Retrieve information from all board footprints, adds drill holes to the DRILLED_HOLES or BOARD_OUTLIN...
Definition: export_idf.cpp:272
@ FP_SMD
Definition: footprint.h:76
@ FP_THROUGH_HOLE
Definition: footprint.h:75
PROJECT & Prj()
Definition: kicad.cpp:595
@ Edge_Cuts
Definition: layer_ids.h:112
@ B_Cu
Definition: layer_ids.h:65
This file contains miscellaneous commonly used macros and functions.
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
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:398
const double MM_PER_IU
Definition: base_units.h:78
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:229
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88