KiCad PCB EDA Suite
export_idf.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 2013 Cirilo Bernardo
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 
29 #include <list>
30 #include <locale_io.h>
31 #include <macros.h>
32 #include <pcb_edit_frame.h>
33 #include <board.h>
34 #include <footprint.h>
35 #include <fp_shape.h>
36 #include <idf_parser.h>
37 #include <build_version.h>
38 #include "project.h"
39 #include "kiway.h"
40 #include "3d_cache/3d_cache.h"
41 #include "filename_resolver.h"
42 
43 #ifndef PCBNEW
44 #define PCBNEW // needed to define the right value of Millimeter2iu(x)
45 #endif
46 #include <convert_to_biu.h> // to define Millimeter2iu(x)
47 
48 // assumed default graphical line thickness: == 0.1mm
49 #define LINE_WIDTH (Millimeter2iu( 0.1 ))
50 
52 
59 static void idf_export_outline( BOARD* aPcb, IDF3_BOARD& aIDFBoard )
60 {
61  double scale = aIDFBoard.GetUserScale();
62 
63  PCB_SHAPE* graphic; // KiCad graphical item
64  IDF_POINT sp, ep; // start and end points from KiCad item
65 
66  std::list< IDF_SEGMENT* > lines; // IDF intermediate form of KiCad graphical item
67  IDF_OUTLINE* outline = NULL; // graphical items forming an outline or cutout
68 
69  // NOTE: IMPLEMENTATION
70  // If/when component cutouts are allowed, we must implement them separately. Cutouts
71  // must be added to the board outline section and not to the Other Outline section.
72  // The footprint cutouts should be handled via the idf_export_footprint() routine.
73 
74  double offX, offY;
75  aIDFBoard.GetUserOffset( offX, offY );
76 
77  // Retrieve segments and arcs from the board
78  for( BOARD_ITEM* item : aPcb->Drawings() )
79  {
80  if( item->Type() != PCB_SHAPE_T || item->GetLayer() != Edge_Cuts )
81  continue;
82 
83  graphic = (PCB_SHAPE*) item;
84 
85  switch( graphic->GetShape() )
86  {
88  {
89  if( ( graphic->GetStart().x == graphic->GetEnd().x )
90  && ( graphic->GetStart().y == graphic->GetEnd().y ) )
91  {
92  break;
93  }
94 
95  sp.x = graphic->GetStart().x * scale + offX;
96  sp.y = -graphic->GetStart().y * scale + offY;
97  ep.x = graphic->GetEnd().x * scale + offX;
98  ep.y = -graphic->GetEnd().y * scale + offY;
99  IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep );
100 
101  if( seg )
102  lines.push_back( seg );
103  }
104  break;
105 
107  {
108  if( ( graphic->GetStart().x == graphic->GetEnd().x )
109  && ( graphic->GetStart().y == graphic->GetEnd().y ) )
110  {
111  break;
112  }
113 
114  double top = graphic->GetStart().y * scale + offY;
115  double left = graphic->GetStart().x * scale + offX;
116  double bottom = graphic->GetEnd().y * scale + offY;
117  double right = graphic->GetEnd().x * scale + offX;
118 
119  IDF_POINT corners[4];
120  corners[0] = IDF_POINT( left, top );
121  corners[1] = IDF_POINT( right, top );
122  corners[2] = IDF_POINT( right, bottom );
123  corners[3] = IDF_POINT( left, bottom );
124 
125  lines.push_back( new IDF_SEGMENT( corners[0], corners[1] ) );
126  lines.push_back( new IDF_SEGMENT( corners[1], corners[2] ) );
127  lines.push_back( new IDF_SEGMENT( corners[2], corners[3] ) );
128  lines.push_back( new IDF_SEGMENT( corners[3], corners[0] ) );
129  }
130  break;
131 
132  case PCB_SHAPE_TYPE::ARC:
133  {
134  if( ( graphic->GetCenter().x == graphic->GetArcStart().x )
135  && ( graphic->GetCenter().y == graphic->GetArcStart().y ) )
136  {
137  break;
138  }
139 
140  sp.x = graphic->GetCenter().x * scale + offX;
141  sp.y = -graphic->GetCenter().y * scale + offY;
142  ep.x = graphic->GetArcStart().x * scale + offX;
143  ep.y = -graphic->GetArcStart().y * scale + offY;
144  IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep, -graphic->GetAngle() / 10.0, true );
145 
146  if( seg )
147  lines.push_back( seg );
148  }
149  break;
150 
152  {
153  if( graphic->GetRadius() == 0 )
154  break;
155 
156  sp.x = graphic->GetCenter().x * scale + offX;
157  sp.y = -graphic->GetCenter().y * scale + offY;
158  ep.x = sp.x - graphic->GetRadius() * scale;
159  ep.y = sp.y;
160  // Circles must always have an angle of +360 deg. to appease
161  // quirky MCAD implementations of IDF.
162  IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep, 360.0, true );
163 
164  if( seg )
165  lines.push_back( seg );
166  }
167  break;
168 
169  default:
170  break;
171  }
172  }
173 
174  // if there is no outline then use the bounding box
175  if( lines.empty() )
176  {
177  goto UseBoundingBox;
178  }
179 
180  // get the board outline and write it out
181  // note: we do not use a try/catch block here since we intend
182  // to simply ignore unclosed loops and continue processing
183  // until we're out of segments to process
184  outline = new IDF_OUTLINE;
185  IDF3::GetOutline( lines, *outline );
186 
187  if( outline->empty() )
188  goto UseBoundingBox;
189 
190  aIDFBoard.AddBoardOutline( outline );
191  outline = NULL;
192 
193  // get all cutouts and write them out
194  while( !lines.empty() )
195  {
196  if( !outline )
197  outline = new IDF_OUTLINE;
198 
199  IDF3::GetOutline( lines, *outline );
200 
201  if( outline->empty() )
202  {
203  outline->Clear();
204  continue;
205  }
206 
207  aIDFBoard.AddBoardOutline( outline );
208  outline = NULL;
209  }
210 
211  return;
212 
213 UseBoundingBox:
214 
215  // clean up if necessary
216  while( !lines.empty() )
217  {
218  delete lines.front();
219  lines.pop_front();
220  }
221 
222  if( outline )
223  outline->Clear();
224  else
225  outline = new IDF_OUTLINE;
226 
227  // Fetch a rectangular bounding box for the board; there is always some uncertainty in the
228  // board dimensions computed via ComputeBoundingBox() since this depends on the individual
229  // footprint entities.
230  EDA_RECT bbbox = aPcb->GetBoardEdgesBoundingBox();
231 
232  // convert to mm and compensate for an assumed LINE_WIDTH line thickness
233  double x = ( bbbox.GetOrigin().x + LINE_WIDTH / 2 ) * scale + offX;
234  double y = ( bbbox.GetOrigin().y + LINE_WIDTH / 2 ) * scale + offY;
235  double dx = ( bbbox.GetSize().x - LINE_WIDTH ) * scale;
236  double dy = ( bbbox.GetSize().y - LINE_WIDTH ) * scale;
237 
238  double px[4], py[4];
239  px[0] = x;
240  py[0] = y;
241 
242  px[1] = x;
243  py[1] = y + dy;
244 
245  px[2] = x + dx;
246  py[2] = y + dy;
247 
248  px[3] = x + dx;
249  py[3] = y;
250 
251  IDF_POINT p1, p2;
252 
253  p1.x = px[3];
254  p1.y = py[3];
255  p2.x = px[0];
256  p2.y = py[0];
257 
258  outline->push( new IDF_SEGMENT( p1, p2 ) );
259 
260  for( int i = 1; i < 4; ++i )
261  {
262  p1.x = px[i - 1];
263  p1.y = py[i - 1];
264  p2.x = px[i];
265  p2.y = py[i];
266 
267  outline->push( new IDF_SEGMENT( p1, p2 ) );
268  }
269 
270  aIDFBoard.AddBoardOutline( outline );
271 }
272 
273 
281 static void idf_export_footprint( BOARD* aPcb, FOOTPRINT* aFootprint, IDF3_BOARD& aIDFBoard )
282 {
283  // Reference Designator
284  std::string crefdes = TO_UTF8( aFootprint->Reference().GetShownText() );
285 
286  if( crefdes.empty() || !crefdes.compare( "~" ) )
287  {
288  std::string cvalue = TO_UTF8( aFootprint->Value().GetShownText() );
289 
290  // if both the RefDes and Value are empty or set to '~' the board owns the part,
291  // otherwise associated parts of the footprint must be marked NOREFDES.
292  if( cvalue.empty() || !cvalue.compare( "~" ) )
293  crefdes = "BOARD";
294  else
295  crefdes = "NOREFDES";
296  }
297 
298  // TODO: If footprint cutouts are supported we must add code here
299  // for( EDA_ITEM* item = aFootprint->GraphicalItems(); item != NULL; item = item->Next() )
300  // {
301  // if( item->Type() != PCB_FP_SHAPE_T || item->GetLayer() != Edge_Cuts )
302  // continue;
303  // code to export cutouts
304  // }
305 
306  // Export pads
307  double drill, x, y;
308  double scale = aIDFBoard.GetUserScale();
309  IDF3::KEY_PLATING kplate;
310  std::string pintype;
311  std::string tstr;
312 
313  double dx, dy;
314 
315  aIDFBoard.GetUserOffset( dx, dy );
316 
317  for( auto pad : aFootprint->Pads() )
318  {
319  drill = (double) pad->GetDrillSize().x * scale;
320  x = pad->GetPosition().x * scale + dx;
321  y = -pad->GetPosition().y * scale + dy;
322 
323  // Export the hole on the edge layer
324  if( drill > 0.0 )
325  {
326  // plating
327  if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
328  kplate = IDF3::NPTH;
329  else
330  kplate = IDF3::PTH;
331 
332  // hole type
333  tstr = TO_UTF8( pad->GetName() );
334 
335  if( tstr.empty() || !tstr.compare( "0" ) || !tstr.compare( "~" )
336  || ( kplate == IDF3::NPTH )
337  || ( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ) )
338  pintype = "MTG";
339  else
340  pintype = "PIN";
341 
342  // fields:
343  // 1. hole dia. : float
344  // 2. X coord : float
345  // 3. Y coord : float
346  // 4. plating : PTH | NPTH
347  // 5. Assoc. part : BOARD | NOREFDES | PANEL | {"refdes"}
348  // 6. type : PIN | VIA | MTG | TOOL | { "other" }
349  // 7. owner : MCAD | ECAD | UNOWNED
350  if( ( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
351  && ( pad->GetDrillSize().x != pad->GetDrillSize().y ) )
352  {
353  // NOTE: IDF does not have direct support for slots;
354  // slots are implemented as a board cutout and we
355  // cannot represent plating or reference designators
356 
357  double dlength = pad->GetDrillSize().y * scale;
358 
359  // NOTE: The orientation of footprints and pads have
360  // the opposite sense due to KiCad drawing on a
361  // screen with a LH coordinate system
362  double angle = pad->GetOrientation() / 10.0;
363 
364  // NOTE: Since this code assumes the scenario where
365  // GetDrillSize().y is the length but idf_parser.cpp
366  // assumes a length along the X axis, the orientation
367  // must be shifted +90 deg when GetDrillSize().y is
368  // the major axis.
369 
370  if( dlength < drill )
371  {
372  std::swap( drill, dlength );
373  }
374  else
375  {
376  angle += 90.0;
377  }
378 
379  // NOTE: KiCad measures a slot's length from end to end
380  // rather than between the centers of the arcs
381  dlength -= drill;
382 
383  aIDFBoard.AddSlot( drill, dlength, angle, x, y );
384  }
385  else
386  {
387  IDF_DRILL_DATA *dp = new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
388  pintype, IDF3::ECAD );
389 
390  if( !aIDFBoard.AddDrill( dp ) )
391  {
392  delete dp;
393 
394  std::ostringstream ostr;
395  ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__;
396  ostr << "(): could not add drill";
397 
398  throw std::runtime_error( ostr.str() );
399  }
400  }
401  }
402  }
403 
404  // add any valid models to the library item list
405  std::string refdes;
406 
407  IDF3_COMPONENT* comp = NULL;
408 
409  auto sM = aFootprint->Models().begin();
410  auto eM = aFootprint->Models().end();
411  wxFileName idfFile;
412  wxString idfExt;
413 
414  while( sM != eM )
415  {
416  idfFile.Assign( resolver->ResolvePath( sM->m_Filename ) );
417  idfExt = idfFile.GetExt();
418 
419  if( idfExt.Cmp( wxT( "idf" ) ) && idfExt.Cmp( wxT( "IDF" ) ) )
420  {
421  ++sM;
422  continue;
423  }
424 
425  if( refdes.empty() )
426  {
427  refdes = TO_UTF8( aFootprint->Reference().GetShownText() );
428 
429  // NOREFDES cannot be used or else the software gets confused
430  // when writing out the placement data due to conflicting
431  // placement and layer specifications; to work around this we
432  // create a (hopefully) unique refdes for our exported part.
433  if( refdes.empty() || !refdes.compare( "~" ) )
434  refdes = aIDFBoard.GetNewRefDes();
435  }
436 
437  IDF3_COMP_OUTLINE* outline;
438 
439  outline = aIDFBoard.GetComponentOutline( idfFile.GetFullPath() );
440 
441  if( !outline )
442  throw( std::runtime_error( aIDFBoard.GetError() ) );
443 
444  double rotz = aFootprint->GetOrientation() / 10.0;
445  double locx = sM->m_Offset.x * 25.4; // part offsets are in inches
446  double locy = sM->m_Offset.y * 25.4;
447  double locz = sM->m_Offset.z * 25.4;
448  double lrot = sM->m_Rotation.z;
449 
450  bool top = ( aFootprint->GetLayer() == B_Cu ) ? false : true;
451 
452  if( top )
453  {
454  locy = -locy;
455  RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
456  locy = -locy;
457  }
458 
459  if( !top )
460  {
461  lrot = -lrot;
462  RotatePoint( &locx, &locy, aFootprint->GetOrientation() );
463  locy = -locy;
464 
465  rotz = 180.0 - rotz;
466 
467  if( rotz >= 360.0 )
468  while( rotz >= 360.0 ) rotz -= 360.0;
469 
470  if( rotz <= -360.0 )
471  while( rotz <= -360.0 ) rotz += 360.0;
472  }
473 
474  if( comp == NULL )
475  comp = aIDFBoard.FindComponent( refdes );
476 
477  if( comp == NULL )
478  {
479  comp = new IDF3_COMPONENT( &aIDFBoard );
480 
481  if( comp == NULL )
482  throw( std::runtime_error( aIDFBoard.GetError() ) );
483 
484  comp->SetRefDes( refdes );
485 
486  if( top )
487  {
488  comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
489  -aFootprint->GetPosition().y * scale + dy,
490  rotz, IDF3::LYR_TOP );
491  }
492  else
493  {
494  comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
495  -aFootprint->GetPosition().y * scale + dy,
496  rotz, IDF3::LYR_BOTTOM );
497  }
498 
499  comp->SetPlacement( IDF3::PS_ECAD );
500 
501  aIDFBoard.AddComponent( comp );
502  }
503  else
504  {
505  double refX, refY, refA;
506  IDF3::IDF_LAYER side;
507 
508  if( ! comp->GetPosition( refX, refY, refA, side ) )
509  {
510  // place the item
511  if( top )
512  {
513  comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
514  -aFootprint->GetPosition().y * scale + dy,
515  rotz, IDF3::LYR_TOP );
516  }
517  else
518  {
519  comp->SetPosition( aFootprint->GetPosition().x * scale + dx,
520  -aFootprint->GetPosition().y * scale + dy,
521  rotz, IDF3::LYR_BOTTOM );
522  }
523 
524  comp->SetPlacement( IDF3::PS_ECAD );
525 
526  }
527  else
528  {
529  // check that the retrieved component matches this one
530  refX = refX - ( aFootprint->GetPosition().x * scale + dx );
531  refY = refY - ( -aFootprint->GetPosition().y * scale + dy );
532  refA = refA - rotz;
533  refA *= refA;
534  refX *= refX;
535  refY *= refY;
536  refX += refY;
537 
538  // conditions: same side, X,Y coordinates within 10 microns,
539  // angle within 0.01 degree
540  if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
541  || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
542  {
543  comp->GetPosition( refX, refY, refA, side );
544 
545  std::ostringstream ostr;
546  ostr << "* " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
547  ostr << "* conflicting Reference Designator '" << refdes << "'\n";
548  ostr << "* X loc: " << ( aFootprint->GetPosition().x * scale + dx);
549  ostr << " vs. " << refX << "\n";
550  ostr << "* Y loc: " << ( -aFootprint->GetPosition().y * scale + dy);
551  ostr << " vs. " << refY << "\n";
552  ostr << "* angle: " << rotz;
553  ostr << " vs. " << refA << "\n";
554 
555  if( top )
556  ostr << "* TOP vs. ";
557  else
558  ostr << "* BOTTOM vs. ";
559 
560  if( side == IDF3::LYR_TOP )
561  ostr << "TOP";
562  else
563  ostr << "BOTTOM";
564 
565  throw( std::runtime_error( ostr.str() ) );
566  }
567  }
568  }
569 
570 
571  // create the local data ...
572  IDF3_COMP_OUTLINE_DATA* data = new IDF3_COMP_OUTLINE_DATA( comp, outline );
573 
574  data->SetOffsets( locx, locy, locz, lrot );
575  comp->AddOutlineData( data );
576  ++sM;
577  }
578 }
579 
580 
586 bool PCB_EDIT_FRAME::Export_IDF3( BOARD* aPcb, const wxString& aFullFileName,
587  bool aUseThou, double aXRef, double aYRef )
588 {
589  IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
590 
591  // Switch the locale to standard C (needed to print floating point numbers)
592  LOCALE_IO toggle;
593 
594  resolver = Prj().Get3DCacheManager()->GetResolver();
595 
596  bool ok = true;
597  double scale = MM_PER_IU; // we must scale internal units to mm for IDF
598  IDF3::IDF_UNIT idfUnit;
599 
600  if( aUseThou )
601  {
602  idfUnit = IDF3::UNIT_THOU;
603  idfBoard.SetUserPrecision( 1 );
604  }
605  else
606  {
607  idfUnit = IDF3::UNIT_MM;
608  idfBoard.SetUserPrecision( 5 );
609  }
610 
611  wxFileName brdName = aPcb->GetFileName();
612 
613  idfBoard.SetUserScale( scale );
614  idfBoard.SetBoardThickness( aPcb->GetDesignSettings().GetBoardThickness() * scale );
615  idfBoard.SetBoardName( TO_UTF8( brdName.GetFullName() ) );
616  idfBoard.SetBoardVersion( 0 );
617  idfBoard.SetLibraryVersion( 0 );
618 
619  std::ostringstream ostr;
620  ostr << "KiCad " << TO_UTF8( GetBuildVersion() );
621  idfBoard.SetIDFSource( ostr.str() );
622 
623  try
624  {
625  // set up the board reference point
626  idfBoard.SetUserOffset( -aXRef, aYRef );
627 
628  // Export the board outline
629  idf_export_outline( aPcb, idfBoard );
630 
631  // Output the drill holes and footprint (library) data.
632  for( FOOTPRINT* footprint : aPcb->Footprints() )
633  idf_export_footprint( aPcb, footprint, idfBoard );
634 
635  if( !idfBoard.WriteFile( aFullFileName, idfUnit, false ) )
636  {
637  wxString msg;
638  msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( idfBoard.GetError().c_str() );
639  wxMessageBox( msg );
640 
641  ok = false;
642  }
643  }
644  catch( const IO_ERROR& ioe )
645  {
646  wxString msg;
647  msg << _( "IDF Export Failed:\n" ) << ioe.What();
648  wxMessageBox( msg );
649 
650  ok = false;
651  }
652  catch( const std::exception& e )
653  {
654  wxString msg;
655  msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( e.what() );
656  wxMessageBox( msg );
657  ok = false;
658  }
659 
660  return ok;
661 }
std::list< FP_3DMODEL > & Models()
Definition: footprint.h:178
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
Definition: pcb_shape.h:156
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
const EDA_RECT GetBoardEdgesBoundingBox() const
Returns the board bounding box calculated using exclusively the board edges (graphics on Edge....
Definition: board.h:812
static void idf_export_outline(BOARD *aPcb, IDF3_BOARD &aIDFBoard)
Function idf_export_outline retrieves line segment information from the edge layer and compiles the d...
Definition: export_idf.cpp:59
PCB_SHAPE_TYPE GetShape() const
Definition: pcb_shape.h:130
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
Definition: pcb_shape.h:201
bool Export_IDF3(BOARD *aPcb, const wxString &aFullFileName, bool aUseThou, double aXRef, double aYRef)
Create an IDF3 compliant BOARD (*.emn) and LIBRARY (*.emp) file.
Definition: export_idf.cpp:586
double GetOrientation() const
Definition: footprint.h:186
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
const wxString & GetFileName() const
Definition: board.h:300
PADS & Pads()
Definition: footprint.h:164
This file contains miscellaneous commonly used macros and functions.
wxPoint GetArcStart() const
Definition: pcb_shape.h:179
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:462
FP_TEXT & Reference()
Definition: footprint.h:463
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
like PAD_PTH, but not plated
#define NULL
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
wxString GetBuildVersion()
Get the full KiCad version string.
const wxPoint GetOrigin() const
Definition: eda_rect.h:106
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
segment with non rounded ends
FOOTPRINTS & Footprints()
Definition: board.h:305
wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.cpp:342
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Definition: pcb_shape.h:145
static void idf_export_footprint(BOARD *aPcb, FOOTPRINT *aFootprint, IDF3_BOARD &aIDFBoard)
Function idf_export_footprint retrieves information from all board footprints, adds drill holes to th...
Definition: export_idf.cpp:281
wxString ResolvePath(const wxString &aFileName)
Determines the full path of the given file name.
const int scale
Provide an extensible class to resolve 3D model paths.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
double GetAngle() const
Definition: pcb_shape.h:127
Handle the component boundary box.
Definition: eda_rect.h:42
usual segment : line with rounded ends
wxPoint GetPosition() const override
Definition: footprint.h:182
#define UNIT_MM
Definition: units_scales.h:31
static FILENAME_RESOLVER * resolver
Definition: export_idf.cpp:51
Arcs (with rounded ends)
virtual wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: fp_text.cpp:398
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
DRAWINGS & Drawings()
Definition: board.h:308
const wxSize GetSize() const
Definition: eda_rect.h:96
#define LINE_WIDTH
Definition: export_idf.cpp:49