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 <wxPcbStruct.h>
#include <trigo.h>
#include <build_version.h>
#include <macros.h>
#include <pcbnew.h>
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_edge_mod.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)
 
static std::string GenCADLayerName (int aCuCount, PCB_LAYER_ID aId)
 
static std::string GenCADLayerNameFlipped (int aCuCount, PCB_LAYER_ID aId)
 
static std::string fmt_mask (LSET aSet)
 
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 int TrackListSortByNetcode (const void *refptr, const void *objptr)
 

Variables

static const PCB_LAYER_ID gc_seq []
 
static int GencadOffsetX
 
static int GencadOffsetY
 
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 369 of file export_gencad.cpp.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

370 {
371  /* The artworks section is empty */
372  fputs( "$ARTWORKS\n", aFile );
373  fputs( "$ENDARTWORKS\n\n", aFile );
374 }
static void CreateBoardSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 1027 of file export_gencad.cpp.

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

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

1028 {
1029  fputs( "$BOARD\n", aFile );
1030 
1031  // Extract the board edges
1032  for( EDA_ITEM* drawing = aPcb->m_Drawings; drawing != 0;
1033  drawing = drawing->Next() )
1034  {
1035  if( drawing->Type() == PCB_LINE_T )
1036  {
1037  DRAWSEGMENT* drawseg = static_cast<DRAWSEGMENT*>( drawing );
1038  if( drawseg->GetLayer() == Edge_Cuts )
1039  {
1040  // XXX GenCAD supports arc boundaries but I've seen nothing that reads them
1041  fprintf( aFile, "LINE %g %g %g %g\n",
1042  MapXTo( drawseg->GetStart().x ), MapYTo( drawseg->GetStart().y ),
1043  MapXTo( drawseg->GetEnd().x ), MapYTo( drawseg->GetEnd().y ) );
1044  }
1045  }
1046  }
1047 
1048  fputs( "$ENDBOARD\n\n", aFile );
1049 }
static double MapYTo(int aY)
BOARD_ITEM * Next() const
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
DLIST< BOARD_ITEM > m_Drawings
Definition: class_board.h:242
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
static double MapXTo(int aX)
static void CreateComponentsSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 691 of file export_gencad.cpp.

References B_SilkS, F_SilkS, GenCADLayerName(), BOARD::GetCopperLayerCount(), TEXTE_MODULE::GetLength(), TEXTE_MODULE::GetPos0(), 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().

692 {
693  fputs( "$COMPONENTS\n", aFile );
694 
695  int cu_count = aPcb->GetCopperLayerCount();
696 
697  for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
698  {
699  const char* mirror;
700  const char* flip;
701  double fp_orient = module->GetOrientation();
702 
703  if( module->GetFlag() )
704  {
705  mirror = "0";
706  flip = "FLIP";
707  NEGATE_AND_NORMALIZE_ANGLE_POS( fp_orient );
708  }
709  else
710  {
711  mirror = "0";
712  flip = "0";
713  }
714 
715  fprintf( aFile, "\nCOMPONENT %s\n",
716  TO_UTF8( module->GetReference() ) );
717  fprintf( aFile, "DEVICE %s_%s\n",
718  TO_UTF8( module->GetReference() ),
719  TO_UTF8( module->GetValue() ) );
720  fprintf( aFile, "PLACE %g %g\n",
721  MapXTo( module->GetPosition().x ),
722  MapYTo( module->GetPosition().y ) );
723  fprintf( aFile, "LAYER %s\n",
724  (module->GetFlag()) ? "BOTTOM" : "TOP" );
725  fprintf( aFile, "ROTATION %g\n",
726  fp_orient / 10.0 );
727  fprintf( aFile, "SHAPE %s %s %s\n",
728  TO_UTF8( module->GetReference() ),
729  mirror, flip );
730 
731  // Text on silk layer: RefDes and value (are they actually useful?)
732  TEXTE_MODULE *textmod = &module->Reference();
733 
734  for( int ii = 0; ii < 2; ii++ )
735  {
736  double txt_orient = textmod->GetTextAngle();
737  std::string layer = GenCADLayerName( cu_count, module->GetFlag() ? B_SilkS : F_SilkS );
738 
739  fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"",
740  textmod->GetPos0().x / SCALE_FACTOR,
741  -textmod->GetPos0().y / SCALE_FACTOR,
742  textmod->GetTextWidth() / SCALE_FACTOR,
743  txt_orient / 10.0,
744  mirror,
745  layer.c_str(),
746  TO_UTF8( textmod->GetText() ) );
747 
748  // Please note, the width is approx
749  fprintf( aFile, " 0 0 %g %g\n",
750  ( textmod->GetTextWidth() * textmod->GetLength() ) / SCALE_FACTOR,
751  textmod->GetTextHeight() / SCALE_FACTOR );
752 
753  textmod = &module->Value(); // Dirty trick for the second iteration
754  }
755 
756  // The SHEET is a 'generic description' for referencing the component
757  fprintf( aFile, "SHEET \"RefDes: %s, Value: %s\"\n",
758  TO_UTF8( module->GetReference() ),
759  TO_UTF8( module->GetValue() ) );
760  }
761 
762  fputs( "$ENDCOMPONENTS\n\n", aFile );
763 }
int GetLength() const
const wxPoint & GetPos0() const
int GetTextWidth() const
Definition: eda_text.h:218
MODULE * Next() const
Definition: class_module.h:99
int GetCopperLayerCount() const
Function GetCopperLayerCount.
static double MapYTo(int aY)
double GetTextAngle() const
Definition: eda_text.h:164
#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:130
static std::string GenCADLayerName(int aCuCount, PCB_LAYER_ID aId)
void NEGATE_AND_NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:262
DLIST< MODULE > m_Modules
Definition: class_board.h:243
static const double SCALE_FACTOR
int GetTextHeight() const
Definition: eda_text.h:221
static double MapXTo(int aX)
static void CreateDevicesSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 996 of file export_gencad.cpp.

References LIB_ID::Format(), MODULE::GetAttributes(), MODULE::GetFPID(), MODULE::GetReference(), MODULE::GetValue(), BOARD::m_Modules, MOD_CMS, MOD_VIRTUAL, MODULE::Next(), and TO_UTF8.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

997 {
998  MODULE* module;
999 
1000  fputs( "$DEVICES\n", aFile );
1001 
1002  for( module = aPcb->m_Modules; module; module = module->Next() )
1003  {
1004  fprintf( aFile, "DEVICE \"%s\"\n", TO_UTF8( module->GetReference() ) );
1005  fprintf( aFile, "PART \"%s\"\n", TO_UTF8( module->GetValue() ) );
1006  fprintf( aFile, "PACKAGE \"%s\"\n", module->GetFPID().Format().c_str() );
1007 
1008  // The TYPE attribute is almost freeform
1009  const char* ty = "TH";
1010 
1011  if( module->GetAttributes() & MOD_CMS )
1012  ty = "SMD";
1013 
1014  if( module->GetAttributes() & MOD_VIRTUAL )
1015  ty = "VIRTUAL";
1016 
1017  fprintf( aFile, "TYPE %s\n", ty );
1018  }
1019 
1020  fputs( "$ENDDEVICES\n\n", aFile );
1021 }
MODULE * Next() const
Definition: class_module.h:99
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:76
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:439
const LIB_ID & GetFPID() const
Definition: class_module.h:151
#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:184
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:411
DLIST< MODULE > m_Modules
Definition: class_board.h:243
Virtual component: when created by copper shapes on board (Like edge card connectors, mounting hole...)
Definition: class_module.h:78
UTF8 Format() const
Function Format.
Definition: lib_id.cpp:263
static bool CreateHeaderInfoData ( FILE *  aFile,
PCB_EDIT_FRAME frame 
)
static

Definition at line 820 of file export_gencad.cpp.

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

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

821 {
822  wxString msg;
823  BOARD *board = aFrame->GetBoard();
824 
825  fputs( "$HEADER\n", aFile );
826  fputs( "GENCAD 1.4\n", aFile );
827 
828  // Please note: GenCAD syntax requires quoted strings if they can contain spaces
829  msg.Printf( wxT( "USER \"%s %s\"\n" ),
830  GetChars( Pgm().App().GetAppName() ),
831  GetChars( GetBuildVersion() ) );
832  fputs( TO_UTF8( msg ), aFile );
833 
834  msg = wxT( "DRAWING \"" ) + board->GetFileName() + wxT( "\"\n" );
835  fputs( TO_UTF8( msg ), aFile );
836 
837  const TITLE_BLOCK& tb = aFrame->GetTitleBlock();
838 
839  msg = wxT( "REVISION \"" ) + tb.GetRevision() + wxT( " " ) + tb.GetDate() + wxT( "\"\n" );
840 
841  fputs( TO_UTF8( msg ), aFile );
842  fputs( "UNITS INCH\n", aFile );
843 
844  msg.Printf( wxT( "ORIGIN %g %g\n" ),
845  MapXTo( aFrame->GetAuxOrigin().x ),
846  MapYTo( aFrame->GetAuxOrigin().y ) );
847  fputs( TO_UTF8( msg ), aFile );
848 
849  fputs( "INTERTRACK 0\n", aFile );
850  fputs( "$ENDHEADER\n\n", aFile );
851 
852  return true;
853 }
static double MapYTo(int aY)
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:65
const wxString & GetDate() const
Class TITLE_BLOCK holds the information shown in the lower right corner of a plot, printout, or editing view.
#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
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:166
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 379 of file export_gencad.cpp.

References D_PAD::Compare(), DIM, fmt_mask(), gc_seq, GenCADLayerName(), GenCADLayerNameFlipped(), BOARD::GetCopperLayerCount(), BOARD::GetDesignSettings(), D_PAD::GetDrillSize(), VIA::GetDrillValue(), BOARD_DESIGN_SETTINGS::GetEnabledLayers(), GetFirstVia(), D_PAD::GetLayerSet(), VIA::GetLayerSet(), D_PAD::GetOffset(), BOARD::GetPadCount(), BOARD::GetPads(), D_PAD::GetShape(), D_PAD::GetSize(), D_PAD::GetSubRatsnest(), TRACK::GetWidth(), BOARD::m_Track, PAD_SHAPE_CIRCLE, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_TRAPEZOID, PadListSortByShape(), SCALE_FACTOR, LSET::Seq(), D_PAD::SetSubRatsnest(), ViaSort(), wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

380 {
381  std::vector<D_PAD*> pads;
382  std::vector<D_PAD*> padstacks;
383  std::vector<VIA*> vias;
384  std::vector<VIA*> viastacks;
385 
386  padstacks.resize( 1 ); // We count pads from 1
387 
388  // The master layermask (i.e. the enabled layers) for padstack generation
389  LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
390  int cu_count = aPcb->GetCopperLayerCount();
391 
392  fputs( "$PADS\n", aFile );
393 
394  // Enumerate and sort the pads
395  if( aPcb->GetPadCount() > 0 )
396  {
397  pads = aPcb->GetPads();
398  qsort( &pads[0], aPcb->GetPadCount(), sizeof( D_PAD* ),
400  }
401 
402  // The same for vias
403  for( VIA* via = GetFirstVia( aPcb->m_Track ); via;
404  via = GetFirstVia( via->Next() ) )
405  {
406  vias.push_back( via );
407  }
408 
409  qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort );
410 
411  // Emit vias pads
412  TRACK* old_via = 0;
413 
414  for( unsigned i = 0; i < vias.size(); i++ )
415  {
416  VIA* via = vias[i];
417 
418  if( old_via && 0 == ViaSort( &old_via, &via ) )
419  continue;
420 
421  old_via = via;
422  viastacks.push_back( via );
423  fprintf( aFile, "PAD V%d.%d.%s ROUND %g\nCIRCLE 0 0 %g\n",
424  via->GetWidth(), via->GetDrillValue(),
425  fmt_mask( via->GetLayerSet() ).c_str(),
426  via->GetDrillValue() / SCALE_FACTOR,
427  via->GetWidth() / (SCALE_FACTOR * 2) );
428  }
429 
430  // Emit component pads
431  D_PAD* old_pad = 0;
432  int pad_name_number = 0;
433 
434  for( unsigned i = 0; i<pads.size(); ++i )
435  {
436  D_PAD* pad = pads[i];
437 
438  pad->SetSubRatsnest( pad_name_number );
439 
440  if( old_pad && 0==D_PAD::Compare( old_pad, pad ) )
441  continue; // already created
442 
443  old_pad = pad;
444 
445  pad_name_number++;
446  pad->SetSubRatsnest( pad_name_number );
447 
448  fprintf( aFile, "PAD P%d", pad->GetSubRatsnest() );
449 
450  padstacks.push_back( pad ); // Will have its own padstack later
451  int dx = pad->GetSize().x / 2;
452  int dy = pad->GetSize().y / 2;
453 
454  switch( pad->GetShape() )
455  {
456  default:
457  case PAD_SHAPE_CIRCLE:
458  fprintf( aFile, " ROUND %g\n",
459  pad->GetDrillSize().x / SCALE_FACTOR );
460  /* Circle is center, radius */
461  fprintf( aFile, "CIRCLE %g %g %g\n",
462  pad->GetOffset().x / SCALE_FACTOR,
463  -pad->GetOffset().y / SCALE_FACTOR,
464  pad->GetSize().x / (SCALE_FACTOR * 2) );
465  break;
466 
467  case PAD_SHAPE_RECT:
468  fprintf( aFile, " RECTANGULAR %g\n",
469  pad->GetDrillSize().x / SCALE_FACTOR );
470 
471  // Rectangle is begin, size *not* begin, end!
472  fprintf( aFile, "RECTANGLE %g %g %g %g\n",
473  (-dx + pad->GetOffset().x ) / SCALE_FACTOR,
474  (-dy - pad->GetOffset().y ) / SCALE_FACTOR,
475  dx / (SCALE_FACTOR / 2), dy / (SCALE_FACTOR / 2) );
476  break;
477 
478  case PAD_SHAPE_OVAL: // Create outline by 2 lines and 2 arcs
479  {
480  // OrCAD Layout call them OVAL or OBLONG - GenCAD call them FINGERs
481  fprintf( aFile, " FINGER %g\n",
482  pad->GetDrillSize().x / SCALE_FACTOR );
483  int dr = dx - dy;
484 
485  if( dr >= 0 ) // Horizontal oval
486  {
487  int radius = dy;
488  fprintf( aFile, "LINE %g %g %g %g\n",
489  (-dr + pad->GetOffset().x) / SCALE_FACTOR,
490  (-pad->GetOffset().y - radius) / SCALE_FACTOR,
491  (dr + pad->GetOffset().x ) / SCALE_FACTOR,
492  (-pad->GetOffset().y - radius) / SCALE_FACTOR );
493 
494  // GenCAD arcs are (start, end, center)
495  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
496  (dr + pad->GetOffset().x) / SCALE_FACTOR,
497  (-pad->GetOffset().y - radius) / SCALE_FACTOR,
498  (dr + pad->GetOffset().x) / SCALE_FACTOR,
499  (-pad->GetOffset().y + radius) / SCALE_FACTOR,
500  (dr + pad->GetOffset().x) / SCALE_FACTOR,
501  -pad->GetOffset().y / SCALE_FACTOR );
502 
503  fprintf( aFile, "LINE %g %g %g %g\n",
504  (dr + pad->GetOffset().x) / SCALE_FACTOR,
505  (-pad->GetOffset().y + radius) / SCALE_FACTOR,
506  (-dr + pad->GetOffset().x) / SCALE_FACTOR,
507  (-pad->GetOffset().y + radius) / SCALE_FACTOR );
508  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
509  (-dr + pad->GetOffset().x) / SCALE_FACTOR,
510  (-pad->GetOffset().y + radius) / SCALE_FACTOR,
511  (-dr + pad->GetOffset().x) / SCALE_FACTOR,
512  (-pad->GetOffset().y - radius) / SCALE_FACTOR,
513  (-dr + pad->GetOffset().x) / SCALE_FACTOR,
514  -pad->GetOffset().y / SCALE_FACTOR );
515  }
516  else // Vertical oval
517  {
518  dr = -dr;
519  int radius = dx;
520  fprintf( aFile, "LINE %g %g %g %g\n",
521  (-radius + pad->GetOffset().x) / SCALE_FACTOR,
522  (-pad->GetOffset().y - dr) / SCALE_FACTOR,
523  (-radius + pad->GetOffset().x ) / SCALE_FACTOR,
524  (-pad->GetOffset().y + dr) / SCALE_FACTOR );
525  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
526  (-radius + pad->GetOffset().x ) / SCALE_FACTOR,
527  (-pad->GetOffset().y + dr) / SCALE_FACTOR,
528  (radius + pad->GetOffset().x ) / SCALE_FACTOR,
529  (-pad->GetOffset().y + dr) / SCALE_FACTOR,
530  pad->GetOffset().x / SCALE_FACTOR,
531  (-pad->GetOffset().y + dr) / SCALE_FACTOR );
532 
533  fprintf( aFile, "LINE %g %g %g %g\n",
534  (radius + pad->GetOffset().x) / SCALE_FACTOR,
535  (-pad->GetOffset().y + dr) / SCALE_FACTOR,
536  (radius + pad->GetOffset().x) / SCALE_FACTOR,
537  (-pad->GetOffset().y - dr) / SCALE_FACTOR );
538  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
539  (radius + pad->GetOffset().x) / SCALE_FACTOR,
540  (-pad->GetOffset().y - dr) / SCALE_FACTOR,
541  (-radius + pad->GetOffset().x) / SCALE_FACTOR,
542  (-pad->GetOffset().y - dr) / SCALE_FACTOR,
543  pad->GetOffset().x / SCALE_FACTOR,
544  (-pad->GetOffset().y - dr) / SCALE_FACTOR );
545  }
546  }
547  break;
548 
549  case PAD_SHAPE_TRAPEZOID:
550  fprintf( aFile, " POLYGON %g\n",
551  pad->GetDrillSize().x / SCALE_FACTOR );
552 
553  // XXX TO BE IMPLEMENTED! and I don't know if it could be actually imported by something
554  break;
555  }
556  }
557 
558  fputs( "\n$ENDPADS\n\n", aFile );
559 
560  // Now emit the padstacks definitions, using the combined layer masks
561  fputs( "$PADSTACKS\n", aFile );
562 
563  // Via padstacks
564  for( unsigned i = 0; i < viastacks.size(); i++ )
565  {
566  VIA* via = viastacks[i];
567 
568  LSET mask = via->GetLayerSet() & master_layermask;
569 
570  fprintf( aFile, "PADSTACK VIA%d.%d.%s %g\n",
571  via->GetWidth(), via->GetDrillValue(),
572  fmt_mask( mask ).c_str(),
573  via->GetDrillValue() / SCALE_FACTOR );
574 
575  for( LSEQ seq = mask.Seq( gc_seq, DIM( gc_seq ) ); seq; ++seq )
576  {
577  PCB_LAYER_ID layer = *seq;
578 
579  fprintf( aFile, "PAD V%d.%d.%s %s 0 0\n",
580  via->GetWidth(), via->GetDrillValue(),
581  fmt_mask( mask ).c_str(),
582  GenCADLayerName( cu_count, layer ).c_str()
583  );
584  }
585  }
586 
587  /* Component padstacks
588  * CAM350 don't apply correctly the FLIP semantics for padstacks, i.e. doesn't
589  * swap the top and bottom layers... so I need to define the shape as MIRRORX
590  * and define a separate 'flipped' padstack... until it appears yet another
591  * noncompliant importer */
592  for( unsigned i = 1; i < padstacks.size(); i++ )
593  {
594  D_PAD* pad = padstacks[i];
595 
596  // Straight padstack
597  fprintf( aFile, "PADSTACK PAD%u %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
598 
599  LSET pad_set = pad->GetLayerSet() & master_layermask;
600 
601  // the special gc_seq
602  for( LSEQ seq = pad_set.Seq( gc_seq, DIM( gc_seq ) ); seq; ++seq )
603  {
604  PCB_LAYER_ID layer = *seq;
605 
606  fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerName( cu_count, layer ).c_str() );
607  }
608 
609  // Flipped padstack
610  fprintf( aFile, "PADSTACK PAD%uF %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
611 
612  // the normal PCB_LAYER_ID sequence is inverted from gc_seq[]
613  for( LSEQ seq = pad_set.Seq(); seq; ++seq )
614  {
615  PCB_LAYER_ID layer = *seq;
616 
617  fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerNameFlipped( cu_count, layer ).c_str() );
618  }
619  }
620 
621  fputs( "$ENDPADSTACKS\n\n", aFile );
622 }
#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...
const D_PADS & GetPads()
Function GetPads returns a reference to a list of all the pads.
Definition: class_board.h:762
static int ViaSort(const void *aRefptr, const void *aObjptr)
int GetCopperLayerCount() const
Function GetCopperLayerCount.
void SetSubRatsnest(int aSubRatsnest)
Definition: class_pad.h:475
const wxSize & GetDrillSize() const
Definition: class_pad.h:188
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:166
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:337
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.
int GetSubRatsnest() const
Function GetSubRatsnest.
Definition: class_pad.h:474
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:1021
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:235
const wxSize & GetSize() const
Definition: class_pad.h:182
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
unsigned GetPadCount() const
Function GetPadCount.
Definition: class_board.h:741
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
static std::string GenCADLayerName(int aCuCount, PCB_LAYER_ID aId)
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:115
static const double SCALE_FACTOR
DLIST< TRACK > m_Track
Definition: class_board.h:244
static std::string fmt_mask(LSET aSet)
LSET GetEnabledLayers() const
Function GetEnabledLayers returns a bit-mask of all the layers that are enabled.
const wxPoint & GetOffset() const
Definition: class_pad.h:191
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:497
static void CreateRoutesSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 890 of file export_gencad.cpp.

References 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, BOARD::m_Zone, MapXTo(), MapYTo(), TRACK::Next(), PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, SCALE_FACTOR, TO_UTF8, TrackListSortByNetcode(), EDA_ITEM::Type(), vset(), wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

891 {
892  TRACK* track, ** tracklist;
893  int vianum = 1;
894  int old_netcode, old_width, old_layer;
895  int nbitems, ii;
896  LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
897 
898  int cu_count = aPcb->GetCopperLayerCount();
899 
900  // Count items
901  nbitems = 0;
902 
903  for( track = aPcb->m_Track; track; track = track->Next() )
904  nbitems++;
905 
906  for( track = aPcb->m_Zone; track; track = track->Next() )
907  {
908  if( track->Type() == PCB_ZONE_T )
909  nbitems++;
910  }
911 
912  tracklist = (TRACK**) operator new( (nbitems + 1)* sizeof( TRACK* ) );
913 
914  nbitems = 0;
915 
916  for( track = aPcb->m_Track; track; track = track->Next() )
917  tracklist[nbitems++] = track;
918 
919  for( track = aPcb->m_Zone; track; track = track->Next() )
920  {
921  if( track->Type() == PCB_ZONE_T )
922  tracklist[nbitems++] = track;
923  }
924 
925  tracklist[nbitems] = NULL;
926 
927  qsort( tracklist, nbitems, sizeof(TRACK*), TrackListSortByNetcode );
928 
929  fputs( "$ROUTES\n", aFile );
930 
931  old_netcode = -1; old_width = -1; old_layer = -1;
932 
933  for( ii = 0; ii < nbitems; ii++ )
934  {
935  track = tracklist[ii];
936 
937  if( old_netcode != track->GetNetCode() )
938  {
939  old_netcode = track->GetNetCode();
940  NETINFO_ITEM* net = track->GetNet();
941  wxString netname;
942 
943  if( net && (net->GetNetname() != wxEmptyString) )
944  netname = net->GetNetname();
945  else
946  netname = wxT( "_noname_" );
947 
948  fprintf( aFile, "ROUTE %s\n", TO_UTF8( netname ) );
949  }
950 
951  if( old_width != track->GetWidth() )
952  {
953  old_width = track->GetWidth();
954  fprintf( aFile, "TRACK TRACK%d\n", track->GetWidth() );
955  }
956 
957  if( (track->Type() == PCB_TRACE_T) || (track->Type() == PCB_ZONE_T) )
958  {
959  if( old_layer != track->GetLayer() )
960  {
961  old_layer = track->GetLayer();
962  fprintf( aFile, "LAYER %s\n",
963  GenCADLayerName( cu_count, track->GetLayer() ).c_str()
964  );
965  }
966 
967  fprintf( aFile, "LINE %g %g %g %g\n",
968  MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ),
969  MapXTo( track->GetEnd().x ), MapYTo( track->GetEnd().y ) );
970  }
971 
972  if( track->Type() == PCB_VIA_T )
973  {
974  const VIA* via = static_cast<const VIA*>(track);
975 
976  LSET vset = via->GetLayerSet() & master_layermask;
977 
978  fprintf( aFile, "VIA VIA%d.%d.%s %g %g ALL %g via%d\n",
979  via->GetWidth(), via->GetDrillValue(),
980  fmt_mask( vset ).c_str(),
981  MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ),
982  via->GetDrillValue() / SCALE_FACTOR, vianum++ );
983  }
984  }
985 
986  fputs( "$ENDROUTES\n\n", aFile );
987 
988  delete tracklist;
989 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
int GetCopperLayerCount() const
Function GetCopperLayerCount.
static double MapYTo(int aY)
DLIST< SEGZONE > m_Zone
Definition: class_board.h:245
const wxPoint & GetEnd() const
Definition: class_track.h:118
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:107
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:121
static int TrackListSortByNetcode(const void *refptr, const void *objptr)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
class SEGZONE, a segment used to fill a zone area (segment on a copper layer)
Definition: typeinfo.h:109
int GetNetCode() const
Function GetNetCode.
static std::string GenCADLayerName(int aCuCount, PCB_LAYER_ID aId)
Class NETINFO_ITEM handles the data for a net.
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
TRACK * Next() const
Definition: class_track.h:98
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:115
static const double SCALE_FACTOR
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
DLIST< TRACK > m_Track
Definition: class_board.h:244
static std::string fmt_mask(LSET aSet)
const wxString & GetNetname() const
Function GetNetname.
LSET GetEnabledLayers() const
Function GetEnabledLayers returns a bit-mask of all the layers that are enabled.
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 629 of file export_gencad.cpp.

References LSET::AllCuMask(), B_Cu, F_Cu, FootprintWriteShape(), MODULE::GetFlag(), D_PAD::GetLayerSet(), MODULE::GetOrientation(), D_PAD::GetOrientation(), D_PAD::GetPos0(), D_PAD::GetSubRatsnest(), BOARD::m_Modules, MODULE::Next(), D_PAD::Next(), NORMALIZE_ANGLE_POS(), MODULE::Pads(), SCALE_FACTOR, D_PAD::StringPadName(), TO_UTF8, wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

630 {
631  MODULE* module;
632  D_PAD* pad;
633  const char* layer;
634  wxString pinname;
635  const char* mirror = "0";
636 
637  fputs( "$SHAPES\n", aFile );
638 
639  const LSET all_cu = LSET::AllCuMask();
640 
641  for( module = aPcb->m_Modules; module; module = module->Next() )
642  {
643  FootprintWriteShape( aFile, module );
644 
645  for( pad = module->Pads(); pad; pad = pad->Next() )
646  {
647  /* Funny thing: GenCAD requires the pad side even if you use
648  * padstacks (which are theorically optional but gerbtools
649  *requires* them). Now the trouble thing is that 'BOTTOM'
650  * is interpreted by someone as a padstack flip even
651  * if the spec explicitly says it's not... */
652  layer = "ALL";
653 
654  if( ( pad->GetLayerSet() & all_cu ) == LSET( B_Cu ) )
655  {
656  layer = module->GetFlag() ? "TOP" : "BOTTOM";
657  }
658  else if( ( pad->GetLayerSet() & all_cu ) == LSET( F_Cu ) )
659  {
660  layer = module->GetFlag() ? "BOTTOM" : "TOP";
661  }
662 
663  pad->StringPadName( pinname );
664 
665  if( pinname.IsEmpty() )
666  pinname = wxT( "none" );
667 
668  double orient = pad->GetOrientation() - module->GetOrientation();
669  NORMALIZE_ANGLE_POS( orient );
670 
671  // Bottom side modules use the flipped padstack
672  fprintf( aFile, (module->GetFlag()) ?
673  "PIN %s PAD%dF %g %g %s %g %s\n" :
674  "PIN %s PAD%d %g %g %s %g %s\n",
675  TO_UTF8( pinname ), pad->GetSubRatsnest(),
676  pad->GetPos0().x / SCALE_FACTOR,
677  -pad->GetPos0().y / SCALE_FACTOR,
678  layer, orient / 10.0, mirror );
679  }
680  }
681 
682  fputs( "$ENDSHAPES\n\n", aFile );
683 }
int GetFlag() const
Definition: class_module.h:189
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:639
MODULE * Next() const
Definition: class_module.h:99
const wxPoint & GetPos0() const
Definition: class_pad.h:176
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:222
#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.
double GetOrientation() const
Definition: class_module.h:147
int GetSubRatsnest() const
Function GetSubRatsnest.
Definition: class_pad.h:474
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:235
D_PAD * Next() const
Definition: class_pad.h:106
static void FootprintWriteShape(FILE *File, MODULE *module)
DLIST< MODULE > m_Modules
Definition: class_board.h:243
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:214
static const double SCALE_FACTOR
DLIST< D_PAD > & Pads()
Definition: class_module.h:133
void StringPadName(wxString &text) const
Definition: class_pad.cpp:442
static void CreateSignalsSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 768 of file export_gencad.cpp.

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

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

769 {
770  wxString msg;
771  NETINFO_ITEM* net;
772  D_PAD* pad;
773  MODULE* module;
774  int NbNoConn = 1;
775 
776  fputs( "$SIGNALS\n", aFile );
777 
778  for( unsigned ii = 0; ii < aPcb->GetNetCount(); ii++ )
779  {
780  net = aPcb->FindNet( ii );
781 
782  if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection)
783  {
784  msg.Printf( "NoConnection%d", NbNoConn++ );
785  }
786 
787  if( net->GetNet() <= 0 ) // dummy netlist (no connection)
788  continue;
789 
790  msg = wxT( "SIGNAL " ) + net->GetNetname();
791 
792  fputs( TO_UTF8( msg ), aFile );
793  fputs( "\n", aFile );
794 
795  for( module = aPcb->m_Modules; module; module = module->Next() )
796  {
797  for( pad = module->Pads(); pad; pad = pad->Next() )
798  {
799  wxString padname;
800 
801  if( pad->GetNetCode() != net->GetNet() )
802  continue;
803 
804  pad->StringPadName( padname );
805  msg.Printf( wxT( "NODE %s %s" ),
806  GetChars( module->GetReference() ),
807  GetChars( padname ) );
808 
809  fputs( TO_UTF8( msg ), aFile );
810  fputs( "\n", aFile );
811  }
812  }
813  }
814 
815  fputs( "$ENDSIGNALS\n\n", aFile );
816 }
MODULE * Next() const
Definition: class_module.h:99
#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:106
int GetNet() const
Function GetNet.
int GetNetCode() const
Function GetNetCode.
Class NETINFO_ITEM handles the data for a net.
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:411
DLIST< MODULE > m_Modules
Definition: class_board.h:243
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
DLIST< D_PAD > & Pads()
Definition: class_module.h:133
const wxString & GetNetname() const
Function GetNetname.
void StringPadName(wxString &text) const
Definition: class_pad.cpp:442
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:814
static void CreateTracksInfoData ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 1062 of file export_gencad.cpp.

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

Referenced by PCB_EDIT_FRAME::ExportToGenCAD().

1063 {
1064  TRACK* track;
1065  int last_width = -1;
1066 
1067  // Find thickness used for traces
1068  // XXX could use the same sorting approach used for pads
1069 
1070  std::vector <int> trackinfo;
1071 
1072  unsigned ii;
1073 
1074  for( track = aPcb->m_Track; track; track = track->Next() )
1075  {
1076  if( last_width != track->GetWidth() ) // Find a thickness already used.
1077  {
1078  for( ii = 0; ii < trackinfo.size(); ii++ )
1079  {
1080  if( trackinfo[ii] == track->GetWidth() )
1081  break;
1082  }
1083 
1084  if( ii == trackinfo.size() ) // not found
1085  trackinfo.push_back( track->GetWidth() );
1086 
1087  last_width = track->GetWidth();
1088  }
1089  }
1090 
1091  for( track = aPcb->m_Zone; track; track = track->Next() )
1092  {
1093  if( last_width != track->GetWidth() ) // Find a thickness already used.
1094  {
1095  for( ii = 0; ii < trackinfo.size(); ii++ )
1096  {
1097  if( trackinfo[ii] == track->GetWidth() )
1098  break;
1099  }
1100 
1101  if( ii == trackinfo.size() ) // not found
1102  trackinfo.push_back( track->GetWidth() );
1103 
1104  last_width = track->GetWidth();
1105  }
1106  }
1107 
1108  // Write data
1109  fputs( "$TRACKS\n", aFile );
1110 
1111  for( ii = 0; ii < trackinfo.size(); ii++ )
1112  {
1113  fprintf( aFile, "TRACK TRACK%d %g\n", trackinfo[ii],
1114  trackinfo[ii] / SCALE_FACTOR );
1115  }
1116 
1117  fputs( "$ENDTRACKS\n\n", aFile );
1118 }
DLIST< SEGZONE > m_Zone
Definition: class_board.h:245
TRACK * Next() const
Definition: class_track.h:98
int GetWidth() const
Definition: class_track.h:115
static const double SCALE_FACTOR
DLIST< TRACK > m_Track
Definition: class_board.h:244
static std::string fmt_mask ( LSET  aSet)
static

Definition at line 210 of file export_gencad.cpp.

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

Referenced by CreatePadsShapesSection(), and CreateRoutesSection().

211 {
212 #if 0
213  return aSet.FmtHex();
214 #else
215  return StrPrintf( "%08x", (unsigned) ( aSet & LSET::AllCuMask() ).to_ulong() );
216 #endif
217 }
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:639
std::string FmtHex() const
Function FmtHex returns a hex string showing contents of this LSEQ.
Definition: lset.cpp:253
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
static void FootprintWriteShape ( FILE *  File,
MODULE module 
)
static

Definition at line 1126 of file export_gencad.cpp.

References B_SilkS, DisplayError(), F_SilkS, Format(), DRAWSEGMENT::GetAngle(), MODULE::GetAttributes(), EDGE_MODULE::GetEnd0(), MODULE::GetFlag(), BOARD_ITEM::GetLayer(), GetLineLength(), MODULE::GetReference(), DRAWSEGMENT::GetShape(), EDGE_MODULE::GetStart0(), MODULE::GraphicalItems(), 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().

1127 {
1128  EDGE_MODULE* PtEdge;
1129  EDA_ITEM* PtStruct;
1130 
1131  // Control Y axis change sign for flipped modules
1132  int Yaxis_sign = -1;
1133 
1134  // Flip for bottom side components
1135  if( module->GetFlag() )
1136  Yaxis_sign = 1;
1137 
1138  /* creates header: */
1139  fprintf( aFile, "\nSHAPE %s\n", TO_UTF8( module->GetReference() ) );
1140 
1141  if( module->GetAttributes() & MOD_VIRTUAL )
1142  {
1143  fprintf( aFile, "INSERT SMD\n" );
1144  }
1145  else
1146  {
1147  if( module->GetAttributes() & MOD_CMS )
1148  {
1149  fprintf( aFile, "INSERT SMD\n" );
1150  }
1151  else
1152  {
1153  fprintf( aFile, "INSERT TH\n" );
1154  }
1155  }
1156 
1157 #if 0 /* ATTRIBUTE name and value is unspecified and the original exporter
1158  * got the syntax wrong, so CAM350 rejected the whole shape! */
1159 
1160  if( module->m_Attributs != MOD_DEFAULT )
1161  {
1162  fprintf( aFile, "ATTRIBUTE" );
1163 
1164  if( module->m_Attributs & MOD_CMS )
1165  fprintf( aFile, " PAD_SMD" );
1166 
1167  if( module->m_Attributs & MOD_VIRTUAL )
1168  fprintf( aFile, " VIRTUAL" );
1169 
1170  fprintf( aFile, "\n" );
1171  }
1172 #endif
1173 
1174  // Silk outline; wildly interpreted by various importers:
1175  // CAM350 read it right but only closed shapes
1176  // ProntoPlace double-flip it (at least the pads are correct)
1177  // GerberTool usually get it right...
1178  for( PtStruct = module->GraphicalItems(); PtStruct; PtStruct = PtStruct->Next() )
1179  {
1180  switch( PtStruct->Type() )
1181  {
1182  case PCB_MODULE_TEXT_T:
1183 
1184  // If we wanted to export text, this is not the correct section
1185  break;
1186 
1187  case PCB_MODULE_EDGE_T:
1188  PtEdge = (EDGE_MODULE*) PtStruct;
1189  if( PtEdge->GetLayer() == F_SilkS
1190  || PtEdge->GetLayer() == B_SilkS )
1191  {
1192  switch( PtEdge->GetShape() )
1193  {
1194  case S_SEGMENT:
1195  fprintf( aFile, "LINE %g %g %g %g\n",
1196  (PtEdge->m_Start0.x) / SCALE_FACTOR,
1197  (Yaxis_sign * PtEdge->m_Start0.y) / SCALE_FACTOR,
1198  (PtEdge->m_End0.x) / SCALE_FACTOR,
1199  (Yaxis_sign * PtEdge->m_End0.y ) / SCALE_FACTOR );
1200  break;
1201 
1202  case S_CIRCLE:
1203  {
1204  int radius = KiROUND( GetLineLength( PtEdge->m_End0,
1205  PtEdge->m_Start0 ) );
1206  fprintf( aFile, "CIRCLE %g %g %g\n",
1207  PtEdge->m_Start0.x / SCALE_FACTOR,
1208  Yaxis_sign * PtEdge->m_Start0.y / SCALE_FACTOR,
1209  radius / SCALE_FACTOR );
1210  break;
1211  }
1212 
1213  case S_ARC:
1214  {
1215  int arcendx, arcendy;
1216  arcendx = PtEdge->m_End0.x - PtEdge->m_Start0.x;
1217  arcendy = PtEdge->m_End0.y - PtEdge->m_Start0.y;
1218  RotatePoint( &arcendx, &arcendy, -PtEdge->GetAngle() );
1219  arcendx += PtEdge->GetStart0().x;
1220  arcendy += PtEdge->GetStart0().y;
1221  if( Yaxis_sign == -1 )
1222  {
1223  // Flipping Y flips the arc direction too
1224  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
1225  (arcendx) / SCALE_FACTOR,
1226  (Yaxis_sign * arcendy) / SCALE_FACTOR,
1227  (PtEdge->m_End0.x) / SCALE_FACTOR,
1228  (Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
1229  (PtEdge->GetStart0().x) / SCALE_FACTOR,
1230  (Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
1231  }
1232  else
1233  {
1234  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
1235  (PtEdge->GetEnd0().x) / SCALE_FACTOR,
1236  (Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
1237  (arcendx) / SCALE_FACTOR,
1238  (Yaxis_sign * arcendy) / SCALE_FACTOR,
1239  (PtEdge->GetStart0().x) / SCALE_FACTOR,
1240  (Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
1241  }
1242  break;
1243  }
1244 
1245  case S_POLYGON:
1246  // Not exported (TODO)
1247  break;
1248 
1249  default:
1250  DisplayError( NULL, wxString::Format( "Type Edge Module %d invalid.", PtStruct->Type() ) );
1251  break;
1252  }
1253  }
1254  break;
1255 
1256  default:
1257  break;
1258  }
1259  }
1260 }
int GetFlag() const
Definition: class_module.h:189
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
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:183
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
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:76
usual segment : line with rounded ends
EDA_ITEM * Next() const
Definition: base_struct.h:206
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
DLIST< BOARD_ITEM > & GraphicalItems()
Definition: class_module.h:136
wxPoint m_End0
#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:184
default
Definition: class_module.h:75
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
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
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:411
Virtual component: when created by copper shapes on board (Like edge card connectors, mounting hole...)
Definition: class_module.h:78
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
static const double SCALE_FACTOR
wxPoint m_Start0
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:69
int m_Attributs
Flag bits ( see Mod_Attribut )
Definition: class_module.h:673
static std::string GenCADLayerName ( int  aCuCount,
PCB_LAYER_ID  aId 
)
static

Definition at line 100 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 StrPrintf().

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

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

References GenCADLayerName(), and StrPrintf().

Referenced by CreatePadsShapesSection().

198 {
199  if( 1<= aId && aId <= 14 )
200  {
201  return StrPrintf( "INNER%d", 14 - aId );
202  }
203 
204  return GenCADLayerName( aCuCount, aId );
205 };
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
static std::string GenCADLayerName(int aCuCount, PCB_LAYER_ID aId)
static double MapXTo ( int  aX)
static

Definition at line 230 of file export_gencad.cpp.

References GencadOffsetX, and SCALE_FACTOR.

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

231 {
232  return (aX - GencadOffsetX) / SCALE_FACTOR;
233 }
static const double SCALE_FACTOR
static int GencadOffsetX
static double MapYTo ( int  aY)
static

Definition at line 236 of file export_gencad.cpp.

References GencadOffsetY, and SCALE_FACTOR.

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

237 {
238  return (GencadOffsetY - aY) / SCALE_FACTOR;
239 }
static int GencadOffsetY
static const double SCALE_FACTOR
static int PadListSortByShape ( const void *  aRefptr,
const void *  aObjptr 
)
static

Definition at line 340 of file export_gencad.cpp.

References D_PAD::Compare().

Referenced by CreatePadsShapesSection().

341 {
342  const D_PAD* padref = *(D_PAD**) aRefptr;
343  const D_PAD* padcmp = *(D_PAD**) aObjptr;
344 
345  return D_PAD::Compare( padref, padcmp );
346 }
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:1021
static int TrackListSortByNetcode ( const void *  refptr,
const void *  objptr 
)
static

Definition at line 860 of file export_gencad.cpp.

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

Referenced by CreateRoutesSection().

861 {
862  const TRACK* ref, * cmp;
863  int diff;
864 
865  ref = *( (TRACK**) refptr );
866  cmp = *( (TRACK**) objptr );
867 
868  if( ( diff = ref->GetNetCode() - cmp->GetNetCode() ) )
869  return diff;
870 
871  if( ( diff = ref->GetWidth() - cmp->GetWidth() ) )
872  return diff;
873 
874  if( ( diff = ref->GetLayer() - cmp->GetLayer() ) )
875  return diff;
876 
877  return 0;
878 }
int GetNetCode() const
Function GetNetCode.
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int GetWidth() const
Definition: class_track.h:115
bool cmp(const Point *a, const Point *b)
Definition: shapes.h:227
static int ViaSort ( const void *  aRefptr,
const void *  aObjptr 
)
static

Definition at line 350 of file export_gencad.cpp.

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

Referenced by CreatePadsShapesSection().

351 {
352  VIA* padref = *(VIA**) aRefptr;
353  VIA* padcmp = *(VIA**) aObjptr;
354 
355  if( padref->GetWidth() != padcmp->GetWidth() )
356  return padref->GetWidth() - padcmp->GetWidth();
357 
358  if( padref->GetDrillValue() != padcmp->GetDrillValue() )
359  return padref->GetDrillValue() - padcmp->GetDrillValue();
360 
361  if( padref->GetLayerSet() != padcmp->GetLayerSet() )
362  return padref->GetLayerSet().FmtBin().compare( padcmp->GetLayerSet().FmtBin() );
363 
364  return 0;
365 }
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:115
std::string FmtBin() const
Function FmtBin returns a binary string showing contents of this LSEQ.
Definition: lset.cpp:229

Variable Documentation

const PCB_LAYER_ID gc_seq[]
static

Definition at line 160 of file export_gencad.cpp.

Referenced by CreatePadsShapesSection().

int GencadOffsetX
static

Definition at line 221 of file export_gencad.cpp.

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

int GencadOffsetY
static

Definition at line 221 of file export_gencad.cpp.

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

const double SCALE_FACTOR = 1000.0 * IU_PER_MILS
static