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 1024 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().

1025 {
1026  fputs( "$BOARD\n", aFile );
1027 
1028  // Extract the board edges
1029  for( auto drawing : aPcb->Drawings() )
1030  {
1031  if( drawing->Type() == PCB_LINE_T )
1032  {
1033  DRAWSEGMENT* drawseg = static_cast<DRAWSEGMENT*>( drawing );
1034  if( drawseg->GetLayer() == Edge_Cuts )
1035  {
1036  // XXX GenCAD supports arc boundaries but I've seen nothing that reads them
1037  fprintf( aFile, "LINE %g %g %g %g\n",
1038  MapXTo( drawseg->GetStart().x ), MapYTo( drawseg->GetStart().y ),
1039  MapXTo( drawseg->GetEnd().x ), MapYTo( drawseg->GetEnd().y ) );
1040  }
1041  }
1042  }
1043 
1044  fputs( "$ENDBOARD\n\n", aFile );
1045 }
static double MapYTo(int aY)
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
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.
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:251
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:100
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:245
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 993 of file export_gencad.cpp.

References UTF8::c_str(), 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().

994 {
995  MODULE* module;
996 
997  fputs( "$DEVICES\n", aFile );
998 
999  for( module = aPcb->m_Modules; module; module = module->Next() )
1000  {
1001  fprintf( aFile, "DEVICE \"%s\"\n", TO_UTF8( module->GetReference() ) );
1002  fprintf( aFile, "PART \"%s\"\n", TO_UTF8( module->GetValue() ) );
1003  fprintf( aFile, "PACKAGE \"%s\"\n", module->GetFPID().Format().c_str() );
1004 
1005  // The TYPE attribute is almost freeform
1006  const char* ty = "TH";
1007 
1008  if( module->GetAttributes() & MOD_CMS )
1009  ty = "SMD";
1010 
1011  if( module->GetAttributes() & MOD_VIRTUAL )
1012  ty = "VIRTUAL";
1013 
1014  fprintf( aFile, "TYPE %s\n", ty );
1015  }
1016 
1017  fputs( "$ENDDEVICES\n\n", aFile );
1018 }
MODULE * Next() const
Definition: class_module.h:100
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:447
const LIB_ID & GetFPID() const
Definition: class_module.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
int GetAttributes() const
Definition: class_module.h:197
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:419
DLIST< MODULE > m_Modules
Definition: class_board.h:245
Virtual component: when created by copper shapes on board (Like edge card connectors, mounting hole...)
Definition: class_module.h:79
const char * c_str() const
Definition: utf8.h:107
UTF8 Format() const
Function Format.
Definition: lib_id.cpp:263
static bool CreateHeaderInfoData ( FILE *  aFile,
PCB_EDIT_FRAME frame 
)
static

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

818 {
819  wxString msg;
820  BOARD *board = aFrame->GetBoard();
821 
822  fputs( "$HEADER\n", aFile );
823  fputs( "GENCAD 1.4\n", aFile );
824 
825  // Please note: GenCAD syntax requires quoted strings if they can contain spaces
826  msg.Printf( wxT( "USER \"%s %s\"\n" ),
827  GetChars( Pgm().App().GetAppName() ),
828  GetChars( GetBuildVersion() ) );
829  fputs( TO_UTF8( msg ), aFile );
830 
831  msg = wxT( "DRAWING \"" ) + board->GetFileName() + wxT( "\"\n" );
832  fputs( TO_UTF8( msg ), aFile );
833 
834  const TITLE_BLOCK& tb = aFrame->GetTitleBlock();
835 
836  msg = wxT( "REVISION \"" ) + tb.GetRevision() + wxT( " " ) + tb.GetDate() + wxT( "\"\n" );
837 
838  fputs( TO_UTF8( msg ), aFile );
839  fputs( "UNITS INCH\n", aFile );
840 
841  msg.Printf( wxT( "ORIGIN %g %g\n" ),
842  MapXTo( aFrame->GetAuxOrigin().x ),
843  MapYTo( aFrame->GetAuxOrigin().y ) );
844  fputs( TO_UTF8( msg ), aFile );
845 
846  fputs( "INTERTRACK 0\n", aFile );
847  fputs( "$ENDHEADER\n\n", aFile );
848 
849  return true;
850 }
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:234
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:169
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...
static int ViaSort(const void *aRefptr, const void *aObjptr)
int GetCopperLayerCount() const
Function GetCopperLayerCount.
void SetSubRatsnest(int aSubRatsnest)
Definition: class_pad.h:615
const wxSize & GetDrillSize() const
Definition: class_pad.h:260
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:201
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:614
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:1063
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:377
const wxSize & GetSize() const
Definition: class_pad.h:254
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
unsigned GetPadCount() const
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 ...
int GetWidth() const
Definition: class_track.h:115
static const double SCALE_FACTOR
DLIST< TRACK > m_Track
Definition: class_board.h:246
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:263
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:490
static void CreateRoutesSection ( FILE *  aFile,
BOARD aPcb 
)
static

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

888 {
889  TRACK* track, ** tracklist;
890  int vianum = 1;
891  int old_netcode, old_width, old_layer;
892  int nbitems, ii;
893  LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
894 
895  int cu_count = aPcb->GetCopperLayerCount();
896 
897  // Count items
898  nbitems = 0;
899 
900  for( track = aPcb->m_Track; track; track = track->Next() )
901  nbitems++;
902 
903  for( track = aPcb->m_Zone; track; track = track->Next() )
904  {
905  if( track->Type() == PCB_ZONE_T )
906  nbitems++;
907  }
908 
909  tracklist = (TRACK**) operator new( (nbitems + 1)* sizeof( TRACK* ) );
910 
911  nbitems = 0;
912 
913  for( track = aPcb->m_Track; track; track = track->Next() )
914  tracklist[nbitems++] = track;
915 
916  for( track = aPcb->m_Zone; track; track = track->Next() )
917  {
918  if( track->Type() == PCB_ZONE_T )
919  tracklist[nbitems++] = track;
920  }
921 
922  tracklist[nbitems] = NULL;
923 
924  qsort( tracklist, nbitems, sizeof(TRACK*), TrackListSortByNetcode );
925 
926  fputs( "$ROUTES\n", aFile );
927 
928  old_netcode = -1; old_width = -1; old_layer = -1;
929 
930  for( ii = 0; ii < nbitems; ii++ )
931  {
932  track = tracklist[ii];
933 
934  if( old_netcode != track->GetNetCode() )
935  {
936  old_netcode = track->GetNetCode();
937  NETINFO_ITEM* net = track->GetNet();
938  wxString netname;
939 
940  if( net && (net->GetNetname() != wxEmptyString) )
941  netname = net->GetNetname();
942  else
943  netname = wxT( "_noname_" );
944 
945  fprintf( aFile, "ROUTE %s\n", TO_UTF8( netname ) );
946  }
947 
948  if( old_width != track->GetWidth() )
949  {
950  old_width = track->GetWidth();
951  fprintf( aFile, "TRACK TRACK%d\n", track->GetWidth() );
952  }
953 
954  if( (track->Type() == PCB_TRACE_T) || (track->Type() == PCB_ZONE_T) )
955  {
956  if( old_layer != track->GetLayer() )
957  {
958  old_layer = track->GetLayer();
959  fprintf( aFile, "LAYER %s\n",
960  GenCADLayerName( cu_count, track->GetLayer() ).c_str()
961  );
962  }
963 
964  fprintf( aFile, "LINE %g %g %g %g\n",
965  MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ),
966  MapXTo( track->GetEnd().x ), MapYTo( track->GetEnd().y ) );
967  }
968 
969  if( track->Type() == PCB_VIA_T )
970  {
971  const VIA* via = static_cast<const VIA*>(track);
972 
973  LSET vset = via->GetLayerSet() & master_layermask;
974 
975  fprintf( aFile, "VIA VIA%d.%d.%s %g %g ALL %g via%d\n",
976  via->GetWidth(), via->GetDrillValue(),
977  fmt_mask( vset ).c_str(),
978  MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ),
979  via->GetDrillValue() / SCALE_FACTOR, vianum++ );
980  }
981  }
982 
983  fputs( "$ENDROUTES\n\n", aFile );
984 
985  delete tracklist;
986 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
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:247
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:532
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.
Definition: class_netinfo.h:69
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:246
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(), D_PAD::GetName(), MODULE::GetOrientation(), D_PAD::GetOrientation(), D_PAD::GetPos0(), D_PAD::GetSubRatsnest(), BOARD::m_Modules, MODULE::Next(), D_PAD::Next(), NORMALIZE_ANGLE_POS(), MODULE::PadsList(), SCALE_FACTOR, 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->PadsList(); 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  pinname = pad->GetName();
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:202
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:100
const wxPoint & GetPos0() const
Definition: class_pad.h:248
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:160
int GetSubRatsnest() const
Function GetSubRatsnest.
Definition: class_pad.h:614
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:377
D_PAD * Next() const
Definition: class_pad.h:145
const wxString & GetName() const
Definition: class_pad.h:175
static void FootprintWriteShape(FILE *File, MODULE *module)
DLIST< MODULE > m_Modules
Definition: class_board.h:245
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:357
static const double SCALE_FACTOR
DLIST< D_PAD > & PadsList()
Definition: class_module.h:134
static void CreateSignalsSection ( FILE *  aFile,
BOARD aPcb 
)
static

Definition at line 768 of file export_gencad.cpp.

References 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().

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->PadsList(); pad; pad = pad->Next() )
798  {
799  if( pad->GetNetCode() != net->GetNet() )
800  continue;
801 
802  msg.Printf( wxT( "NODE %s %s" ),
803  GetChars( module->GetReference() ),
804  GetChars( pad->GetName() ) );
805 
806  fputs( TO_UTF8( msg ), aFile );
807  fputs( "\n", aFile );
808  }
809  }
810  }
811 
812  fputs( "$ENDSIGNALS\n\n", aFile );
813 }
MODULE * Next() const
Definition: class_module.h:100
#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:145
const wxString & GetName() const
Definition: class_pad.h:175
int GetNet() const
Function GetNet.
int GetNetCode() const
Function GetNetCode.
Class NETINFO_ITEM handles the data for a net.
Definition: class_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:419
DLIST< MODULE > m_Modules
Definition: class_board.h:245
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
DLIST< D_PAD > & PadsList()
Definition: class_module.h:134
const wxString & GetNetname() const
Function GetNetname.
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:772
static void CreateTracksInfoData ( FILE *  aFile,
BOARD aPcb 
)
static

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

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

1123 {
1124  EDGE_MODULE* PtEdge;
1125  EDA_ITEM* PtStruct;
1126 
1127  // Control Y axis change sign for flipped modules
1128  int Yaxis_sign = -1;
1129 
1130  // Flip for bottom side components
1131  if( module->GetFlag() )
1132  Yaxis_sign = 1;
1133 
1134  /* creates header: */
1135  fprintf( aFile, "\nSHAPE %s\n", TO_UTF8( module->GetReference() ) );
1136 
1137  if( module->GetAttributes() & MOD_VIRTUAL )
1138  {
1139  fprintf( aFile, "INSERT SMD\n" );
1140  }
1141  else
1142  {
1143  if( module->GetAttributes() & MOD_CMS )
1144  {
1145  fprintf( aFile, "INSERT SMD\n" );
1146  }
1147  else
1148  {
1149  fprintf( aFile, "INSERT TH\n" );
1150  }
1151  }
1152 
1153 #if 0 /* ATTRIBUTE name and value is unspecified and the original exporter
1154  * got the syntax wrong, so CAM350 rejected the whole shape! */
1155 
1156  if( module->m_Attributs != MOD_DEFAULT )
1157  {
1158  fprintf( aFile, "ATTRIBUTE" );
1159 
1160  if( module->m_Attributs & MOD_CMS )
1161  fprintf( aFile, " PAD_SMD" );
1162 
1163  if( module->m_Attributs & MOD_VIRTUAL )
1164  fprintf( aFile, " VIRTUAL" );
1165 
1166  fprintf( aFile, "\n" );
1167  }
1168 #endif
1169 
1170  // Silk outline; wildly interpreted by various importers:
1171  // CAM350 read it right but only closed shapes
1172  // ProntoPlace double-flip it (at least the pads are correct)
1173  // GerberTool usually get it right...
1174  for( PtStruct = module->GraphicalItemsList(); PtStruct; PtStruct = PtStruct->Next() )
1175  {
1176  switch( PtStruct->Type() )
1177  {
1178  case PCB_MODULE_TEXT_T:
1179 
1180  // If we wanted to export text, this is not the correct section
1181  break;
1182 
1183  case PCB_MODULE_EDGE_T:
1184  PtEdge = (EDGE_MODULE*) PtStruct;
1185  if( PtEdge->GetLayer() == F_SilkS
1186  || PtEdge->GetLayer() == B_SilkS )
1187  {
1188  switch( PtEdge->GetShape() )
1189  {
1190  case S_SEGMENT:
1191  fprintf( aFile, "LINE %g %g %g %g\n",
1192  (PtEdge->m_Start0.x) / SCALE_FACTOR,
1193  (Yaxis_sign * PtEdge->m_Start0.y) / SCALE_FACTOR,
1194  (PtEdge->m_End0.x) / SCALE_FACTOR,
1195  (Yaxis_sign * PtEdge->m_End0.y ) / SCALE_FACTOR );
1196  break;
1197 
1198  case S_CIRCLE:
1199  {
1200  int radius = KiROUND( GetLineLength( PtEdge->m_End0,
1201  PtEdge->m_Start0 ) );
1202  fprintf( aFile, "CIRCLE %g %g %g\n",
1203  PtEdge->m_Start0.x / SCALE_FACTOR,
1204  Yaxis_sign * PtEdge->m_Start0.y / SCALE_FACTOR,
1205  radius / SCALE_FACTOR );
1206  break;
1207  }
1208 
1209  case S_ARC:
1210  {
1211  int arcendx, arcendy;
1212  arcendx = PtEdge->m_End0.x - PtEdge->m_Start0.x;
1213  arcendy = PtEdge->m_End0.y - PtEdge->m_Start0.y;
1214  RotatePoint( &arcendx, &arcendy, -PtEdge->GetAngle() );
1215  arcendx += PtEdge->GetStart0().x;
1216  arcendy += PtEdge->GetStart0().y;
1217  if( Yaxis_sign == -1 )
1218  {
1219  // Flipping Y flips the arc direction too
1220  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
1221  (arcendx) / SCALE_FACTOR,
1222  (Yaxis_sign * arcendy) / SCALE_FACTOR,
1223  (PtEdge->m_End0.x) / SCALE_FACTOR,
1224  (Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
1225  (PtEdge->GetStart0().x) / SCALE_FACTOR,
1226  (Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
1227  }
1228  else
1229  {
1230  fprintf( aFile, "ARC %g %g %g %g %g %g\n",
1231  (PtEdge->GetEnd0().x) / SCALE_FACTOR,
1232  (Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
1233  (arcendx) / SCALE_FACTOR,
1234  (Yaxis_sign * arcendy) / SCALE_FACTOR,
1235  (PtEdge->GetStart0().x) / SCALE_FACTOR,
1236  (Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
1237  }
1238  break;
1239  }
1240 
1241  case S_POLYGON:
1242  // Not exported (TODO)
1243  break;
1244 
1245  default:
1246  DisplayError( NULL, wxString::Format( "Type Edge Module %d invalid.", PtStruct->Type() ) );
1247  break;
1248  }
1249  }
1250  break;
1251 
1252  default:
1253  break;
1254  }
1255  }
1256 }
int GetFlag() const
Definition: class_module.h:202
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
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:77
usual segment : line with rounded ends
EDA_ITEM * Next() const
Definition: base_struct.h:220
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
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:197
default
Definition: class_module.h:76
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:419
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:165
static const double SCALE_FACTOR
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:137
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:71
int m_Attributs
Flag bits ( see Mod_Attribut )
Definition: class_module.h:678
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:1063
static int TrackListSortByNetcode ( const void *  refptr,
const void *  objptr 
)
static

Definition at line 857 of file export_gencad.cpp.

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

Referenced by CreateRoutesSection().

858 {
859  const TRACK* ref, * cmp;
860  int diff;
861 
862  ref = *( (TRACK**) refptr );
863  cmp = *( (TRACK**) objptr );
864 
865  if( ( diff = ref->GetNetCode() - cmp->GetNetCode() ) )
866  return diff;
867 
868  if( ( diff = ref->GetWidth() - cmp->GetWidth() ) )
869  return diff;
870 
871  if( ( diff = ref->GetLayer() - cmp->GetLayer() ) )
872  return diff;
873 
874  return 0;
875 }
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