KiCad PCB EDA Suite
export_gencad.cpp File Reference

Export GenCAD 1.4 format. More...

#include <fctsys.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <gestfich.h>
#include <pgm_base.h>
#include <pcb_edit_frame.h>
#include <trigo.h>
#include <build_version.h>
#include <macros.h>
#include <pcbnew.h>
#include <dialogs/dialog_gencad_export_options.h>
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_edge_mod.h>
#include <hash_eda.h>

Go to the source code of this file.

Functions

static bool CreateHeaderInfoData (FILE *aFile, PCB_EDIT_FRAME *frame)
 
static void CreateArtworksSection (FILE *aFile)
 
static void CreateTracksInfoData (FILE *aFile, BOARD *aPcb)
 
static void CreateBoardSection (FILE *aFile, BOARD *aPcb)
 
static void CreateComponentsSection (FILE *aFile, BOARD *aPcb)
 
static void CreateDevicesSection (FILE *aFile, BOARD *aPcb)
 
static void CreateRoutesSection (FILE *aFile, BOARD *aPcb)
 
static void CreateSignalsSection (FILE *aFile, BOARD *aPcb)
 
static void CreateShapesSection (FILE *aFile, BOARD *aPcb)
 
static void CreatePadsShapesSection (FILE *aFile, BOARD *aPcb)
 
static void FootprintWriteShape (FILE *File, MODULE *module, const wxString &aShapeName)
 
static std::string GenCADLayerName (int aCuCount, PCB_LAYER_ID aId)
 
static std::string GenCADLayerNameFlipped (int aCuCount, PCB_LAYER_ID aId)
 
static wxString escapeString (const wxString &aString)
 
static std::string fmt_mask (LSET aSet)
 
static const wxString & getShapeName (MODULE *aModule)
 
static double MapXTo (int aX)
 
static double MapYTo (int aY)
 
static int PadListSortByShape (const void *aRefptr, const void *aObjptr)
 
static int ViaSort (const void *aRefptr, const void *aObjptr)
 
static size_t hashModule (const MODULE *aModule)
 Compute hashes for modules without taking into account their position, rotation or layer. More...
 
static int TrackListSortByNetcode (const void *refptr, const void *objptr)
 

Variables

static const PCB_LAYER_ID gc_seq []
 
static bool flipBottomPads
 
static bool uniquePins
 
static bool individualShapes
 
static bool storeOriginCoords
 
static int GencadOffsetX
 
static int GencadOffsetY
 
static std::map< MODULE *, int > componentShapes
 
static std::map< int, wxString > shapeNames
 
static const double SCALE_FACTOR = 1000.0 * IU_PER_MILS
 

Detailed Description

Export GenCAD 1.4 format.

Definition in file export_gencad.cpp.

Function Documentation

static void CreateArtworksSection ( FILE *  aFile)
static

Definition at line 400 of file export_gencad.cpp.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

401 {
402  /* The artworks section is empty */
403  fputs( "$ARTWORKS\n", aFile );
404  fputs( "$ENDARTWORKS\n\n", aFile );
405 }
static void CreateBoardSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 1183 of file export_gencad.cpp.

References BOARD::Drawings(), Edge_Cuts, DRAWSEGMENT::GetEnd(), BOARD_ITEM::GetLayer(), DRAWSEGMENT::GetStart(), MapXTo(), MapYTo(), PCB_LINE_T, wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

1184 {
1185  fputs( "$BOARD\n", aFile );
1186 
1187  // Extract the board edges
1188  for( auto drawing : aPcb->Drawings() )
1189  {
1190  if( drawing->Type() == PCB_LINE_T )
1191  {
1192  DRAWSEGMENT* drawseg = static_cast<DRAWSEGMENT*>( drawing );
1193  if( drawseg->GetLayer() == Edge_Cuts )
1194  {
1195  // XXX GenCAD supports arc boundaries but I've seen nothing that reads them
1196  fprintf( aFile, "LINE %g %g %g %g\n",
1197  MapXTo( drawseg->GetStart().x ), MapYTo( drawseg->GetStart().y ),
1198  MapXTo( drawseg->GetEnd().x ), MapYTo( drawseg->GetEnd().y ) );
1199  }
1200  }
1201  }
1202 
1203  fputs( "$ENDBOARD\n\n", aFile );
1204 }
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
static double MapYTo(int aY)
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:255
static double MapXTo(int aX)
static void CreateComponentsSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 855 of file export_gencad.cpp.

References B_SilkS, escapeString(), F_SilkS, GenCADLayerName(), BOARD::GetCopperLayerCount(), TEXTE_MODULE::GetLength(), TEXTE_MODULE::GetPos0(), getShapeName(), EDA_TEXT::GetText(), EDA_TEXT::GetTextAngle(), EDA_TEXT::GetTextHeight(), EDA_TEXT::GetTextWidth(), BOARD::m_Modules, MapXTo(), MapYTo(), NEGATE_AND_NORMALIZE_ANGLE_POS(), MODULE::Next(), SCALE_FACTOR, TO_UTF8, wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

856 {
857  fputs( "$COMPONENTS\n", aFile );
858 
859  int cu_count = aPcb->GetCopperLayerCount();
860 
861  for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
862  {
863  const char* mirror;
864  const char* flip;
865  double fp_orient = module->GetOrientation();
866 
867  if( module->GetFlag() )
868  {
869  mirror = "MIRRORX";
870  flip = "FLIP";
871  NEGATE_AND_NORMALIZE_ANGLE_POS( fp_orient );
872  }
873  else
874  {
875  mirror = "0";
876  flip = "0";
877  }
878 
879  fprintf( aFile, "\nCOMPONENT \"%s\"\n",
880  TO_UTF8( escapeString( module->GetReference() ) ) );
881  fprintf( aFile, "DEVICE \"DEV_%s\"\n",
882  TO_UTF8( escapeString( getShapeName( module ) ) ) );
883  fprintf( aFile, "PLACE %g %g\n",
884  MapXTo( module->GetPosition().x ),
885  MapYTo( module->GetPosition().y ) );
886  fprintf( aFile, "LAYER %s\n",
887  module->GetFlag() ? "BOTTOM" : "TOP" );
888  fprintf( aFile, "ROTATION %g\n",
889  fp_orient / 10.0 );
890  fprintf( aFile, "SHAPE \"%s\" %s %s\n",
891  TO_UTF8( escapeString( getShapeName( module ) ) ),
892  mirror, flip );
893 
894  // Text on silk layer: RefDes and value (are they actually useful?)
895  TEXTE_MODULE *textmod = &module->Reference();
896 
897  for( int ii = 0; ii < 2; ii++ )
898  {
899  double txt_orient = textmod->GetTextAngle();
900  std::string layer = GenCADLayerName( cu_count, module->GetFlag() ? B_SilkS : F_SilkS );
901 
902  fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"",
903  textmod->GetPos0().x / SCALE_FACTOR,
904  -textmod->GetPos0().y / SCALE_FACTOR,
905  textmod->GetTextWidth() / SCALE_FACTOR,
906  txt_orient / 10.0,
907  mirror,
908  layer.c_str(),
909  TO_UTF8( escapeString( textmod->GetText() ) ) );
910 
911  // Please note, the width is approx
912  fprintf( aFile, " 0 0 %g %g\n",
913  ( textmod->GetTextWidth() * textmod->GetLength() ) / SCALE_FACTOR,
914  textmod->GetTextHeight() / SCALE_FACTOR );
915 
916  textmod = &module->Value(); // Dirty trick for the second iteration
917  }
918 
919  // The SHEET is a 'generic description' for referencing the component
920  fprintf( aFile, "SHEET \"RefDes: %s, Value: %s\"\n",
921  TO_UTF8( module->GetReference() ),
922  TO_UTF8( module->GetValue() ) );
923  }
924 
925  fputs( "$ENDCOMPONENTS\n\n", aFile );
926 }
int GetLength() const
const wxPoint & GetPos0() const
int GetTextWidth() const
Definition: eda_text.h:231
MODULE * Next() const
Definition: class_module.h:123
int GetCopperLayerCount() const
Function GetCopperLayerCount.
static double MapYTo(int aY)
static wxString escapeString(const wxString &aString)
double GetTextAngle() const
Definition: eda_text.h:177
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
static std::string GenCADLayerName(int aCuCount, PCB_LAYER_ID aId)
void NEGATE_AND_NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:305
DLIST< MODULE > m_Modules
Definition: class_board.h:248
static const double SCALE_FACTOR
int GetTextHeight() const
Definition: eda_text.h:234
static const wxString & getShapeName(MODULE *aModule)
static double MapXTo(int aX)
static void CreateDevicesSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 1145 of file export_gencad.cpp.

References componentShapes, escapeString(), LIB_ID::Format(), MODULE::GetAttributes(), MODULE::GetFPID(), MODULE::GetValue(), MOD_CMS, MOD_VIRTUAL, shapeNames, and TO_UTF8.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

1146 {
1147  std::set<wxString> emitted;
1148  fputs( "$DEVICES\n", aFile );
1149 
1150  for( const auto& componentShape : componentShapes )
1151  {
1152  const wxString& shapeName = shapeNames[componentShape.second];
1153  bool newDevice;
1154  std::tie( std::ignore, newDevice ) = emitted.insert( shapeName );
1155 
1156  if( !newDevice ) // do not repeat device definitions
1157  continue;
1158 
1159  const MODULE* module = componentShape.first;
1160  fprintf( aFile, "\nDEVICE \"DEV_%s\"\n", TO_UTF8( escapeString( shapeName ) ) );
1161  fprintf( aFile, "PART \"%s\"\n", TO_UTF8( escapeString( module->GetValue() ) ) );
1162  fprintf( aFile, "PACKAGE \"%s\"\n", TO_UTF8( escapeString( module->GetFPID().Format() ) ) );
1163 
1164  // The TYPE attribute is almost freeform
1165  const char* ty = "TH";
1166 
1167  if( module->GetAttributes() & MOD_CMS )
1168  ty = "SMD";
1169 
1170  if( module->GetAttributes() & MOD_VIRTUAL )
1171  ty = "VIRTUAL";
1172 
1173  fprintf( aFile, "TYPE %s\n", ty );
1174  }
1175 
1176  fputs( "$ENDDEVICES\n\n", aFile );
1177 }
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:77
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:497
static wxString escapeString(const wxString &aString)
const LIB_ID & GetFPID() const
Definition: class_module.h:193
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
int GetAttributes() const
Definition: class_module.h:226
Virtual component: when created by copper shapes on board (Like edge card connectors, mounting hole...)
Definition: class_module.h:79
UTF8 Format() const
Definition: lib_id.cpp:237
static std::map< MODULE *, int > componentShapes
static std::map< int, wxString > shapeNames
static bool CreateHeaderInfoData ( FILE *  aFile,
PCB_EDIT_FRAME frame 
)
static

Definition at line 980 of file export_gencad.cpp.

References PCB_BASE_FRAME::GetBoard(), GetBuildVersion(), GetChars(), TITLE_BLOCK::GetDate(), BOARD::GetFileName(), TITLE_BLOCK::GetRevision(), PCB_BASE_FRAME::GetTitleBlock(), MapXTo(), MapYTo(), Pgm(), storeOriginCoords, and TO_UTF8.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

981 {
982  wxString msg;
983  BOARD *board = aFrame->GetBoard();
984 
985  fputs( "$HEADER\n", aFile );
986  fputs( "GENCAD 1.4\n", aFile );
987 
988  // Please note: GenCAD syntax requires quoted strings if they can contain spaces
989  msg.Printf( wxT( "USER \"%s %s\"\n" ),
990  GetChars( Pgm().App().GetAppName() ),
991  GetChars( GetBuildVersion() ) );
992  fputs( TO_UTF8( msg ), aFile );
993 
994  msg = wxT( "DRAWING \"" ) + board->GetFileName() + wxT( "\"\n" );
995  fputs( TO_UTF8( msg ), aFile );
996 
997  const TITLE_BLOCK& tb = aFrame->GetTitleBlock();
998 
999  msg = wxT( "REVISION \"" ) + tb.GetRevision() + wxT( " " ) + tb.GetDate() + wxT( "\"\n" );
1000 
1001  fputs( TO_UTF8( msg ), aFile );
1002  fputs( "UNITS INCH\n", aFile );
1003 
1004  // giving 0 as the argument to Map{X,Y}To returns the scaled origin point
1005  msg.Printf( wxT( "ORIGIN %g %g\n" ),
1006  storeOriginCoords ? MapXTo( 0 ) : 0,
1007  storeOriginCoords ? MapYTo( 0 ) : 0 );
1008  fputs( TO_UTF8( msg ), aFile );
1009 
1010  fputs( "INTERTRACK 0\n", aFile );
1011  fputs( "$ENDHEADER\n\n", aFile );
1012 
1013  return true;
1014 }
static double MapYTo(int aY)
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:66
const wxString & GetDate() const
Definition: title_block.h:79
Class TITLE_BLOCK holds the information shown in the lower right corner of a plot, printout, or editing view.
Definition: title_block.h:40
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
const wxString & GetFileName() const
Definition: class_board.h:237
const wxString & GetRevision() const
Definition: title_block.h:89
static bool storeOriginCoords
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
static double MapXTo(int aX)
static void CreatePadsShapesSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 410 of file export_gencad.cpp.

References D_PAD::BuildPadPolygon(), D_PAD::Compare(), SHAPE_LINE_CHAIN::CPoint(), DIM, flipBottomPads, fmt_mask(), gc_seq, GenCADLayerName(), GenCADLayerNameFlipped(), BOARD::GetCopperLayerCount(), D_PAD::GetCustomShapeAsPolygon(), BOARD::GetDesignSettings(), D_PAD::GetDrillSize(), VIA::GetDrillValue(), BOARD_DESIGN_SETTINGS::GetEnabledLayers(), GetFirstVia(), VIA::GetLayerSet(), D_PAD::GetLayerSet(), D_PAD::GetOffset(), BOARD::GetPadCount(), BOARD::GetPads(), D_PAD::GetRoundRectCornerRadius(), D_PAD::GetShape(), D_PAD::GetSize(), D_PAD::GetSubRatsnest(), TRACK::GetWidth(), i, BOARD::m_Track, min, next(), PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, PadListSortByShape(), SHAPE_LINE_CHAIN::PointCount(), SCALE_FACTOR, LSET::Seq(), D_PAD::SetSubRatsnest(), ViaSort(), wxPoint::x, VECTOR2< T >::x, wxPoint::y, and VECTOR2< T >::y.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

411 {
412  std::vector<D_PAD*> pads;
413  std::vector<D_PAD*> padstacks;
414  std::vector<VIA*> vias;
415  std::vector<VIA*> viastacks;
416 
417  padstacks.resize( 1 ); // We count pads from 1
418 
419  // The master layermask (i.e. the enabled layers) for padstack generation
420  LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
421  int cu_count = aPcb->GetCopperLayerCount();
422 
423  fputs( "$PADS\n", aFile );
424 
425  // Enumerate and sort the pads
426  if( aPcb->GetPadCount() > 0 )
427  {
428  pads = aPcb->GetPads();
429  qsort( &pads[0], aPcb->GetPadCount(), sizeof( D_PAD* ),
431  }
432 
433  // The same for vias
434  for( VIA* via = GetFirstVia( aPcb->m_Track ); via;
435  via = GetFirstVia( via->Next() ) )
436  {
437  vias.push_back( via );
438  }
439 
440  qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort );
441 
442  // Emit vias pads
443  TRACK* old_via = 0;
444 
445  for( unsigned i = 0; i < vias.size(); i++ )
446  {
447  VIA* via = vias[i];
448 
449  if( old_via && 0 == ViaSort( &old_via, &via ) )
450  continue;
451 
452  old_via = via;
453  viastacks.push_back( via );
454  fprintf( aFile, "PAD V%d.%d.%s ROUND %g\nCIRCLE 0 0 %g\n",
455  via->GetWidth(), via->GetDrillValue(),
456  fmt_mask( via->GetLayerSet() & master_layermask ).c_str(),
457  via->GetDrillValue() / SCALE_FACTOR,
458  via->GetWidth() / (SCALE_FACTOR * 2) );
459  }
460 
461  // Emit component pads
462  D_PAD* old_pad = 0;
463  int pad_name_number = 0;
464 
465  for( unsigned i = 0; i<pads.size(); ++i )
466  {
467  D_PAD* pad = pads[i];
468  const wxPoint& off = pad->GetOffset();
469 
470  pad->SetSubRatsnest( pad_name_number );
471 
472  if( old_pad && 0==D_PAD::Compare( old_pad, pad ) )
473  continue; // already created
474 
475  old_pad = pad;
476 
477  pad_name_number++;
478  pad->SetSubRatsnest( pad_name_number );
479 
480  fprintf( aFile, "PAD P%d", pad->GetSubRatsnest() );
481 
482  padstacks.push_back( pad ); // Will have its own padstack later
483  int dx = pad->GetSize().x / 2;
484  int dy = pad->GetSize().y / 2;
485 
486  switch( pad->GetShape() )
487  {
488  default:
489  wxASSERT_MSG( false, "Pad type not implemented" );
490  // fall-through
491 
492  case PAD_SHAPE_CIRCLE:
493  fprintf( aFile, " ROUND %g\n",
494  pad->GetDrillSize().x / SCALE_FACTOR );
495  /* Circle is center, radius */
496  fprintf( aFile, "CIRCLE %g %g %g\n",
497  off.x / SCALE_FACTOR,
498  -off.y / SCALE_FACTOR,
499  pad->GetSize().x / (SCALE_FACTOR * 2) );
500  break;
501 
502  case PAD_SHAPE_RECT:
503  fprintf( aFile, " RECTANGULAR %g\n",
504  pad->GetDrillSize().x / SCALE_FACTOR );
505 
506  // Rectangle is begin, size *not* begin, end!
507  fprintf( aFile, "RECTANGLE %g %g %g %g\n",
508  (-dx + off.x ) / SCALE_FACTOR,
509  (-dy - off.y ) / SCALE_FACTOR,
510  dx / (SCALE_FACTOR / 2), dy / (SCALE_FACTOR / 2) );
511  break;
512 
513  case PAD_SHAPE_ROUNDRECT:
514  case PAD_SHAPE_OVAL:
515  {
516  const wxSize& size = pad->GetSize();
517  int radius;
518 
519  if( pad->GetShape() == PAD_SHAPE_ROUNDRECT )
520  radius = pad->GetRoundRectCornerRadius();
521  else
522  radius = std::min( size.x, size.y ) / 2;
523 
524  int lineX = size.x / 2 - radius;
525  int lineY = size.y / 2 - radius;
526 
527  fprintf( aFile, " POLYGON %g\n", pad->GetDrillSize().x / SCALE_FACTOR );
528 
529  // bottom left arc
530  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
531  ( off.x - lineX - radius ) / SCALE_FACTOR,
532  ( -off.y - lineY ) / SCALE_FACTOR, ( off.x - lineX ) / SCALE_FACTOR,
533  ( -off.y - lineY - radius ) / SCALE_FACTOR,
534  ( off.x - lineX ) / SCALE_FACTOR, ( -off.y - lineY ) / SCALE_FACTOR );
535 
536  // bottom line
537  if( lineX > 0 )
538  {
539  fprintf( aFile, "LINE %g %g %g %g\n",
540  ( off.x - lineX ) / SCALE_FACTOR,
541  ( -off.y - lineY - radius ) / SCALE_FACTOR,
542  ( off.x + lineX ) / SCALE_FACTOR,
543  ( -off.y - lineY - radius ) / SCALE_FACTOR );
544  }
545 
546  // bottom right arc
547  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
548  ( off.x + lineX ) / SCALE_FACTOR,
549  ( -off.y - lineY - radius ) / SCALE_FACTOR,
550  ( off.x + lineX + radius ) / SCALE_FACTOR,
551  ( -off.y - lineY ) / SCALE_FACTOR, ( off.x + lineX ) / SCALE_FACTOR,
552  ( -off.y - lineY ) / SCALE_FACTOR );
553 
554  // right line
555  if( lineY > 0 )
556  {
557  fprintf( aFile, "LINE %g %g %g %g\n",
558  ( off.x + lineX + radius ) / SCALE_FACTOR,
559  ( -off.y + lineY ) / SCALE_FACTOR,
560  ( off.x + lineX + radius ) / SCALE_FACTOR,
561  ( -off.y - lineY ) / SCALE_FACTOR );
562  }
563 
564  // top right arc
565  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
566  ( off.x + lineX + radius ) / SCALE_FACTOR,
567  ( -off.y + lineY ) / SCALE_FACTOR, ( off.x + lineX ) / SCALE_FACTOR,
568  ( -off.y + lineY + radius ) / SCALE_FACTOR,
569  ( off.x + lineX ) / SCALE_FACTOR, ( -off.y + lineY ) / SCALE_FACTOR );
570 
571  // top line
572  if( lineX > 0 )
573  {
574  fprintf( aFile, "LINE %g %g %g %g\n"
575  , ( off.x - lineX ) / SCALE_FACTOR,
576  ( -off.y + lineY + radius ) / SCALE_FACTOR,
577  ( off.x + lineX ) / SCALE_FACTOR,
578  ( -off.y + lineY + radius ) / SCALE_FACTOR );
579  }
580 
581  // top left arc
582  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
583  ( off.x - lineX ) / SCALE_FACTOR,
584  ( -off.y + lineY + radius ) / SCALE_FACTOR,
585  ( off.x - lineX - radius ) / SCALE_FACTOR,
586  ( -off.y + lineY ) / SCALE_FACTOR, ( off.x - lineX ) / SCALE_FACTOR,
587  ( -off.y + lineY ) / SCALE_FACTOR );
588 
589  // left line
590  if( lineY > 0 )
591  {
592  fprintf( aFile, "LINE %g %g %g %g\n",
593  ( off.x - lineX - radius ) / SCALE_FACTOR,
594  ( -off.y - lineY ) / SCALE_FACTOR,
595  ( off.x - lineX - radius ) / SCALE_FACTOR,
596  ( -off.y + lineY ) / SCALE_FACTOR );
597  }
598  }
599  break;
600 
601  case PAD_SHAPE_TRAPEZOID:
602  {
603  fprintf( aFile, " POLYGON %g\n", pad->GetDrillSize().x / SCALE_FACTOR );
604 
605  wxPoint poly[4];
606  pad->BuildPadPolygon( poly, wxSize( 0, 0 ), 0 );
607 
608  for( int cur = 0; cur < 4; ++cur )
609  {
610  int next = ( cur + 1 ) % 4;
611  fprintf( aFile, "LINE %g %g %g %g\n",
612  ( off.x + poly[cur].x ) / SCALE_FACTOR,
613  ( -off.y - poly[cur].y ) / SCALE_FACTOR,
614  ( off.x + poly[next].x ) / SCALE_FACTOR,
615  ( -off.y - poly[next].y ) / SCALE_FACTOR );
616  }
617  }
618  break;
619 
620  case PAD_SHAPE_CUSTOM:
621  {
622  fprintf( aFile, " POLYGON %g\n", pad->GetDrillSize().x / SCALE_FACTOR );
623 
624  const SHAPE_POLY_SET& outline = pad->GetCustomShapeAsPolygon();
625 
626  for( int jj = 0; jj < outline.OutlineCount(); ++jj )
627  {
628  const SHAPE_LINE_CHAIN& poly = outline.COutline( jj );
629  int pointCount = poly.PointCount();
630 
631  for( int ii = 0; ii < pointCount; ii++ )
632  {
633  int next = ( ii + 1 ) % pointCount;
634  fprintf( aFile, "LINE %g %g %g %g\n",
635  ( off.x + poly.CPoint( ii ).x ) / SCALE_FACTOR,
636  ( -off.y - poly.CPoint( ii ).y ) / SCALE_FACTOR,
637  ( off.x + poly.CPoint( next ).x ) / SCALE_FACTOR,
638  ( -off.y - poly.CPoint( next ).y ) / SCALE_FACTOR );
639  }
640  }
641  }
642  break;
643  }
644  }
645 
646  fputs( "\n$ENDPADS\n\n", aFile );
647 
648  // Now emit the padstacks definitions, using the combined layer masks
649  fputs( "$PADSTACKS\n", aFile );
650 
651  // Via padstacks
652  for( unsigned i = 0; i < viastacks.size(); i++ )
653  {
654  VIA* via = viastacks[i];
655 
656  LSET mask = via->GetLayerSet() & master_layermask;
657 
658  fprintf( aFile, "PADSTACK VIA%d.%d.%s %g\n",
659  via->GetWidth(), via->GetDrillValue(),
660  fmt_mask( mask ).c_str(),
661  via->GetDrillValue() / SCALE_FACTOR );
662 
663  for( LSEQ seq = mask.Seq( gc_seq, DIM( gc_seq ) ); seq; ++seq )
664  {
665  PCB_LAYER_ID layer = *seq;
666 
667  fprintf( aFile, "PAD V%d.%d.%s %s 0 0\n",
668  via->GetWidth(), via->GetDrillValue(),
669  fmt_mask( mask ).c_str(),
670  GenCADLayerName( cu_count, layer ).c_str()
671  );
672  }
673  }
674 
675  /* Component padstacks
676  * Older versions of CAM350 don't apply correctly the FLIP semantics for
677  * padstacks, i.e. doesn't swap the top and bottom layers... so I need to
678  * define the shape as MIRRORX and define a separate 'flipped' padstack...
679  * until it appears yet another noncompliant importer */
680  for( unsigned i = 1; i < padstacks.size(); i++ )
681  {
682  D_PAD* pad = padstacks[i];
683 
684  // Straight padstack
685  fprintf( aFile, "PADSTACK PAD%u %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
686 
687  LSET pad_set = pad->GetLayerSet() & master_layermask;
688 
689  // the special gc_seq
690  for( LSEQ seq = pad_set.Seq( gc_seq, DIM( gc_seq ) ); seq; ++seq )
691  {
692  PCB_LAYER_ID layer = *seq;
693 
694  fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerName( cu_count, layer ).c_str() );
695  }
696 
697  // Flipped padstack
698  if( flipBottomPads )
699  {
700  fprintf( aFile, "PADSTACK PAD%uF %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
701 
702  // the normal PCB_LAYER_ID sequence is inverted from gc_seq[]
703  for( LSEQ seq = pad_set.Seq(); seq; ++seq )
704  {
705  PCB_LAYER_ID layer = *seq;
706 
707  fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerNameFlipped( cu_count, layer ).c_str() );
708  }
709  }
710  }
711 
712  fputs( "$ENDPADSTACKS\n\n", aFile );
713 }
CITER next(CITER it)
Definition: ptree.cpp:130
#define DIM(x)
of elements in an array
Definition: macros.h:98
static int PadListSortByShape(const void *aRefptr, const void *aObjptr)
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
static int ViaSort(const void *aRefptr, const void *aObjptr)
const SHAPE_POLY_SET & GetCustomShapeAsPolygon() const
Accessor to the custom shape as one polygon.
Definition: class_pad.h:341
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
int PointCount() const
Function PointCount()
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:528
int GetCopperLayerCount() const
Function GetCopperLayerCount.
void SetSubRatsnest(int aSubRatsnest)
Definition: class_pad.h:656
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
static bool flipBottomPads
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:364
static std::string GenCADLayerNameFlipped(int aCuCount, PCB_LAYER_ID aId)
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
Class SHAPE_POLY_SET.
int GetSubRatsnest() const
Function GetSubRatsnest.
Definition: class_pad.h:655
static int Compare(const D_PAD *padref, const D_PAD *padcmp)
Function Compare compares two pads and return 0 if they are equal.
Definition: class_pad.cpp:1104
static const PCB_LAYER_ID gc_seq[]
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:402
const wxSize & GetSize() const
Definition: class_pad.h:269
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:538
unsigned GetPadCount()
Function GetPadCount.
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
static std::string GenCADLayerName(int aCuCount, PCB_LAYER_ID aId)
const std::vector< D_PAD * > GetPads()
Function GetPads returns a reference to a list of all the pads.
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Class SHAPE_LINE_CHAIN.
int GetWidth() const
Definition: class_track.h:116
size_t i
Definition: json11.cpp:597
static const double SCALE_FACTOR
DLIST< TRACK > m_Track
Definition: class_board.h:249
static std::string fmt_mask(LSET aSet)
LSET GetEnabledLayers() const
Function GetEnabledLayers returns a bit-mask of all the layers that are enabled.
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
const wxPoint & GetOffset() const
Definition: class_pad.h:278
#define min(a, b)
Definition: auxiliary.h:85
VIA * GetFirstVia(TRACK *aTrk, const TRACK *aStopPoint=NULL)
Scan a track list for the first VIA o NULL if not found (or NULL passed)
Definition: class_track.h:507
static void CreateRoutesSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 1051 of file export_gencad.cpp.

References escapeString(), fmt_mask(), GenCADLayerName(), BOARD::GetCopperLayerCount(), BOARD::GetDesignSettings(), VIA::GetDrillValue(), BOARD_DESIGN_SETTINGS::GetEnabledLayers(), TRACK::GetEnd(), BOARD_ITEM::GetLayer(), VIA::GetLayerSet(), BOARD_CONNECTED_ITEM::GetNet(), BOARD_CONNECTED_ITEM::GetNetCode(), NETINFO_ITEM::GetNetname(), TRACK::GetStart(), TRACK::GetWidth(), BOARD::m_Track, MapXTo(), MapYTo(), TRACK::Next(), PCB_SEGZONE_T, PCB_TRACE_T, PCB_VIA_T, SCALE_FACTOR, TO_UTF8, TrackListSortByNetcode(), EDA_ITEM::Type(), vset(), wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

1052 {
1053  TRACK* track, ** tracklist;
1054  int vianum = 1;
1055  int old_netcode, old_width, old_layer;
1056  int nbitems, ii;
1057  LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
1058 
1059  int cu_count = aPcb->GetCopperLayerCount();
1060 
1061  // Count items
1062  nbitems = 0;
1063 
1064  for( track = aPcb->m_Track; track; track = track->Next() )
1065  nbitems++;
1066 
1067  tracklist = (TRACK**) operator new( (nbitems + 1)* sizeof( TRACK* ) );
1068 
1069  nbitems = 0;
1070 
1071  for( track = aPcb->m_Track; track; track = track->Next() )
1072  tracklist[nbitems++] = track;
1073 
1074  tracklist[nbitems] = NULL;
1075 
1076  qsort( tracklist, nbitems, sizeof(TRACK*), TrackListSortByNetcode );
1077 
1078  fputs( "$ROUTES\n", aFile );
1079 
1080  old_netcode = -1; old_width = -1; old_layer = -1;
1081 
1082  for( ii = 0; ii < nbitems; ii++ )
1083  {
1084  track = tracklist[ii];
1085 
1086  if( old_netcode != track->GetNetCode() )
1087  {
1088  old_netcode = track->GetNetCode();
1089  NETINFO_ITEM* net = track->GetNet();
1090  wxString netname;
1091 
1092  if( net && (net->GetNetname() != wxEmptyString) )
1093  netname = net->GetNetname();
1094  else
1095  netname = wxT( "_noname_" );
1096 
1097  fprintf( aFile, "ROUTE \"%s\"\n", TO_UTF8( escapeString( netname ) ) );
1098  }
1099 
1100  if( old_width != track->GetWidth() )
1101  {
1102  old_width = track->GetWidth();
1103  fprintf( aFile, "TRACK TRACK%d\n", track->GetWidth() );
1104  }
1105 
1106  if( (track->Type() == PCB_TRACE_T) || (track->Type() == PCB_SEGZONE_T) )
1107  {
1108  if( old_layer != track->GetLayer() )
1109  {
1110  old_layer = track->GetLayer();
1111  fprintf( aFile, "LAYER %s\n",
1112  GenCADLayerName( cu_count, track->GetLayer() ).c_str()
1113  );
1114  }
1115 
1116  fprintf( aFile, "LINE %g %g %g %g\n",
1117  MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ),
1118  MapXTo( track->GetEnd().x ), MapYTo( track->GetEnd().y ) );
1119  }
1120 
1121  if( track->Type() == PCB_VIA_T )
1122  {
1123  const VIA* via = static_cast<const VIA*>(track);
1124 
1125  LSET vset = via->GetLayerSet() & master_layermask;
1126 
1127  fprintf( aFile, "VIA VIA%d.%d.%s %g %g ALL %g via%d\n",
1128  via->GetWidth(), via->GetDrillValue(),
1129  fmt_mask( vset ).c_str(),
1130  MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ),
1131  via->GetDrillValue() / SCALE_FACTOR, vianum++ );
1132  }
1133  }
1134 
1135  fputs( "$ENDROUTES\n\n", aFile );
1136 
1137  delete tracklist;
1138 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int GetCopperLayerCount() const
Function GetCopperLayerCount.
static double MapYTo(int aY)
static wxString escapeString(const wxString &aString)
const wxPoint & GetEnd() const
Definition: class_track.h:119
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void vset(double *v, double x, double y, double z)
Definition: trackball.cpp:82
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
Class LSET is a set of PCB_LAYER_IDs.
const wxPoint & GetStart() const
Definition: class_track.h:122
static int TrackListSortByNetcode(const void *refptr, const void *objptr)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:538
int GetNetCode() const
Function GetNetCode.
static std::string GenCADLayerName(int aCuCount, PCB_LAYER_ID aId)
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:69
TRACK * Next() const
Definition: class_track.h:99
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
int GetWidth() const
Definition: class_track.h:116
static const double SCALE_FACTOR
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
DLIST< TRACK > m_Track
Definition: class_board.h:249
static std::string fmt_mask(LSET aSet)
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:239
LSET GetEnabledLayers() const
Function GetEnabledLayers returns a bit-mask of all the layers that are enabled.
class SEGZONE, a segment used to fill a zone area (segment on a
Definition: typeinfo.h:97
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
static double MapXTo(int aX)
static void CreateShapesSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 737 of file export_gencad.cpp.

References componentShapes, escapeString(), UTF8::find(), flipBottomPads, FootprintWriteShape(), LIB_ID::Format(), Format(), MODULE::GetFlag(), MODULE::GetFPID(), D_PAD::GetName(), MODULE::GetOrientation(), D_PAD::GetOrientation(), D_PAD::GetPos0(), MODULE::GetReference(), D_PAD::GetSubRatsnest(), hashModule(), individualShapes, BOARD::m_Modules, MODULE::Next(), D_PAD::Next(), NORMALIZE_ANGLE_POS(), MODULE::PadsList(), SCALE_FACTOR, shapeNames, TO_UTF8, uniquePins, wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

738 {
739  MODULE* module;
740  D_PAD* pad;
741  const char* layer;
742  wxString pinname;
743  const char* mirror = "0";
744  std::map<wxString, size_t> shapes;
745 
746  fputs( "$SHAPES\n", aFile );
747 
748  for( module = aPcb->m_Modules; module; module = module->Next() )
749  {
750  if( !individualShapes )
751  {
752  // Check if such shape has been already generated, and if so - reuse it
753  // It is necessary to compute hash (i.e. check all children objects) as
754  // certain components instances might have been modified on the board.
755  // In such case the shape will be different despite the same LIB_ID.
756  wxString shapeName = module->GetFPID().Format();
757 
758  auto shapeIt = shapes.find( shapeName );
759  size_t modHash = hashModule( module );
760 
761  if( shapeIt != shapes.end() )
762  {
763  if( modHash != shapeIt->second )
764  {
765  // there is an entry for this footprint, but it has a modified shape,
766  // so we need to create a new entry
767  wxString newShapeName;
768  int suffix = 0;
769 
770  // find an unused name or matching entry
771  do
772  {
773  newShapeName = wxString::Format( "%s_%d", shapeName, suffix );
774  shapeIt = shapes.find( newShapeName );
775  ++suffix;
776  }
777  while( shapeIt != shapes.end() && shapeIt->second != modHash );
778 
779  shapeName = newShapeName;
780  }
781 
782  if( shapeIt != shapes.end() && modHash == shapeIt->second )
783  {
784  // shape found, so reuse it
785  componentShapes[module] = modHash;
786  continue;
787  }
788  }
789 
790  // new shape
791  componentShapes[module] = modHash;
792  shapeNames[modHash] = shapeName;
793  shapes[shapeName] = modHash;
794  FootprintWriteShape( aFile, module, shapeName );
795  }
796  else // individual shape for each component
797  {
798  FootprintWriteShape( aFile, module, module->GetReference() );
799  }
800 
801  // set of already emitted pins to check for duplicates
802  std::set<wxString> pins;
803 
804  for( pad = module->PadsList(); pad; pad = pad->Next() )
805  {
806  /* Padstacks are defined using the correct layers for the pads, therefore to
807  * all pads need to be marked as TOP to use the padstack information correctly.
808  */
809  layer = "TOP";
810  pinname = pad->GetName();
811 
812  if( pinname.IsEmpty() )
813  pinname = wxT( "none" );
814 
815  if( uniquePins )
816  {
817  int suffix = 0;
818  wxString origPinname( pinname );
819 
820  auto it = pins.find( pinname );
821 
822  while( it != pins.end() )
823  {
824  pinname = wxString::Format( "%s_%d", origPinname, suffix );
825  ++suffix;
826  it = pins.find( pinname );
827  }
828 
829  pins.insert( pinname );
830  }
831 
832  double orient = pad->GetOrientation() - module->GetOrientation();
833  NORMALIZE_ANGLE_POS( orient );
834 
835  // Bottom side modules use the flipped padstack
836  fprintf( aFile, ( flipBottomPads && module->GetFlag() ) ?
837  "PIN \"%s\" PAD%dF %g %g %s %g %s\n" :
838  "PIN \"%s\" PAD%d %g %g %s %g %s\n",
839  TO_UTF8( escapeString( pinname ) ), pad->GetSubRatsnest(),
840  pad->GetPos0().x / SCALE_FACTOR,
841  -pad->GetPos0().y / SCALE_FACTOR,
842  layer, orient / 10.0, mirror );
843  }
844  }
845 
846  fputs( "$ENDSHAPES\n\n", aFile );
847 }
int GetFlag() const
Definition: class_module.h:231
MODULE * Next() const
Definition: class_module.h:123
static bool uniquePins
const wxPoint & GetPos0() const
Definition: class_pad.h:263
static wxString escapeString(const wxString &aString)
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:241
static bool flipBottomPads
const LIB_ID & GetFPID() const
Definition: class_module.h:193
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
static bool individualShapes
double GetOrientation() const
Definition: class_module.h:189
int GetSubRatsnest() const
Function GetSubRatsnest.
Definition: class_pad.h:655
std::string::size_type find(char c) const
Definition: utf8.h:110
D_PAD * Next() const
Definition: class_pad.h:160
const wxString & GetName() const
Definition: class_pad.h:190
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
static size_t hashModule(const MODULE *aModule)
Compute hashes for modules without taking into account their position, rotation or layer...
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:463
static void FootprintWriteShape(FILE *File, MODULE *module, const wxString &aShapeName)
DLIST< MODULE > m_Modules
Definition: class_board.h:248
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:382
static const double SCALE_FACTOR
UTF8 Format() const
Definition: lib_id.cpp:237
DLIST< D_PAD > & PadsList()
Definition: class_module.h:163
static std::map< MODULE *, int > componentShapes
static std::map< int, wxString > shapeNames
static void CreateSignalsSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 931 of file export_gencad.cpp.

References escapeString(), BOARD::FindNet(), GetChars(), D_PAD::GetName(), NETINFO_ITEM::GetNet(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD::GetNetCount(), NETINFO_ITEM::GetNetname(), MODULE::GetReference(), BOARD::m_Modules, MODULE::Next(), D_PAD::Next(), MODULE::PadsList(), and TO_UTF8.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

932 {
933  wxString msg;
934  NETINFO_ITEM* net;
935  D_PAD* pad;
936  MODULE* module;
937  int NbNoConn = 1;
938 
939  fputs( "$SIGNALS\n", aFile );
940 
941  for( unsigned ii = 0; ii < aPcb->GetNetCount(); ii++ )
942  {
943  net = aPcb->FindNet( ii );
944 
945  if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection)
946  {
947  msg.Printf( "NoConnection%d", NbNoConn++ );
948  }
949 
950  if( net->GetNet() <= 0 ) // dummy netlist (no connection)
951  continue;
952 
953  msg = wxT( "SIGNAL \"" ) + escapeString( net->GetNetname() ) + "\"";
954 
955  fputs( TO_UTF8( msg ), aFile );
956  fputs( "\n", aFile );
957 
958  for( module = aPcb->m_Modules; module; module = module->Next() )
959  {
960  for( pad = module->PadsList(); pad; pad = pad->Next() )
961  {
962  if( pad->GetNetCode() != net->GetNet() )
963  continue;
964 
965  msg.Printf( wxT( "NODE \"%s\" \"%s\"" ),
966  GetChars( escapeString( module->GetReference() ) ),
967  GetChars( escapeString( pad->GetName() ) ) );
968 
969  fputs( TO_UTF8( msg ), aFile );
970  fputs( "\n", aFile );
971  }
972  }
973  }
974 
975  fputs( "$ENDSIGNALS\n\n", aFile );
976 }
MODULE * Next() const
Definition: class_module.h:123
static wxString escapeString(const wxString &aString)
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
D_PAD * Next() const
Definition: class_pad.h:160
const wxString & GetName() const
Definition: class_pad.h:190
int GetNet() const
Function GetNet.
Definition: netinfo.h:231
int GetNetCode() const
Function GetNetCode.
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:69
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:463
DLIST< MODULE > m_Modules
Definition: class_board.h:248
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
DLIST< D_PAD > & PadsList()
Definition: class_module.h:163
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:239
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:779
static void CreateTracksInfoData ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 1217 of file export_gencad.cpp.

References TRACK::GetWidth(), BOARD::m_Track, TRACK::Next(), and SCALE_FACTOR.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

1218 {
1219  TRACK* track;
1220  int last_width = -1;
1221 
1222  // Find thickness used for traces
1223  // XXX could use the same sorting approach used for pads
1224 
1225  std::vector <int> trackinfo;
1226 
1227  unsigned ii;
1228 
1229  for( track = aPcb->m_Track; track; track = track->Next() )
1230  {
1231  if( last_width != track->GetWidth() ) // Find a thickness already used.
1232  {
1233  for( ii = 0; ii < trackinfo.size(); ii++ )
1234  {
1235  if( trackinfo[ii] == track->GetWidth() )
1236  break;
1237  }
1238 
1239  if( ii == trackinfo.size() ) // not found
1240  trackinfo.push_back( track->GetWidth() );
1241 
1242  last_width = track->GetWidth();
1243  }
1244  }
1245 
1246  // Write data
1247  fputs( "$TRACKS\n", aFile );
1248 
1249  for( ii = 0; ii < trackinfo.size(); ii++ )
1250  {
1251  fprintf( aFile, "TRACK TRACK%d %g\n", trackinfo[ii],
1252  trackinfo[ii] / SCALE_FACTOR );
1253  }
1254 
1255  fputs( "$ENDTRACKS\n\n", aFile );
1256 }
TRACK * Next() const
Definition: class_track.h:99
int GetWidth() const
Definition: class_track.h:116
static const double SCALE_FACTOR
DLIST< TRACK > m_Track
Definition: class_board.h:249
static wxString escapeString ( const wxString &  aString)
static

Definition at line 210 of file export_gencad.cpp.

Referenced by CreateComponentsSection(), CreateDevicesSection(), CreateRoutesSection(), CreateShapesSection(), CreateSignalsSection(), and FootprintWriteShape().

211 {
212  wxString copy( aString );
213  copy.Replace( "\"", "\\\"" );
214  return copy;
215 }
static std::string fmt_mask ( LSET  aSet)
static

Definition at line 219 of file export_gencad.cpp.

References LSET::AllCuMask(), LSET::FmtHex(), and numEval::StrPrintf().

Referenced by CreatePadsShapesSection(), and CreateRoutesSection().

220 {
221 #if 0
222  return aSet.FmtHex();
223 #else
224  return StrPrintf( "%08x", (unsigned) ( aSet & LSET::AllCuMask() ).to_ulong() );
225 #endif
226 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:673
std::string FmtHex() const
Function FmtHex returns a hex string showing contents of this LSEQ.
Definition: lset.cpp:280
int StrPrintf(std::string *aResult, const char *aFormat,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
static void FootprintWriteShape ( FILE *  File,
MODULE module,
const wxString &  aShapeName 
)
static

Definition at line 1264 of file export_gencad.cpp.

References B_SilkS, DisplayError(), escapeString(), F_SilkS, Format(), DRAWSEGMENT::GetAngle(), MODULE::GetAttributes(), EDGE_MODULE::GetEnd0(), BOARD_ITEM::GetLayer(), GetLineLength(), DRAWSEGMENT::GetShape(), EDGE_MODULE::GetStart0(), MODULE::GraphicalItemsList(), KiROUND(), MODULE::m_Attributs, EDGE_MODULE::m_End0, EDGE_MODULE::m_Start0, MOD_CMS, MOD_DEFAULT, MOD_VIRTUAL, EDA_ITEM::Next(), PCB_MODULE_EDGE_T, PCB_MODULE_TEXT_T, RotatePoint(), S_ARC, S_CIRCLE, S_POLYGON, S_SEGMENT, SCALE_FACTOR, TO_UTF8, EDA_ITEM::Type(), wxPoint::x, and wxPoint::y.

Referenced by CreateShapesSection().

1265 {
1266  EDGE_MODULE* PtEdge;
1267  EDA_ITEM* PtStruct;
1268 
1269  /* creates header: */
1270  fprintf( aFile, "\nSHAPE \"%s\"\n", TO_UTF8( escapeString( aShapeName ) ) );
1271 
1272  if( module->GetAttributes() & MOD_VIRTUAL )
1273  {
1274  fprintf( aFile, "INSERT SMD\n" );
1275  }
1276  else
1277  {
1278  if( module->GetAttributes() & MOD_CMS )
1279  {
1280  fprintf( aFile, "INSERT SMD\n" );
1281  }
1282  else
1283  {
1284  fprintf( aFile, "INSERT TH\n" );
1285  }
1286  }
1287 
1288 #if 0 /* ATTRIBUTE name and value is unspecified and the original exporter
1289  * got the syntax wrong, so CAM350 rejected the whole shape! */
1290 
1291  if( module->m_Attributs != MOD_DEFAULT )
1292  {
1293  fprintf( aFile, "ATTRIBUTE" );
1294 
1295  if( module->m_Attributs & MOD_CMS )
1296  fprintf( aFile, " PAD_SMD" );
1297 
1298  if( module->m_Attributs & MOD_VIRTUAL )
1299  fprintf( aFile, " VIRTUAL" );
1300 
1301  fprintf( aFile, "\n" );
1302  }
1303 #endif
1304 
1305  // Silk outline; wildly interpreted by various importers:
1306  // CAM350 read it right but only closed shapes
1307  // ProntoPlace double-flip it (at least the pads are correct)
1308  // GerberTool usually get it right...
1309  for( PtStruct = module->GraphicalItemsList(); PtStruct; PtStruct = PtStruct->Next() )
1310  {
1311  switch( PtStruct->Type() )
1312  {
1313  case PCB_MODULE_TEXT_T:
1314 
1315  // If we wanted to export text, this is not the correct section
1316  break;
1317 
1318  case PCB_MODULE_EDGE_T:
1319  PtEdge = (EDGE_MODULE*) PtStruct;
1320  if( PtEdge->GetLayer() == F_SilkS
1321  || PtEdge->GetLayer() == B_SilkS )
1322  {
1323  switch( PtEdge->GetShape() )
1324  {
1325  case S_SEGMENT:
1326  fprintf( aFile, "LINE %g %g %g %g\n",
1327  PtEdge->m_Start0.x / SCALE_FACTOR,
1328  -PtEdge->m_Start0.y / SCALE_FACTOR,
1329  PtEdge->m_End0.x / SCALE_FACTOR,
1330  -PtEdge->m_End0.y / SCALE_FACTOR );
1331  break;
1332 
1333  case S_CIRCLE:
1334  {
1335  int radius = KiROUND( GetLineLength( PtEdge->m_End0,
1336  PtEdge->m_Start0 ) );
1337  fprintf( aFile, "CIRCLE %g %g %g\n",
1338  PtEdge->m_Start0.x / SCALE_FACTOR,
1339  -PtEdge->m_Start0.y / SCALE_FACTOR,
1340  radius / SCALE_FACTOR );
1341  break;
1342  }
1343 
1344  case S_ARC:
1345  {
1346  int arcendx, arcendy;
1347  arcendx = PtEdge->m_End0.x - PtEdge->m_Start0.x;
1348  arcendy = PtEdge->m_End0.y - PtEdge->m_Start0.y;
1349  RotatePoint( &arcendx, &arcendy, -PtEdge->GetAngle() );
1350  arcendx += PtEdge->GetStart0().x;
1351  arcendy += PtEdge->GetStart0().y;
1352 
1353  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
1354  PtEdge->m_End0.x / SCALE_FACTOR,
1355  -PtEdge->GetEnd0().y / SCALE_FACTOR,
1356  arcendx / SCALE_FACTOR,
1357  -arcendy / SCALE_FACTOR,
1358  PtEdge->GetStart0().x / SCALE_FACTOR,
1359  -PtEdge->GetStart0().y / SCALE_FACTOR );
1360  break;
1361  }
1362 
1363  case S_POLYGON:
1364  // Not exported (TODO)
1365  break;
1366 
1367  default:
1368  DisplayError( NULL, wxString::Format( "Type Edge Module %d invalid.", PtStruct->Type() ) );
1369  break;
1370  }
1371  }
1372  break;
1373 
1374  default:
1375  break;
1376  }
1377  }
1378 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Function GetLineLength returns the length of a line segment defined by aPointA and aPointB...
Definition: trigo.h:191
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:120
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
polygon (not yet used for tracks, but could be in microwave apps)
const wxPoint & GetEnd0() const
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:77
usual segment : line with rounded ends
EDA_ITEM * Next() const
Definition: base_struct.h:209
static wxString escapeString(const wxString &aString)
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
wxPoint m_End0
End point, relative to module origin, orient 0.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
STROKE_T GetShape() const
Arcs (with rounded ends)
int GetAttributes() const
Definition: class_module.h:226
default
Definition: class_module.h:76
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
double GetAngle() const
const wxPoint & GetStart0() const
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
Virtual component: when created by copper shapes on board (Like edge card connectors, mounting hole...)
Definition: class_module.h:79
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
static const double SCALE_FACTOR
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:166
wxPoint m_Start0
Start point or center, relative to module origin, orient 0.
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
int m_Attributs
Flag bits ( see Mod_Attribut )
Definition: class_module.h:739
static std::string GenCADLayerName ( int  aCuCount,
PCB_LAYER_ID  aId 
)
static

Definition at line 102 of file export_gencad.cpp.

References B_Adhes, B_CrtYd, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, Cmts_User, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Cu, F_Fab, F_Mask, F_Paste, F_SilkS, IsCopperLayer(), Margin, and numEval::StrPrintf().

Referenced by CreateComponentsSection(), CreatePadsShapesSection(), CreateRoutesSection(), and GenCADLayerNameFlipped().

103 {
104  if( IsCopperLayer( aId ) )
105  {
106  if( aId == F_Cu )
107  return "TOP";
108  else if( aId == B_Cu )
109  return "BOTTOM";
110 
111  else if( aId <= 14 )
112  {
113  return StrPrintf( "INNER%d", aCuCount - aId - 1 );
114  }
115  else
116  {
117  return StrPrintf( "LAYER%d", aId );
118  }
119  }
120 
121  else
122  {
123  const char* txt;
124 
125  // using a switch to clearly show mapping & catch out of bounds index.
126  switch( aId )
127  {
128  // Technicals
129  case B_Adhes: txt = "B.Adhes"; break;
130  case F_Adhes: txt = "F.Adhes"; break;
131  case B_Paste: txt = "SOLDERPASTE_BOTTOM"; break;
132  case F_Paste: txt = "SOLDERPASTE_TOP"; break;
133  case B_SilkS: txt = "SILKSCREEN_BOTTOM"; break;
134  case F_SilkS: txt = "SILKSCREEN_TOP"; break;
135  case B_Mask: txt = "SOLDERMASK_BOTTOM"; break;
136  case F_Mask: txt = "SOLDERMASK_TOP"; break;
137 
138  // Users
139  case Dwgs_User: txt = "Dwgs.User"; break;
140  case Cmts_User: txt = "Cmts.User"; break;
141  case Eco1_User: txt = "Eco1.User"; break;
142  case Eco2_User: txt = "Eco2.User"; break;
143  case Edge_Cuts: txt = "Edge.Cuts"; break;
144  case Margin: txt = "Margin"; break;
145 
146  // Footprint
147  case F_CrtYd: txt = "F_CrtYd"; break;
148  case B_CrtYd: txt = "B_CrtYd"; break;
149  case F_Fab: txt = "F_Fab"; break;
150  case B_Fab: txt = "B_Fab"; break;
151 
152  default:
153  wxASSERT_MSG( 0, wxT( "aId UNEXPECTED" ) );
154  txt = "BAD-INDEX!"; break;
155  }
156 
157  return txt;
158  }
159 }
int StrPrintf(std::string *aResult, const char *aFormat,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
static std::string GenCADLayerNameFlipped ( int  aCuCount,
PCB_LAYER_ID  aId 
)
static

Definition at line 199 of file export_gencad.cpp.

References GenCADLayerName(), and numEval::StrPrintf().

Referenced by CreatePadsShapesSection().

200 {
201  if( 1<= aId && aId <= 14 )
202  {
203  return StrPrintf( "INNER%d", 14 - aId );
204  }
205 
206  return GenCADLayerName( aCuCount, aId );
207 }
int StrPrintf(std::string *aResult, const char *aFormat,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
static std::string GenCADLayerName(int aCuCount, PCB_LAYER_ID aId)
static const wxString& getShapeName ( MODULE aModule)
static

Definition at line 241 of file export_gencad.cpp.

References componentShapes, MODULE::GetReference(), individualShapes, and shapeNames.

Referenced by CreateComponentsSection().

242 {
243  static const wxString invalid( "invalid" );
244 
245  if( individualShapes )
246  return aModule->GetReference();
247 
248  auto itShape = componentShapes.find( aModule );
249  wxCHECK( itShape != componentShapes.end(), invalid );
250 
251  auto itName = shapeNames.find( itShape->second );
252  wxCHECK( itName != shapeNames.end(), invalid );
253 
254  return itName->second;
255 }
static bool individualShapes
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:463
static std::map< MODULE *, int > componentShapes
static std::map< int, wxString > shapeNames
static size_t hashModule ( const MODULE aModule)
static

Compute hashes for modules without taking into account their position, rotation or layer.

Definition at line 717 of file export_gencad.cpp.

References MODULE::GraphicalItemsList(), hash_eda(), i, LAYER, MODULE::PadsList(), POSITION, REL_COORD, and ROTATION.

Referenced by CreateShapesSection().

718 {
719  size_t ret = 0x11223344;
720  constexpr int flags = HASH_FLAGS::POSITION | HASH_FLAGS::REL_COORD
722 
723  for( const BOARD_ITEM* i = aModule->GraphicalItemsList(); i; i = i->Next() )
724  ret ^= hash_eda( i, flags );
725 
726  for( const D_PAD* i = aModule->PadsList(); i; i = i->Next() )
727  ret ^= hash_eda( i, flags );
728 
729  return ret;
730 }
use coordinates relative to the parent object
Definition: hash_eda.h:40
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
Definition: hash_eda.h:42
size_t i
Definition: json11.cpp:597
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:166
DLIST< D_PAD > & PadsList()
Definition: class_module.h:163
size_t hash_eda(const EDA_ITEM *aItem, int aFlags)
Definition: hash_eda.cpp:48
static double MapXTo ( int  aX)
static

Definition at line 263 of file export_gencad.cpp.

References GencadOffsetX, and SCALE_FACTOR.

Referenced by CreateBoardSection(), CreateComponentsSection(), CreateHeaderInfoData(), and CreateRoutesSection().

264 {
265  return (aX - GencadOffsetX) / SCALE_FACTOR;
266 }
static const double SCALE_FACTOR
static int GencadOffsetX
static double MapYTo ( int  aY)
static

Definition at line 269 of file export_gencad.cpp.

References GencadOffsetY, and SCALE_FACTOR.

Referenced by CreateBoardSection(), CreateComponentsSection(), CreateHeaderInfoData(), and CreateRoutesSection().

270 {
271  return (GencadOffsetY - aY) / SCALE_FACTOR;
272 }
static int GencadOffsetY
static const double SCALE_FACTOR
static int PadListSortByShape ( const void *  aRefptr,
const void *  aObjptr 
)
static

Definition at line 371 of file export_gencad.cpp.

References D_PAD::Compare().

Referenced by CreatePadsShapesSection().

372 {
373  const D_PAD* padref = *(D_PAD**) aRefptr;
374  const D_PAD* padcmp = *(D_PAD**) aObjptr;
375 
376  return D_PAD::Compare( padref, padcmp );
377 }
static int Compare(const D_PAD *padref, const D_PAD *padcmp)
Function Compare compares two pads and return 0 if they are equal.
Definition: class_pad.cpp:1104
static int TrackListSortByNetcode ( const void *  refptr,
const void *  objptr 
)
static

Definition at line 1021 of file export_gencad.cpp.

References BOARD_ITEM::GetLayer(), BOARD_CONNECTED_ITEM::GetNetCode(), and TRACK::GetWidth().

Referenced by CreateRoutesSection().

1022 {
1023  const TRACK* ref, * cmp;
1024  int diff;
1025 
1026  ref = *( (TRACK**) refptr );
1027  cmp = *( (TRACK**) objptr );
1028 
1029  if( ( diff = ref->GetNetCode() - cmp->GetNetCode() ) )
1030  return diff;
1031 
1032  if( ( diff = ref->GetWidth() - cmp->GetWidth() ) )
1033  return diff;
1034 
1035  if( ( diff = ref->GetLayer() - cmp->GetLayer() ) )
1036  return diff;
1037 
1038  return 0;
1039 }
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int GetNetCode() const
Function GetNetCode.
int GetWidth() const
Definition: class_track.h:116
static int ViaSort ( const void *  aRefptr,
const void *  aObjptr 
)
static

Definition at line 381 of file export_gencad.cpp.

References LSET::FmtBin(), VIA::GetDrillValue(), VIA::GetLayerSet(), and TRACK::GetWidth().

Referenced by CreatePadsShapesSection().

382 {
383  VIA* padref = *(VIA**) aRefptr;
384  VIA* padcmp = *(VIA**) aObjptr;
385 
386  if( padref->GetWidth() != padcmp->GetWidth() )
387  return padref->GetWidth() - padcmp->GetWidth();
388 
389  if( padref->GetDrillValue() != padcmp->GetDrillValue() )
390  return padref->GetDrillValue() - padcmp->GetDrillValue();
391 
392  if( padref->GetLayerSet() != padcmp->GetLayerSet() )
393  return padref->GetLayerSet().FmtBin().compare( padcmp->GetLayerSet().FmtBin() );
394 
395  return 0;
396 }
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
int GetWidth() const
Definition: class_track.h:116
std::string FmtBin() const
Function FmtBin returns a binary string showing contents of this LSEQ.
Definition: lset.cpp:256

Variable Documentation

std::map<MODULE*, int> componentShapes
static
bool flipBottomPads
static
const PCB_LAYER_ID gc_seq[]
static

Definition at line 162 of file export_gencad.cpp.

Referenced by CreatePadsShapesSection().

int GencadOffsetX
static

Definition at line 235 of file export_gencad.cpp.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD(), and MapXTo().

int GencadOffsetY
static

Definition at line 235 of file export_gencad.cpp.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD(), and MapYTo().

bool individualShapes
static
std::map<int, wxString> shapeNames
static
bool storeOriginCoords
static

Definition at line 232 of file export_gencad.cpp.

Referenced by CreateHeaderInfoData(), and PCB_EDIT_FRAME::ExportToGenCAD().

bool uniquePins
static

Definition at line 230 of file export_gencad.cpp.

Referenced by CreateShapesSection(), and PCB_EDIT_FRAME::ExportToGenCAD().