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>
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 std::optional<LIBRARY_TABLE_ROW*> fpRow =
284 PROJECT_PCB::FootprintLibAdapter( aPcb->GetProject() )->GetRow( libraryName );
285 if( fpRow )
286 footprintBasePath = LIBRARY_MANAGER::GetFullURI( *fpRow, true );
287 }
288
289 if( crefdes.empty() || !crefdes.compare( "~" ) )
290 {
291 std::string cvalue = TO_UTF8( aFootprint->Value().GetShownText( false ) );
292
293 // if both the RefDes and Value are empty or set to '~' the board owns the part,
294 // otherwise associated parts of the footprint must be marked NOREFDES.
295 if( cvalue.empty() || !cvalue.compare( "~" ) )
296 crefdes = "BOARD";
297 else
298 crefdes = "NOREFDES";
299 }
300
301 // TODO: If footprint cutouts are supported we must add code here
302 // for( EDA_ITEM* item = aFootprint->GraphicalItems(); item != NULL; item = item->Next() )
303 // {
304 // if( item->Type() != PCB_SHAPE_T || item->GetLayer() != Edge_Cuts )
305 // continue;
306 // code to export cutouts
307 // }
308
309 // Export pads
310 double drill, x, y;
311 double scale = aIDFBoard.GetUserScale();
312 IDF3::KEY_PLATING kplate;
313 std::string pintype;
314 std::string tstr;
315
316 double dx, dy;
317
318 aIDFBoard.GetUserOffset( dx, dy );
319
320 for( auto pad : aFootprint->Pads() )
321 {
322 drill = (double) pad->GetDrillSize().x * scale;
323 x = pad->GetPosition().x * scale + dx;
324 y = -pad->GetPosition().y * scale + dy;
325
326 // Export the hole on the edge layer
327 if( drill > 0.0 )
328 {
329 // plating
330 if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
331 kplate = IDF3::NPTH;
332 else
333 kplate = IDF3::PTH;
334
335 // hole type
336 tstr = TO_UTF8( pad->GetNumber() );
337
338 if( tstr.empty() || !tstr.compare( "0" ) || !tstr.compare( "~" )
339 || ( kplate == IDF3::NPTH )
340 || ( pad->GetDrillShape() == PAD_DRILL_SHAPE::OBLONG ) )
341 pintype = "MTG";
342 else
343 pintype = "PIN";
344
345 // fields:
346 // 1. hole dia. : float
347 // 2. X coord : float
348 // 3. Y coord : float
349 // 4. plating : PTH | NPTH
350 // 5. Assoc. part : BOARD | NOREFDES | PANEL | {"refdes"}
351 // 6. type : PIN | VIA | MTG | TOOL | { "other" }
352 // 7. owner : MCAD | ECAD | UNOWNED
353 if( ( pad->GetDrillShape() == PAD_DRILL_SHAPE::OBLONG )
354 && ( pad->GetDrillSize().x != pad->GetDrillSize().y ) )
355 {
356 // NOTE: IDF does not have direct support for slots;
357 // slots are implemented as a board cutout and we
358 // cannot represent plating or reference designators
359
360 double dlength = pad->GetDrillSize().y * scale;
361
362 // NOTE: The orientation of footprints and pads have
363 // the opposite sense due to KiCad drawing on a
364 // screen with a LH coordinate system
365 double angle = pad->GetOrientation().AsDegrees();
366
367 // NOTE: Since this code assumes the scenario where
368 // GetDrillSize().y is the length but idf_parser.cpp
369 // assumes a length along the X axis, the orientation
370 // must be shifted +90 deg when GetDrillSize().y is
371 // the major axis.
372
373 if( dlength < drill )
374 {
375 std::swap( drill, dlength );
376 }
377 else
378 {
379 angle += 90.0;
380 }
381
382 // NOTE: KiCad measures a slot's length from end to end
383 // rather than between the centers of the arcs
384 dlength -= drill;
385
386 aIDFBoard.AddSlot( drill, dlength, angle, x, y );
387 }
388 else
389 {
390 IDF_DRILL_DATA *dp = new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
391 pintype, IDF3::ECAD );
392
393 if( !aIDFBoard.AddDrill( dp ) )
394 {
395 delete dp;
396
397 std::ostringstream ostr;
398 ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__;
399 ostr << "(): could not add drill";
400
401 throw std::runtime_error( ostr.str() );
402 }
403 }
404 }
405 }
406
407 if( ( !(aFootprint->GetAttributes() & (FP_THROUGH_HOLE|FP_SMD)) ) && !aIncludeUnspecified )
408 return;
409
410 if( aFootprint->IsDNP() && !aIncludeDNP )
411 return;
412
413 // add any valid models to the library item list
414 std::string refdes;
415
416 IDF3_COMPONENT* comp = nullptr;
417
418 auto sM = aFootprint->Models().begin();
419 auto eM = aFootprint->Models().end();
420 wxFileName idfFile;
421 wxString idfExt;
422
423 while( sM != eM )
424 {
425 if( !sM->m_Show )
426 {
427 ++sM;
428 continue;
429 }
430
431 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
432 embeddedFilesStack.push_back( aFootprint->GetEmbeddedFiles() );
433 embeddedFilesStack.push_back( aPcb->GetEmbeddedFiles() );
434
435 idfFile.Assign( resolver->ResolvePath( sM->m_Filename, footprintBasePath, std::move( embeddedFilesStack ) ) );
436 idfExt = idfFile.GetExt();
437
438 if( idfExt.Cmp( wxT( "idf" ) ) && idfExt.Cmp( wxT( "IDF" ) ) )
439 {
440 ++sM;
441 continue;
442 }
443
444 if( refdes.empty() )
445 {
446 refdes = TO_UTF8( aFootprint->Reference().GetShownText( false ) );
447
448 // NOREFDES cannot be used or else the software gets confused
449 // when writing out the placement data due to conflicting
450 // placement and layer specifications; to work around this we
451 // create a (hopefully) unique refdes for our exported part.
452 if( refdes.empty() || !refdes.compare( "~" ) )
453 refdes = aIDFBoard.GetNewRefDes();
454 }
455
456 IDF3_COMP_OUTLINE* outline;
457
458 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
459
460 if( !outline )
461 throw( std::runtime_error( aIDFBoard.GetError() ) );
462
463 double rotz = aFootprint->GetOrientation().AsDegrees();
464 double locx = sM->m_Offset.x; // part offsets are in mm
465 double locy = sM->m_Offset.y;
466 double locz = sM->m_Offset.z;
467 double lrot = sM->m_Rotation.z;
468
469 bool top = ( aFootprint->GetLayer() == B_Cu ) ? false : true;
470
471 if( top )
472 {
473 locy = -locy;
474 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
475 locy = -locy;
476 }
477
478 if( !top )
479 {
480 lrot = -lrot;
481 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
482 locy = -locy;
483
484 rotz = 180.0 - rotz;
485
486 if( rotz >= 360.0 )
487 while( rotz >= 360.0 ) rotz -= 360.0;
488
489 if( rotz <= -360.0 )
490 while( rotz <= -360.0 ) rotz += 360.0;
491 }
492
493 if( comp == nullptr )
494 comp = aIDFBoard.FindComponent( refdes );
495
496 if( comp == nullptr )
497 {
498 comp = new IDF3_COMPONENT( &aIDFBoard );
499
500 if( comp == nullptr )
501 throw( std::runtime_error( aIDFBoard.GetError() ) );
502
503 comp->SetRefDes( refdes );
504
505 if( top )
506 {
507 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
508 -aFootprint->GetPosition().y * scale + dy,
509 rotz, IDF3::LYR_TOP );
510 }
511 else
512 {
513 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
514 -aFootprint->GetPosition().y * scale + dy,
515 rotz, IDF3::LYR_BOTTOM );
516 }
517
518 comp->SetPlacement( IDF3::PS_ECAD );
519
520 aIDFBoard.AddComponent( comp );
521 }
522 else
523 {
524 double refX, refY, refA;
525 IDF3::IDF_LAYER side;
526
527 if( ! comp->GetPosition( refX, refY, refA, side ) )
528 {
529 // place the item
530 if( top )
531 {
532 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
533 -aFootprint->GetPosition().y * scale + dy,
534 rotz, IDF3::LYR_TOP );
535 }
536 else
537 {
538 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
539 -aFootprint->GetPosition().y * scale + dy,
540 rotz, IDF3::LYR_BOTTOM );
541 }
542
543 comp->SetPlacement( IDF3::PS_ECAD );
544
545 }
546 else
547 {
548 // check that the retrieved component matches this one
549 refX = refX - ( aFootprint->GetPosition().x * scale + dx );
550 refY = refY - ( -aFootprint->GetPosition().y * scale + dy );
551 refA = refA - rotz;
552 refA *= refA;
553 refX *= refX;
554 refY *= refY;
555 refX += refY;
556
557 // conditions: same side, X,Y coordinates within 10 microns,
558 // angle within 0.01 degree
559 if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
560 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
561 {
562 comp->GetPosition( refX, refY, refA, side );
563
564 std::ostringstream ostr;
565 ostr << "* " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
566 ostr << "* conflicting Reference Designator '" << refdes << "'\n";
567 ostr << "* X loc: " << ( aFootprint->GetPosition().x * scale + dx);
568 ostr << " vs. " << refX << "\n";
569 ostr << "* Y loc: " << ( -aFootprint->GetPosition().y * scale + dy);
570 ostr << " vs. " << refY << "\n";
571 ostr << "* angle: " << rotz;
572 ostr << " vs. " << refA << "\n";
573
574 if( top )
575 ostr << "* TOP vs. ";
576 else
577 ostr << "* BOTTOM vs. ";
578
579 if( side == IDF3::LYR_TOP )
580 ostr << "TOP";
581 else
582 ostr << "BOTTOM";
583
584 throw( std::runtime_error( ostr.str() ) );
585 }
586 }
587 }
588
589 // create the local data ...
590 IDF3_COMP_OUTLINE_DATA* data = new IDF3_COMP_OUTLINE_DATA( comp, outline );
591
592 data->SetOffsets( locx, locy, locz, lrot );
593 comp->AddOutlineData( data );
594 ++sM;
595 }
596}
597
598
603bool PCB_EDIT_FRAME::Export_IDF3( BOARD* aPcb, const wxString& aFullFileName,
604 bool aUseThou, double aXRef, double aYRef,
605 bool aIncludeUnspecified, bool aIncludeDNP )
606{
607 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
608
609 // Switch the locale to standard C (needed to print floating point numbers)
610 LOCALE_IO toggle;
611
613
614 bool ok = true;
615 double scale = pcbIUScale.MM_PER_IU; // we must scale internal units to mm for IDF
616 IDF3::IDF_UNIT idfUnit;
617
618 if( aUseThou )
619 {
620 idfUnit = IDF3::UNIT_THOU;
621 idfBoard.SetUserPrecision( 1 );
622 }
623 else
624 {
625 idfUnit = IDF3::UNIT_MM;
626 idfBoard.SetUserPrecision( 5 );
627 }
628
629 wxFileName brdName = aPcb->GetFileName();
630
631 idfBoard.SetUserScale( scale );
632 idfBoard.SetBoardThickness( aPcb->GetDesignSettings().GetBoardThickness() * scale );
633 idfBoard.SetBoardName( TO_UTF8( brdName.GetFullName() ) );
634 idfBoard.SetBoardVersion( 0 );
635 idfBoard.SetLibraryVersion( 0 );
636
637 std::ostringstream ostr;
638 ostr << "KiCad " << TO_UTF8( GetBuildVersion() );
639 idfBoard.SetIDFSource( ostr.str() );
640
641 try
642 {
643 // set up the board reference point
644 idfBoard.SetUserOffset( -aXRef, aYRef );
645
646 // Export the board outline
647 idf_export_outline( aPcb, idfBoard );
648
649 // Output the drill holes and footprint (library) data.
650 for( FOOTPRINT* footprint : aPcb->Footprints() )
651 idf_export_footprint( aPcb, footprint, idfBoard, aIncludeUnspecified, aIncludeDNP );
652
653 if( !idfBoard.WriteFile( aFullFileName, idfUnit, false ) )
654 {
655 wxString msg;
656 msg << _( "IDF Export Failed:\n" ) << From_UTF8( idfBoard.GetError().c_str() );
657 wxMessageBox( msg );
658
659 ok = false;
660 }
661 }
662 catch( const IO_ERROR& ioe )
663 {
664 wxString msg;
665 msg << _( "IDF Export Failed:\n" ) << ioe.What();
666 wxMessageBox( msg );
667
668 ok = false;
669 }
670 catch( const std::exception& e )
671 {
672 wxString msg;
673 msg << _( "IDF Export Failed:\n" ) << From_UTF8( e.what() );
674 wxMessageBox( msg );
675 ok = false;
676 }
677
678 return ok;
679}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
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:322
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition board.cpp:2840
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
Definition board.h:1021
const FOOTPRINTS & Footprints() const
Definition board.h:363
const wxString & GetFileName() const
Definition board.h:359
PROJECT * GetProject() const
Definition board.h:554
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1044
const DRAWINGS & Drawings() const
Definition board.h:365
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
int GetRadius() const
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.
bool IsDNP() const
Definition footprint.h:789
EDA_ANGLE GetOrientation() const
Definition footprint.h:248
PCB_FIELD & Value()
read/write accessors:
Definition footprint.h:697
std::deque< PAD * > & Pads()
Definition footprint.h:224
int GetAttributes() const
Definition footprint.h:327
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:257
const LIB_ID & GetFPID() const
Definition footprint.h:269
PCB_FIELD & Reference()
Definition footprint.h:698
std::vector< FP_3DMODEL > & Models()
Definition footprint.h:241
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition footprint.h:1014
VECTOR2I GetPosition() const override
Definition footprint.h:245
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:87
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.
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:139
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
FILENAME_RESOLVER * GetResolver() noexcept
Definition 3d_cache.cpp:513
#define _(s)
@ SEGMENT
Definition eda_shape.h:45
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:46
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 ...
#define LINE_WIDTH
static FILENAME_RESOLVER * resolver
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...
@ FP_SMD
Definition footprint.h:82
@ FP_THROUGH_HOLE
Definition footprint.h:81
PROJECT & Prj()
Definition kicad.cpp:629
@ 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
Definition padstack.h:87
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.
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