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->GetDNPForVariant( aPcb ? aPcb->GetCurrentVariant() : wxString() )
411 && !aIncludeDNP )
412 return;
413
414 // add any valid models to the library item list
415 std::string refdes;
416
417 IDF3_COMPONENT* comp = nullptr;
418
419 auto sM = aFootprint->Models().begin();
420 auto eM = aFootprint->Models().end();
421 wxFileName idfFile;
422 wxString idfExt;
423
424 while( sM != eM )
425 {
426 if( !sM->m_Show )
427 {
428 ++sM;
429 continue;
430 }
431
432 std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
433 embeddedFilesStack.push_back( aFootprint->GetEmbeddedFiles() );
434 embeddedFilesStack.push_back( aPcb->GetEmbeddedFiles() );
435
436 idfFile.Assign( resolver->ResolvePath( sM->m_Filename, footprintBasePath, std::move( embeddedFilesStack ) ) );
437 idfExt = idfFile.GetExt();
438
439 if( idfExt.Cmp( wxT( "idf" ) ) && idfExt.Cmp( wxT( "IDF" ) ) )
440 {
441 ++sM;
442 continue;
443 }
444
445 if( refdes.empty() )
446 {
447 refdes = TO_UTF8( aFootprint->Reference().GetShownText( false ) );
448
449 // NOREFDES cannot be used or else the software gets confused
450 // when writing out the placement data due to conflicting
451 // placement and layer specifications; to work around this we
452 // create a (hopefully) unique refdes for our exported part.
453 if( refdes.empty() || !refdes.compare( "~" ) )
454 refdes = aIDFBoard.GetNewRefDes();
455 }
456
457 IDF3_COMP_OUTLINE* outline;
458
459 outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
460
461 if( !outline )
462 throw( std::runtime_error( aIDFBoard.GetError() ) );
463
464 double rotz = aFootprint->GetOrientation().AsDegrees();
465 double locx = sM->m_Offset.x; // part offsets are in mm
466 double locy = sM->m_Offset.y;
467 double locz = sM->m_Offset.z;
468 double lrot = sM->m_Rotation.z;
469
470 bool top = ( aFootprint->GetLayer() == B_Cu ) ? false : true;
471
472 if( top )
473 {
474 locy = -locy;
475 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
476 locy = -locy;
477 }
478
479 if( !top )
480 {
481 lrot = -lrot;
482 RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
483 locy = -locy;
484
485 rotz = 180.0 - rotz;
486
487 if( rotz >= 360.0 )
488 while( rotz >= 360.0 ) rotz -= 360.0;
489
490 if( rotz <= -360.0 )
491 while( rotz <= -360.0 ) rotz += 360.0;
492 }
493
494 if( comp == nullptr )
495 comp = aIDFBoard.FindComponent( refdes );
496
497 if( comp == nullptr )
498 {
499 comp = new IDF3_COMPONENT( &aIDFBoard );
500
501 if( comp == nullptr )
502 throw( std::runtime_error( aIDFBoard.GetError() ) );
503
504 comp->SetRefDes( refdes );
505
506 if( top )
507 {
508 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
509 -aFootprint->GetPosition().y * scale + dy,
510 rotz, IDF3::LYR_TOP );
511 }
512 else
513 {
514 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
515 -aFootprint->GetPosition().y * scale + dy,
516 rotz, IDF3::LYR_BOTTOM );
517 }
518
519 comp->SetPlacement( IDF3::PS_ECAD );
520
521 aIDFBoard.AddComponent( comp );
522 }
523 else
524 {
525 double refX, refY, refA;
526 IDF3::IDF_LAYER side;
527
528 if( ! comp->GetPosition( refX, refY, refA, side ) )
529 {
530 // place the item
531 if( top )
532 {
533 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
534 -aFootprint->GetPosition().y * scale + dy,
535 rotz, IDF3::LYR_TOP );
536 }
537 else
538 {
539 comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
540 -aFootprint->GetPosition().y * scale + dy,
541 rotz, IDF3::LYR_BOTTOM );
542 }
543
544 comp->SetPlacement( IDF3::PS_ECAD );
545
546 }
547 else
548 {
549 // check that the retrieved component matches this one
550 refX = refX - ( aFootprint->GetPosition().x * scale + dx );
551 refY = refY - ( -aFootprint->GetPosition().y * scale + dy );
552 refA = refA - rotz;
553 refA *= refA;
554 refX *= refX;
555 refY *= refY;
556 refX += refY;
557
558 // conditions: same side, X,Y coordinates within 10 microns,
559 // angle within 0.01 degree
560 if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
561 || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
562 {
563 comp->GetPosition( refX, refY, refA, side );
564
565 std::ostringstream ostr;
566 ostr << "* " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
567 ostr << "* conflicting Reference Designator '" << refdes << "'\n";
568 ostr << "* X loc: " << ( aFootprint->GetPosition().x * scale + dx);
569 ostr << " vs. " << refX << "\n";
570 ostr << "* Y loc: " << ( -aFootprint->GetPosition().y * scale + dy);
571 ostr << " vs. " << refY << "\n";
572 ostr << "* angle: " << rotz;
573 ostr << " vs. " << refA << "\n";
574
575 if( top )
576 ostr << "* TOP vs. ";
577 else
578 ostr << "* BOTTOM vs. ";
579
580 if( side == IDF3::LYR_TOP )
581 ostr << "TOP";
582 else
583 ostr << "BOTTOM";
584
585 throw( std::runtime_error( ostr.str() ) );
586 }
587 }
588 }
589
590 // create the local data ...
591 IDF3_COMP_OUTLINE_DATA* data = new IDF3_COMP_OUTLINE_DATA( comp, outline );
592
593 data->SetOffsets( locx, locy, locz, lrot );
594 comp->AddOutlineData( data );
595 ++sM;
596 }
597}
598
599
604bool PCB_EDIT_FRAME::Export_IDF3( BOARD* aPcb, const wxString& aFullFileName,
605 bool aUseThou, double aXRef, double aYRef,
606 bool aIncludeUnspecified, bool aIncludeDNP )
607{
608 IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
609
610 // Switch the locale to standard C (needed to print floating point numbers)
611 LOCALE_IO toggle;
612
614
615 bool ok = true;
616 double scale = pcbIUScale.MM_PER_IU; // we must scale internal units to mm for IDF
617 IDF3::IDF_UNIT idfUnit;
618
619 if( aUseThou )
620 {
621 idfUnit = IDF3::UNIT_THOU;
622 idfBoard.SetUserPrecision( 1 );
623 }
624 else
625 {
626 idfUnit = IDF3::UNIT_MM;
627 idfBoard.SetUserPrecision( 5 );
628 }
629
630 wxFileName brdName = aPcb->GetFileName();
631
632 idfBoard.SetUserScale( scale );
633 idfBoard.SetBoardThickness( aPcb->GetDesignSettings().GetBoardThickness() * scale );
634 idfBoard.SetBoardName( TO_UTF8( brdName.GetFullName() ) );
635 idfBoard.SetBoardVersion( 0 );
636 idfBoard.SetLibraryVersion( 0 );
637
638 std::ostringstream ostr;
639 ostr << "KiCad " << TO_UTF8( GetBuildVersion() );
640 idfBoard.SetIDFSource( ostr.str() );
641
642 try
643 {
644 // set up the board reference point
645 idfBoard.SetUserOffset( -aXRef, aYRef );
646
647 // Export the board outline
648 idf_export_outline( aPcb, idfBoard );
649
650 // Output the drill holes and footprint (library) data.
651 for( FOOTPRINT* footprint : aPcb->Footprints() )
652 idf_export_footprint( aPcb, footprint, idfBoard, aIncludeUnspecified, aIncludeDNP );
653
654 if( !idfBoard.WriteFile( aFullFileName, idfUnit, false ) )
655 {
656 wxString msg;
657 msg << _( "IDF Export Failed:\n" ) << From_UTF8( idfBoard.GetError().c_str() );
658 wxMessageBox( msg );
659
660 ok = false;
661 }
662 }
663 catch( const IO_ERROR& ioe )
664 {
665 wxString msg;
666 msg << _( "IDF Export Failed:\n" ) << ioe.What();
667 wxMessageBox( msg );
668
669 ok = false;
670 }
671 catch( const std::exception& e )
672 {
673 wxString msg;
674 msg << _( "IDF Export Failed:\n" ) << From_UTF8( e.what() );
675 wxMessageBox( msg );
676 ok = false;
677 }
678
679 return ok;
680}
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:83
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition board.cpp:3083
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
Definition board.h:1064
const FOOTPRINTS & Footprints() const
Definition board.h:363
const wxString & GetFileName() const
Definition board.h:359
wxString GetCurrentVariant() const
Definition board.h:404
PROJECT * GetProject() const
Definition board.h:579
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1082
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:169
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:216
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:174
Provide an extensible class to resolve 3D model paths.
EDA_ANGLE GetOrientation() const
Definition footprint.h:328
PCB_FIELD & Value()
read/write accessors:
Definition footprint.h:777
std::deque< PAD * > & Pads()
Definition footprint.h:304
int GetAttributes() const
Definition footprint.h:407
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition footprint.h:337
const LIB_ID & GetFPID() const
Definition footprint.h:349
PCB_FIELD & Reference()
Definition footprint.h:778
bool GetDNPForVariant(const wxString &aVariantName) const
Get the DNP status for a specific variant.
std::vector< FP_3DMODEL > & Models()
Definition footprint.h:321
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition footprint.h:1193
VECTOR2I GetPosition() const override
Definition footprint.h:325
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.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition pcb_shape.h:81
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:83
@ FP_THROUGH_HOLE
Definition footprint.h:82
PROJECT & Prj()
Definition kicad.cpp:637
@ 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:103
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.
KIBIS top(path, &reporter)
KIBIS_COMPONENT * comp
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