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 The 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 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
441 embeddedFilesStack.push_back( aFootprint->GetEmbeddedFiles() );
442 embeddedFilesStack.push_back( aPcb->GetEmbeddedFiles() );
443
444 idfFile.Assign( resolver->ResolvePath( sM->m_Filename, footprintBasePath, std::move( embeddedFilesStack ) ) );
445 idfExt = idfFile.GetExt();
446
447 if( idfExt.Cmp( wxT( "idf" ) ) && idfExt.Cmp( wxT( "IDF" ) ) )
448 {
449 ++sM;
450 continue;
451 }
452
453 if( refdes.empty() )
454 {
455 refdes = TO_UTF8( aFootprint->Reference().GetShownText( false ) );
456
457 // NOREFDES cannot be used or else the software gets confused
458 // when writing out the placement data due to conflicting
459 // placement and layer specifications; to work around this we
460 // create a (hopefully) unique refdes for our exported part.
461 if( refdes.empty() || !refdes.compare( "~" ) )
462 refdes = aIDFBoard.GetNewRefDes();
463 }
464
465 IDF3_COMP_OUTLINE* outline;
466
467 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
468
469 if( !outline )
470 throw( std::runtime_error( aIDFBoard.GetError() ) );
471
472 double rotz = aFootprint->GetOrientation().AsDegrees();
473 double locx = sM->m_Offset.x; // part offsets are in mm
474 double locy = sM->m_Offset.y;
475 double locz = sM->m_Offset.z;
476 double lrot = sM->m_Rotation.z;
477
478 bool top = ( aFootprint->GetLayer() == B_Cu ) ? false : true;
479
480 if( top )
481 {
482 locy = -locy;
483 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
484 locy = -locy;
485 }
486
487 if( !top )
488 {
489 lrot = -lrot;
490 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
491 locy = -locy;
492
493 rotz = 180.0 - rotz;
494
495 if( rotz >= 360.0 )
496 while( rotz >= 360.0 ) rotz -= 360.0;
497
498 if( rotz <= -360.0 )
499 while( rotz <= -360.0 ) rotz += 360.0;
500 }
501
502 if( comp == nullptr )
503 comp = aIDFBoard.FindComponent( refdes );
504
505 if( comp == nullptr )
506 {
507 comp = new IDF3_COMPONENT( &aIDFBoard );
508
509 if( comp == nullptr )
510 throw( std::runtime_error( aIDFBoard.GetError() ) );
511
512 comp->SetRefDes( refdes );
513
514 if( top )
515 {
516 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
517 -aFootprint->GetPosition().y * scale + dy,
518 rotz, IDF3::LYR_TOP );
519 }
520 else
521 {
522 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
523 -aFootprint->GetPosition().y * scale + dy,
524 rotz, IDF3::LYR_BOTTOM );
525 }
526
527 comp->SetPlacement( IDF3::PS_ECAD );
528
529 aIDFBoard.AddComponent( comp );
530 }
531 else
532 {
533 double refX, refY, refA;
534 IDF3::IDF_LAYER side;
535
536 if( ! comp->GetPosition( refX, refY, refA, side ) )
537 {
538 // place the item
539 if( top )
540 {
541 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
542 -aFootprint->GetPosition().y * scale + dy,
543 rotz, IDF3::LYR_TOP );
544 }
545 else
546 {
547 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
548 -aFootprint->GetPosition().y * scale + dy,
549 rotz, IDF3::LYR_BOTTOM );
550 }
551
552 comp->SetPlacement( IDF3::PS_ECAD );
553
554 }
555 else
556 {
557 // check that the retrieved component matches this one
558 refX = refX - ( aFootprint->GetPosition().x * scale + dx );
559 refY = refY - ( -aFootprint->GetPosition().y * scale + dy );
560 refA = refA - rotz;
561 refA *= refA;
562 refX *= refX;
563 refY *= refY;
564 refX += refY;
565
566 // conditions: same side, X,Y coordinates within 10 microns,
567 // angle within 0.01 degree
568 if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
569 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
570 {
571 comp->GetPosition( refX, refY, refA, side );
572
573 std::ostringstream ostr;
574 ostr << "* " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
575 ostr << "* conflicting Reference Designator '" << refdes << "'\n";
576 ostr << "* X loc: " << ( aFootprint->GetPosition().x * scale + dx);
577 ostr << " vs. " << refX << "\n";
578 ostr << "* Y loc: " << ( -aFootprint->GetPosition().y * scale + dy);
579 ostr << " vs. " << refY << "\n";
580 ostr << "* angle: " << rotz;
581 ostr << " vs. " << refA << "\n";
582
583 if( top )
584 ostr << "* TOP vs. ";
585 else
586 ostr << "* BOTTOM vs. ";
587
588 if( side == IDF3::LYR_TOP )
589 ostr << "TOP";
590 else
591 ostr << "BOTTOM";
592
593 throw( std::runtime_error( ostr.str() ) );
594 }
595 }
596 }
597
598 // create the local data ...
599 IDF3_COMP_OUTLINE_DATA* data = new IDF3_COMP_OUTLINE_DATA( comp, outline );
600
601 data->SetOffsets( locx, locy, locz, lrot );
602 comp->AddOutlineData( data );
603 ++sM;
604 }
605}
606
607
612bool PCB_EDIT_FRAME::Export_IDF3( BOARD* aPcb, const wxString& aFullFileName,
613 bool aUseThou, double aXRef, double aYRef,
614 bool aIncludeUnspecified, bool aIncludeDNP )
615{
616 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
617
618 // Switch the locale to standard C (needed to print floating point numbers)
619 LOCALE_IO toggle;
620
622
623 bool ok = true;
624 double scale = pcbIUScale.MM_PER_IU; // we must scale internal units to mm for IDF
625 IDF3::IDF_UNIT idfUnit;
626
627 if( aUseThou )
628 {
629 idfUnit = IDF3::UNIT_THOU;
630 idfBoard.SetUserPrecision( 1 );
631 }
632 else
633 {
634 idfUnit = IDF3::UNIT_MM;
635 idfBoard.SetUserPrecision( 5 );
636 }
637
638 wxFileName brdName = aPcb->GetFileName();
639
640 idfBoard.SetUserScale( scale );
641 idfBoard.SetBoardThickness( aPcb->GetDesignSettings().GetBoardThickness() * scale );
642 idfBoard.SetBoardName( TO_UTF8( brdName.GetFullName() ) );
643 idfBoard.SetBoardVersion( 0 );
644 idfBoard.SetLibraryVersion( 0 );
645
646 std::ostringstream ostr;
647 ostr << "KiCad " << TO_UTF8( GetBuildVersion() );
648 idfBoard.SetIDFSource( ostr.str() );
649
650 try
651 {
652 // set up the board reference point
653 idfBoard.SetUserOffset( -aXRef, aYRef );
654
655 // Export the board outline
656 idf_export_outline( aPcb, idfBoard );
657
658 // Output the drill holes and footprint (library) data.
659 for( FOOTPRINT* footprint : aPcb->Footprints() )
660 idf_export_footprint( aPcb, footprint, idfBoard, aIncludeUnspecified, aIncludeDNP );
661
662 if( !idfBoard.WriteFile( aFullFileName, idfUnit, false ) )
663 {
664 wxString msg;
665 msg << _( "IDF Export Failed:\n" ) << From_UTF8( idfBoard.GetError().c_str() );
666 wxMessageBox( msg );
667
668 ok = false;
669 }
670 }
671 catch( const IO_ERROR& ioe )
672 {
673 wxString msg;
674 msg << _( "IDF Export Failed:\n" ) << ioe.What();
675 wxMessageBox( msg );
676
677 ok = false;
678 }
679 catch( const std::exception& e )
680 {
681 wxString msg;
682 msg << _( "IDF Export Failed:\n" ) << From_UTF8( e.what() );
683 wxMessageBox( msg );
684 ok = false;
685 }
686
687 return ok;
688}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:112
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:317
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: board.cpp:2577
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
Definition: board.h:980
const FOOTPRINTS & Footprints() const
Definition: board.h:358
const wxString & GetFileName() const
Definition: board.h:354
PROJECT * GetProject() const
Definition: board.h:536
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:946
const DRAWINGS & Drawings() const
Definition: board.h:360
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:116
EDA_ANGLE GetArcAngle() const
Definition: eda_shape.cpp:1076
int GetRadius() const
Definition: eda_shape.cpp:1004
SHAPE_T GetShape() const
Definition: eda_shape.h:168
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:215
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:173
Provide an extensible class to resolve 3D model paths.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath, std::vector< const EMBEDDED_FILES * > aEmbeddedFilesStack)
Determine the full path of the given file name.
bool IsDNP() const
Definition: footprint.h:744
EDA_ANGLE GetOrientation() const
Definition: footprint.h:230
PCB_FIELD & Value()
read/write accessors:
Definition: footprint.h:661
std::deque< PAD * > & Pads()
Definition: footprint.h:209
int GetAttributes() const
Definition: footprint.h:293
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: footprint.h:239
const LIB_ID & GetFPID() const
Definition: footprint.h:251
PCB_FIELD & Reference()
Definition: footprint.h:662
std::vector< FP_3DMODEL > & Models()
Definition: footprint.h:223
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: footprint.h:969
VECTOR2I GetPosition() const override
Definition: footprint.h:227
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:41
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:612
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:81
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:138
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:513
#define _(s)
@ RECTANGLE
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:81
@ FP_THROUGH_HOLE
Definition: footprint.h:80
PROJECT & Prj()
Definition: kicad.cpp:597
@ 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:429
const double MM_PER_IU
Definition: base_units.h:80
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