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