KiCad PCB EDA Suite
FABMASTER Class Reference

#include <import_fabmaster.h>

Classes

struct  CLASS
 
struct  COMPONENT
 
struct  FABMASTER_LAYER
 A!LAYER_SORT!LAYER_SUBCLASS!LAYER_ARTWORK!LAYER_USE!LAYER_CONDUCTOR!LAYER_DIELECTRIC_CONSTANT !LAYER_ELECTRICAL_CONDUCTIVITY!LAYER_MATERIAL!LAYER_SHIELD_LAYER!LAYER_THERMAL_CONDUCTIVITY!LAYER_THICKNESS! More...
 
struct  FABMASTER_PAD_SHAPE
 A!SUBCLASS!PAD_SHAPE_NAME!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1! GRAPHIC_DATA_2!GRAPHIC_DATA_3!GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7! GRAPHIC_DATA_8!GRAPHIC_DATA_9!PAD_STACK_NAME!REFDES!PIN_NUMBER! More...
 
struct  FM_PAD
 
struct  FM_VIA
 
struct  GEOM_GRAPHIC
 
struct  GRAPHIC_ARC
 
struct  GRAPHIC_DATA
 
struct  GRAPHIC_ITEM
 
struct  GRAPHIC_LINE
 
struct  GRAPHIC_RECTANGLE
 
struct  GRAPHIC_TEXT
 
struct  NETNAME
 
struct  PIN
 
struct  SYMBOL
 
struct  TRACE
 

Public Types

using single_row = std::vector< std::string >
 

Public Member Functions

 FABMASTER ()
 
bool Read (const std::string &aFile)
 
bool Process ()
 
bool LoadBoard (BOARD *aBoard, PROGRESS_REPORTER *aProgressReporter)
 

Private Types

enum  section_type : int {
  UNKNOWN_EXTRACT, EXTRACT_PADSTACKS, EXTRACT_PAD_SHAPES, EXTRACT_FULL_LAYERS,
  EXTRACT_VIAS, FABMASTER_EXTRACT_PINS, EXTRACT_PINS, EXTRACT_TRACES,
  EXTRACT_GRAPHICS, EXTRACT_BASIC_LAYERS, EXTRACT_NETS, EXTRACT_REFDES
}
 
enum  COMPCLASS { COMPCLASS_NONE, COMPCLASS_IO, COMPCLASS_IC, COMPCLASS_DISCRETE }
 
enum  SYMTYPE {
  SYMTYPE_NONE, SYMTYPE_PACKAGE, SYMTYPE_MECH, SYMTYPE_FORMAT,
  SYMTYPE_DRAFTING
}
 
enum  GRAPHIC_SHAPE {
  GR_SHAPE_LINE, GR_SHAPE_TEXT, GR_SHAPE_RECTANGLE, GR_SHAPE_ARC,
  GR_SHAPE_CIRCLE
}
 
enum  GRAPHIC_TYPE {
  GR_TYPE_NONE, GR_TYPE_CONNECT, GR_TYPE_NOTCONNECT, GR_TYPE_SHAPE,
  GR_TYPE_POLYGON, GR_TYPE_VOID
}
 
using graphic_element = std::set< std::unique_ptr< GRAPHIC_ITEM >, GRAPHIC_ITEM::SEQ_CMP >
 

Private Member Functions

section_type detectType (size_t aOffset)
 
void checkpoint ()
 
int execute_recordbuffer (int filetype)
 
int getColFromName (size_t aRow, const std::string &aStr)
 
SYMTYPE parseSymType (const std::string &aSymType)
 
COMPCLASS parseCompClass (const std::string &aCompClass)
 
double processScaleFactor (size_t aRow)
 Processes data from text vectors into internal database for further ordering. More...
 
size_t processPadStacks (size_t aRow)
 A!PADNAME!RECNUMBER!LAYER!FIXFLAG!VIAFLAG!PADSHAPE1!PADWIDTH!PADHGHT! PADXOFF!PADYOFF!PADFLASH!PADSHAPENAME!TRELSHAPE1!TRELWIDTH!TRELHGHT! TRELXOFF!TRELYOFF!TRELFLASH!TRELSHAPENAME!APADSHAPE1!APADWIDTH!APADHGHT! APADXOFF!APADYOFF!APADFLASH!APADSHAPENAME! More...
 
size_t processCustomPads (size_t aRow)
 A!SUBCLASS!PAD_SHAPE_NAME!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1! GRAPHIC_DATA_2!GRAPHIC_DATA_3!GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7! GRAPHIC_DATA_8!GRAPHIC_DATA_9!PAD_STACK_NAME!REFDES!PIN_NUMBER! More...
 
size_t processGeometry (size_t aRow)
 A!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2!GRAPHIC_DATA_3! GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7!GRAPHIC_DATA_8!GRAPHIC_DATA_9! SUBCLASS!SYM_NAME!REFDES! More...
 
size_t processVias (size_t aRow)
 A!VIA_X!VIA_Y!PAD_STACK_NAME!NET_NAME!TEST_POINT! More...
 
size_t processTraces (size_t aRow)
 A!CLASS!SUBCLASS!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2! GRAPHIC_DATA_3!GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7!GRAPHIC_DATA_8! GRAPHIC_DATA_9!NET_NAME! More...
 
size_t processFootprints (size_t aRow)
 A!REFDES!COMP_CLASS!COMP_PART_NUMBER!COMP_HEIGHT!COMP_DEVICE_LABEL!COMP_INSERTION_CODE!SYM_TYPE! SYM_NAME!SYM_MIRROR!SYM_ROTATE!SYM_X!SYM_Y!COMP_VALUE!COMP_TOL!COMP_VOLTAGE! More...
 
size_t processNets (size_t aRow)
 A!NET_NAME!REFDES!PIN_NUMBER!PIN_NAME!PIN_GROUND!PIN_POWER! More...
 
size_t processLayers (size_t aRow)
 A!LAYER_SORT!LAYER_SUBCLASS!LAYER_ARTWORK!LAYER_USE!LAYER_CONDUCTOR!LAYER_DIELECTRIC_CONSTANT! LAYER_ELECTRICAL_CONDUCTIVITY!LAYER_MATERIAL!LAYER_SHIELD_LAYER!LAYER_THERMAL_CONDUCTIVITY! LAYER_THICKNESS! More...
 
size_t processSimpleLayers (size_t aRow)
 
size_t processPadStackLayers (size_t aRow)
 
size_t processSymbols (size_t aRow)
 
size_t processPins (size_t aRow)
 A!SYM_NAME!SYM_MIRROR!PIN_NAME!PIN_NUMBER!PIN_X!PIN_Y!PAD_STACK_NAME!REFDES!PIN_ROTATION!TEST_POINT! More...
 
GRAPHIC_ITEMprocessGraphic (const GRAPHIC_DATA &aData, double aScale)
 Specialty functions for processing graphical data rows into the internal database. More...
 
GRAPHIC_ARCprocessArc (const GRAPHIC_DATA &aData, double aScale)
 
GRAPHIC_LINEprocessLine (const GRAPHIC_DATA &aData, double aScale)
 
GRAPHIC_TEXTprocessText (const GRAPHIC_DATA &aData, double aScale)
 
GRAPHIC_RECTANGLEprocessRectangle (const GRAPHIC_DATA &aData, double aScale)
 
PCB_LAYER_ID getLayer (const std::string &aLayerName)
 
bool assignLayers ()
 
double readDouble (const std::string &aStr) const
 Reads the double/integer value from a std string independent of the user locale. More...
 
int readInt (const std::string &aStr) const
 
bool orderZones (BOARD *aBoard)
 Sets zone priorities based on zone BB size. More...
 
bool loadZones (BOARD *aBoard)
 Loads sections of the database into the board. More...
 
bool loadOutline (BOARD *aBoard, const std::unique_ptr< TRACE > &aLine)
 
bool loadNets (BOARD *aBoard)
 
bool loadLayers (BOARD *aBoard)
 
bool loadGraphics (BOARD *aBoard)
 
bool loadVias (BOARD *aBoard)
 
bool loadEtch (BOARD *aBoard, const std::unique_ptr< TRACE > &aLine)
 
bool loadZone (BOARD *aBoard, const std::unique_ptr< FABMASTER::TRACE > &aLine)
 
bool loadPolygon (BOARD *aBoard, const std::unique_ptr< FABMASTER::TRACE > &aLine)
 
bool loadFootprints (BOARD *aBoard)
 
SHAPE_POLY_SET loadShapePolySet (const graphic_element &aLine)
 

Private Attributes

wxFileName m_filename
 
std::deque< single_rowrows
 
bool has_pads
 
bool has_comps
 
bool has_graphic
 
bool has_nets
 
bool has_pins
 
std::unordered_map< std::string, FM_PADpads
 
std::map< std::pair< std::string, std::string >, NETNAMEpin_nets
 
std::set< std::string > netnames
 
std::map< std::string, FABMASTER_LAYERlayers
 
std::unordered_map< std::string, FABMASTER_PAD_SHAPEpad_shapes
 
std::unordered_map< std::string, SYMBOLsymbols
 
std::vector< GEOM_GRAPHICboard_graphics
 
std::map< std::string, std::map< int, GEOM_GRAPHIC > > comp_graphics
 
std::vector< std::unique_ptr< FM_VIA > > vias
 
std::set< std::unique_ptr< TRACE >, TRACE::BY_IDtraces
 
std::set< std::unique_ptr< TRACE >, TRACE::BY_IDzones
 
std::set< std::unique_ptr< TRACE >, TRACE::BY_IDpolygons
 
std::set< std::unique_ptr< TRACE >, TRACE::BY_IDrefdes
 
std::map< std::string, std::vector< std::unique_ptr< COMPONENT > > > components
 
std::map< std::string, std::set< std::unique_ptr< PIN >, PIN::BY_NUM > > pins
 
std::map< std::string, PCB_LAYER_IDlayer_map
 
PROGRESS_REPORTERm_progressReporter
 optional; may be nullptr More...
 
unsigned m_doneCount
 
unsigned m_lastProgressCount
 
unsigned m_totalCount
 for progress reporting More...
 

Detailed Description

Definition at line 50 of file import_fabmaster.h.

Member Typedef Documentation

◆ graphic_element

using FABMASTER::graphic_element = std::set<std::unique_ptr<GRAPHIC_ITEM>, GRAPHIC_ITEM::SEQ_CMP>
private

Definition at line 279 of file import_fabmaster.h.

◆ single_row

using FABMASTER::single_row = std::vector<std::string>

Definition at line 54 of file import_fabmaster.h.

Member Enumeration Documentation

◆ COMPCLASS

enum FABMASTER::COMPCLASS
private
Enumerator
COMPCLASS_NONE 
COMPCLASS_IO 
COMPCLASS_IC 
COMPCLASS_DISCRETE 

Definition at line 140 of file import_fabmaster.h.

◆ GRAPHIC_SHAPE

Enumerator
GR_SHAPE_LINE 
GR_SHAPE_TEXT 
GR_SHAPE_RECTANGLE 
GR_SHAPE_ARC 
GR_SHAPE_CIRCLE 

! Not actually in Fabmaster but we use for 360° arcs

Definition at line 189 of file import_fabmaster.h.

◆ GRAPHIC_TYPE

Enumerator
GR_TYPE_NONE 
GR_TYPE_CONNECT 
GR_TYPE_NOTCONNECT 
GR_TYPE_SHAPE 
GR_TYPE_POLYGON 
GR_TYPE_VOID 

Definition at line 198 of file import_fabmaster.h.

◆ section_type

enum FABMASTER::section_type : int
private
Enumerator
UNKNOWN_EXTRACT 
EXTRACT_PADSTACKS 
EXTRACT_PAD_SHAPES 
EXTRACT_FULL_LAYERS 
EXTRACT_VIAS 
FABMASTER_EXTRACT_PINS 
EXTRACT_PINS 
EXTRACT_TRACES 
EXTRACT_GRAPHICS 
EXTRACT_BASIC_LAYERS 
EXTRACT_NETS 
EXTRACT_REFDES 

Definition at line 78 of file import_fabmaster.h.

◆ SYMTYPE

enum FABMASTER::SYMTYPE
private
Enumerator
SYMTYPE_NONE 
SYMTYPE_PACKAGE 
SYMTYPE_MECH 
SYMTYPE_FORMAT 
SYMTYPE_DRAFTING 

Definition at line 148 of file import_fabmaster.h.

Constructor & Destructor Documentation

◆ FABMASTER()

FABMASTER::FABMASTER ( )
inline

Definition at line 55 of file import_fabmaster.h.

55  :
56  has_pads( false ),
57  has_comps( false ),
58  has_graphic( false ),
59  has_nets( false ),
60  has_pins( false ),
61  m_progressReporter( nullptr ),
62  m_doneCount( 0 ),
64  m_totalCount( 0 )
65 
66  {}
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
unsigned m_doneCount
unsigned m_totalCount
for progress reporting
unsigned m_lastProgressCount

Member Function Documentation

◆ assignLayers()

bool FABMASTER::assignLayers ( )
private

Back copper has a special id number, so assign that to the last copper layer in the stackup

Definition at line 711 of file import_fabmaster.cpp.

712 {
713  bool has_l1 = false;
714  int max_layer = 0;
715  std::string max_layer_name;
716 
717  std::vector<std::pair<std::string, int>> extra_layers
718  {
719  { "ASSEMBLY_TOP", F_Fab },
720  { "ASSEMBLY_BOTTOM", B_Fab },
721  { "PLACE_BOUND_TOP", F_CrtYd },
722  { "PLACE_BOUND_BOTTOM", B_CrtYd },
723  };
724 
725  std::vector<FABMASTER_LAYER*> layer_order;
726 
727  for( auto& el : layers )
728  {
729  FABMASTER_LAYER& layer = el.second;
730  layer.layerid = UNSELECTED_LAYER;
731 
732  if( layer.conductive )
733  {
734  layer_order.push_back( &layer );
735  }
736  else if( layer.name.find( "SILK" ) != std::string::npos &&
737  layer.name.find( "AUTOSILK" ) == std::string::npos ) // Skip the autosilk layer
738  {
739  if( layer.name.find( "B" ) != std::string::npos )
740  layer.layerid = B_SilkS;
741  else
742  layer.layerid = F_SilkS;
743  }
744  else if( layer.name.find( "MASK" ) != std::string::npos ||
745  layer.name.find( "MSK" ) != std::string::npos )
746  {
747  if( layer.name.find( "B" ) != std::string::npos )
748  layer.layerid = B_Mask;
749  else
750  layer.layerid = F_Mask;
751  }
752  else if( layer.name.find( "PAST" ) != std::string::npos )
753  {
754  if( layer.name.find( "B" ) != std::string::npos )
755  layer.layerid = B_Paste;
756  else
757  layer.layerid = F_Paste;
758  }
759  else if( layer.name.find( "NCLEGEND" ) != std::string::npos )
760  layer.layerid = Dwgs_User;
761  else
762  layer.disable = true;
763  }
764 
765  std::sort( layer_order.begin(), layer_order.end(), FABMASTER_LAYER::BY_ID() );
766  int layernum = 0;
767 
768  for( auto layer : layer_order )
769  layer->layerid = layernum++;
770 
773  layer_order.back()->layerid = B_Cu;
774 
775  for( auto& new_pair : extra_layers )
776  {
777  FABMASTER_LAYER new_layer;
778 
779  new_layer.name = new_pair.first;
780  new_layer.layerid = new_pair.second;
781  new_layer.conductive = false;
782 
783  auto result = layers.emplace( new_pair.first, new_layer );
784 
785  if( !result.second )
786  {
787  result.first->second.layerid = new_pair.second;
788  result.first->second.disable = false;
789  }
790  }
791 
792  return true;
793 }
std::map< std::string, FABMASTER_LAYER > layers

References B_CrtYd, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, FABMASTER::FABMASTER_LAYER::conductive, FABMASTER::FABMASTER_LAYER::disable, Dwgs_User, F_CrtYd, F_Fab, F_Mask, F_Paste, F_SilkS, FABMASTER::FABMASTER_LAYER::layerid, layers, FABMASTER::FABMASTER_LAYER::name, and UNSELECTED_LAYER.

Referenced by Process().

◆ checkpoint()

void FABMASTER::checkpoint ( )
private

Definition at line 61 of file import_fabmaster.cpp.

62 {
63  const unsigned PROGRESS_DELTA = 250;
64 
65  if( m_progressReporter )
66  {
67  if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA )
68  {
70  / std::max( 1U, m_totalCount ) );
71 
73  THROW_IO_ERROR( _( "Open cancelled by user." ) );
74 
76  }
77  }
78 }
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
#define _(s)
unsigned m_doneCount
unsigned m_totalCount
for progress reporting
unsigned m_lastProgressCount
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).

References _, PROGRESS_REPORTER::KeepRefreshing(), m_doneCount, m_lastProgressCount, m_progressReporter, m_totalCount, PROGRESS_REPORTER::SetCurrentProgress(), and THROW_IO_ERROR.

Referenced by LoadBoard(), loadFootprints(), loadGraphics(), loadLayers(), loadNets(), loadVias(), and loadZones().

◆ detectType()

FABMASTER::section_type FABMASTER::detectType ( size_t  aOffset)
private

We strip the underscores from all column names as some export variants use them and some do not

Definition at line 186 of file import_fabmaster.cpp.

187 {
188  single_row row;
189  try
190  {
191  row = rows.at( aOffset );
192  }
193  catch( std::out_of_range& )
194  {
195  return UNKNOWN_EXTRACT;
196  }
197 
198  if( row.size() < 3 )
199  return UNKNOWN_EXTRACT;
200 
201  if( row[0].back() != 'A' )
202  return UNKNOWN_EXTRACT;
203 
204  std::string row1 = row[1];
205  std::string row2 = row[2];
206  std::string row3{};
207 
209  alg::delete_if( row1, []( char c ){ return c == '_'; } );
210  alg::delete_if( row2, []( char c ){ return c == '_'; } );
211 
212  if( row.size() > 3 )
213  {
214  row3 = row[3];
215  alg::delete_if( row3, []( char c ){ return c == '_'; } );
216  }
217 
218  if( row1 == "REFDES" && row2 == "COMPCLASS" )
219  return EXTRACT_REFDES;
220 
221  if( row1 == "NETNAME" && row2 == "REFDES" )
222  return EXTRACT_NETS;
223 
224  if( row1 == "CLASS" && row2 == "SUBCLASS" && row3.empty() )
225  return EXTRACT_BASIC_LAYERS;
226 
227  if( row1 == "GRAPHICDATANAME" && row2 == "GRAPHICDATANUMBER" )
228  return EXTRACT_GRAPHICS;
229 
230  if( row1 == "CLASS" && row2 == "SUBCLASS" && row3 == "GRAPHICDATANAME" )
231  return EXTRACT_TRACES;
232 
233  if( row1 == "SYMNAME" && row2 == "PINNAME" )
234  return FABMASTER_EXTRACT_PINS;
235 
236  if( row1 == "SYMNAME" && row2 == "SYMMIRROR" && row3 == "PINNAME" )
237  return EXTRACT_PINS;
238 
239  if( row1 == "VIAX" && row2 == "VIAY" )
240  return EXTRACT_VIAS;
241 
242  if( row1 == "SUBCLASS" && row2 == "PADSHAPENAME" )
243  return EXTRACT_PAD_SHAPES;
244 
245  if( row1 == "PADNAME" )
246  return EXTRACT_PADSTACKS;
247 
248  if( row1 == "LAYERSORT" )
249  return EXTRACT_FULL_LAYERS;
250 
251  wxLogError( _( "Unknown FABMASTER section %s:%s at row %zu." ),
252  row1.c_str(),
253  row2.c_str(),
254  aOffset );
255  return UNKNOWN_EXTRACT;
256 
257 }
std::vector< std::string > single_row
#define _(s)
void delete_if(_Container &__c, _Function &&__f)
Deletes all values from __c for which __f returns true.
Definition: kicad_algo.h:173
std::deque< single_row > rows

References _, alg::delete_if(), EXTRACT_BASIC_LAYERS, EXTRACT_FULL_LAYERS, EXTRACT_GRAPHICS, EXTRACT_NETS, EXTRACT_PAD_SHAPES, EXTRACT_PADSTACKS, EXTRACT_PINS, EXTRACT_REFDES, EXTRACT_TRACES, EXTRACT_VIAS, FABMASTER_EXTRACT_PINS, rows, and UNKNOWN_EXTRACT.

Referenced by Process().

◆ execute_recordbuffer()

int FABMASTER::execute_recordbuffer ( int  filetype)
private

◆ getColFromName()

int FABMASTER::getColFromName ( size_t  aRow,
const std::string &  aStr 
)
private

Some Fabmaster headers include the underscores while others do not so we strip them uniformly before comparing

Definition at line 298 of file import_fabmaster.cpp.

299 {
300  if( aRow >= rows.size() )
301  return -1;
302 
303  std::vector<std::string> header = rows[aRow];
304 
305  for( size_t i = 0; i < header.size(); i++ )
306  {
309  alg::delete_if( header[i], []( const char c ) { return c == '_'; } );
310 
311  if( header[i] == aStr )
312  return i;
313  }
314 
315  THROW_IO_ERROR( wxString::Format( _( "Could not find column label %s." ), aStr.c_str() ) );
316  return -1;
317 }
#define _(s)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void delete_if(_Container &__c, _Function &&__f)
Deletes all values from __c for which __f returns true.
Definition: kicad_algo.h:173
std::deque< single_row > rows

References _, alg::delete_if(), Format(), rows, and THROW_IO_ERROR.

Referenced by processCustomPads(), processFootprints(), processGeometry(), processLayers(), processNets(), processPadStackLayers(), processPadStacks(), processPins(), processSimpleLayers(), processTraces(), and processVias().

◆ getLayer()

PCB_LAYER_ID FABMASTER::getLayer ( const std::string &  aLayerName)
private

Definition at line 320 of file import_fabmaster.cpp.

321 {
322  const auto& kicad_layer = layers.find( aLayerName);
323 
324  if( kicad_layer == layers.end() )
325  return UNDEFINED_LAYER;
326  else
327  return static_cast<PCB_LAYER_ID>( kicad_layer->second.layerid );
328 }
std::map< std::string, FABMASTER_LAYER > layers

References layers, and UNDEFINED_LAYER.

Referenced by loadEtch(), loadFootprints(), loadGraphics(), loadPolygon(), loadZone(), and loadZones().

◆ LoadBoard()

bool FABMASTER::LoadBoard ( BOARD aBoard,
PROGRESS_REPORTER aProgressReporter 
)

Definition at line 3027 of file import_fabmaster.cpp.

3028 {
3029  aBoard->SetFileName( m_filename.GetFullPath() );
3030  m_progressReporter = aProgressReporter;
3031 
3032  m_totalCount = netnames.size()
3033  + layers.size()
3034  + vias.size()
3035  + components.size()
3036  + zones.size()
3037  + board_graphics.size()
3038  + traces.size();
3039  m_doneCount = 0;
3040 
3041  loadNets( aBoard );
3042  loadLayers( aBoard );
3043  loadVias( aBoard );
3044  loadFootprints( aBoard );
3045  loadZones( aBoard );
3046  loadGraphics( aBoard );
3047 
3048  for( auto& track : traces )
3049  {
3050  checkpoint();
3051 
3052  if( track->lclass == "ETCH" )
3053  loadEtch( aBoard, track);
3054  else if( track->layer == "OUTLINE" )
3055  loadOutline( aBoard, track );
3056  }
3057 
3058  orderZones( aBoard );
3059 
3060  return true;
3061 }
std::map< std::string, std::vector< std::unique_ptr< COMPONENT > > > components
bool loadGraphics(BOARD *aBoard)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
bool loadEtch(BOARD *aBoard, const std::unique_ptr< TRACE > &aLine)
std::map< std::string, FABMASTER_LAYER > layers
std::vector< std::unique_ptr< FM_VIA > > vias
bool loadNets(BOARD *aBoard)
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > traces
std::vector< GEOM_GRAPHIC > board_graphics
bool loadFootprints(BOARD *aBoard)
bool loadVias(BOARD *aBoard)
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > zones
void SetFileName(const wxString &aFileName)
Definition: board.h:227
std::set< std::string > netnames
unsigned m_doneCount
unsigned m_totalCount
for progress reporting
wxFileName m_filename
bool orderZones(BOARD *aBoard)
Sets zone priorities based on zone BB size.
bool loadZones(BOARD *aBoard)
Loads sections of the database into the board.
bool loadLayers(BOARD *aBoard)
bool loadOutline(BOARD *aBoard, const std::unique_ptr< TRACE > &aLine)

References board_graphics, checkpoint(), components, layers, loadEtch(), loadFootprints(), loadGraphics(), loadLayers(), loadNets(), loadOutline(), loadVias(), loadZones(), m_doneCount, m_filename, m_progressReporter, m_totalCount, netnames, orderZones(), BOARD::SetFileName(), traces, vias, and zones.

Referenced by FABMASTER_PLUGIN::Load().

◆ loadEtch()

bool FABMASTER::loadEtch ( BOARD aBoard,
const std::unique_ptr< TRACE > &  aLine 
)
private

Definition at line 2521 of file import_fabmaster.cpp.

2522 {
2523  const NETNAMES_MAP& netinfo = aBoard->GetNetInfo().NetsByName();
2524  auto net_it = netinfo.find( aLine->netname );
2525 
2526  int last_subseq = 0;
2527  ZONE* new_zone = nullptr;
2528 
2529  for( const auto& seg : aLine->segment )
2530  {
2531  PCB_LAYER_ID layer = getLayer( seg->layer );
2532 
2533  if( IsCopperLayer( layer ) )
2534  {
2535  if( seg->shape == GR_SHAPE_LINE )
2536  {
2537  const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2538 
2539  PCB_TRACK* trk = new PCB_TRACK( aBoard );
2540 
2541  trk->SetLayer( layer );
2542  trk->SetStart( wxPoint( src->start_x, src->start_y ) );
2543  trk->SetEnd( wxPoint( src->end_x, src->end_y ) );
2544  trk->SetWidth( src->width );
2545 
2546  if( net_it != netinfo.end() )
2547  trk->SetNet( net_it->second );
2548 
2549  aBoard->Add( trk, ADD_MODE::APPEND );
2550  }
2551  else if( seg->shape == GR_SHAPE_ARC )
2552  {
2553  const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2554 
2555  PCB_ARC* trk = new PCB_ARC( aBoard, &src->result );
2556  trk->SetLayer( layer );
2557  trk->SetWidth( src->width );
2558 
2559  if( net_it != netinfo.end() )
2560  trk->SetNet( net_it->second );
2561 
2562  aBoard->Add( trk, ADD_MODE::APPEND );
2563  }
2564  }
2565  else
2566  {
2567  wxLogError( _( "Expecting etch data to be on copper layer. Row found on layer '%s'" ),
2568  seg->layer.c_str() );
2569  }
2570  }
2571 
2572  return true;
2573 }
PCB_LAYER_ID getLayer(const std::string &aLayerName)
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:680
const NETNAMES_MAP & NetsByName() const
Return the name map, at least for python.
Definition: netinfo.h:365
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
#define _(s)
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:808
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65

References _, BOARD::Add(), APPEND, FABMASTER::GRAPHIC_LINE::end_x, FABMASTER::GRAPHIC_LINE::end_y, getLayer(), BOARD::GetNetInfo(), GR_SHAPE_ARC, GR_SHAPE_LINE, IsCopperLayer(), NETINFO_LIST::NetsByName(), FABMASTER::GRAPHIC_ARC::result, FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, and FABMASTER::GRAPHIC_ITEM::width.

Referenced by LoadBoard().

◆ loadFootprints()

bool FABMASTER::loadFootprints ( BOARD aBoard)
private

Always set the module to the top and flip later if needed When flipping later, we get the full coordinate transform for free

TODO:Warning

Definition at line 1970 of file import_fabmaster.cpp.

1971 {
1972  const NETNAMES_MAP& netinfo = aBoard->GetNetInfo().NetsByName();
1973  const auto& ds = aBoard->GetDesignSettings();
1974 
1975  for( auto& mod : components )
1976  {
1977  checkpoint();
1978 
1979  bool has_multiple = mod.second.size() > 1;
1980 
1981  for( int i = 0; i < mod.second.size(); ++i )
1982  {
1983  auto& src = mod.second[i];
1984 
1985  FOOTPRINT* fp = new FOOTPRINT( aBoard );
1986 
1987  wxString mod_ref = src->name;
1988  wxString lib_ref = m_filename.GetName();
1989 
1990  if( has_multiple )
1991  mod_ref.Append( wxString::Format( wxT( "_%d" ), i ) );
1992 
1993  ReplaceIllegalFileNameChars( lib_ref, '_' );
1994  ReplaceIllegalFileNameChars( mod_ref, '_' );
1995 
1996  wxString key = !lib_ref.empty() ? lib_ref + wxT( ":" ) + mod_ref : mod_ref;
1997 
1998  LIB_ID fpID;
1999  fpID.Parse( key, true );
2000  fp->SetFPID( fpID );
2001 
2002  fp->SetPosition( wxPoint( src->x, src->y ) );
2003  fp->SetOrientationDegrees( -src->rotate );
2004 
2005  // KiCad netlisting requires parts to have non-digit + digit annotation.
2006  // If the reference begins with a number, we prepend 'UNK' (unknown) for the source designator
2007  wxString reference = src->refdes;
2008 
2009  if( !std::isalpha( src->refdes[0] ) )
2010  reference.Prepend( "UNK" );
2011 
2012  fp->SetReference( reference );
2013 
2014  fp->SetValue( src->value );
2015  fp->Value().SetLayer( F_Fab );
2016  fp->Value().SetVisible( false );
2017 
2018  for( auto& ref : refdes )
2019  {
2020  const GRAPHIC_TEXT *lsrc =
2021  static_cast<const GRAPHIC_TEXT*>( ( *( ref->segment.begin() ) ).get() );
2022 
2023  if( lsrc->text == src->refdes )
2024  {
2025  FP_TEXT* txt = nullptr;
2026  PCB_LAYER_ID layer = getLayer( ref->layer );
2027 
2028  if( !IsPcbLayer( layer ) )
2029  {
2030  printf("The layer %s is not mapped?\n", ref->layer.c_str() );
2031  continue;
2032  }
2033 
2034  if( layer == F_SilkS || layer == B_SilkS )
2035  txt = &( fp->Reference() );
2036  else
2037  txt = new FP_TEXT( fp );
2038 
2039  if( src->mirror )
2040  {
2041  txt->SetLayer( FlipLayer( layer ) );
2042  txt->SetTextPos( wxPoint( lsrc->start_x, 2 * src->y - ( lsrc->start_y - lsrc->height / 2 ) ) );
2043  }
2044  else
2045  {
2046  txt->SetLayer( layer );
2047  txt->SetTextPos( wxPoint( lsrc->start_x, lsrc->start_y - lsrc->height / 2 ) );
2048  }
2049 
2050  txt->SetText( lsrc->text );
2051  txt->SetItalic( lsrc->ital );
2052  txt->SetTextThickness( lsrc->thickness );
2053  txt->SetTextHeight( lsrc->height );
2054  txt->SetTextWidth( lsrc->width );
2055  txt->SetHorizJustify( lsrc->orient );
2056  txt->SetLocalCoord();
2057 
2058  if( txt != &fp->Reference() )
2059  fp->Add( txt, ADD_MODE::APPEND );
2060  }
2061  }
2062 
2065  fp->SetLayer( F_Cu );
2066 
2067  auto gr_it = comp_graphics.find( src->refdes );
2068 
2069  if( gr_it == comp_graphics.end() )
2070  {
2071  continue;
2072  //TODO: Error
2073  }
2074 
2075  for( auto& gr_ref : gr_it->second )
2076  {
2077  auto& graphic = gr_ref.second;
2078 
2079  for( auto& seg : *graphic.elements )
2080  {
2081  PCB_LAYER_ID layer = Dwgs_User;
2082 
2083  if( IsPcbLayer( getLayer( seg->layer ) ) )
2084  layer = getLayer( seg->layer );
2085 
2086  switch( seg->shape )
2087  {
2088 
2089  case GR_SHAPE_LINE:
2090  {
2091  const GRAPHIC_LINE* lsrc = static_cast<const GRAPHIC_LINE*>( seg.get() );
2092 
2093  FP_SHAPE* line = new FP_SHAPE( fp, SHAPE_T::SEGMENT );
2094 
2095  if( src->mirror )
2096  {
2097  line->SetLayer( FlipLayer( layer ) );
2098  line->SetStart( wxPoint( lsrc->start_x, 2 * src->y - lsrc->start_y ) );
2099  line->SetEnd( wxPoint( lsrc->end_x, 2 * src->y - lsrc->end_y ) );
2100  }
2101  else
2102  {
2103  line->SetLayer( layer );
2104  line->SetStart( wxPoint( lsrc->start_x, lsrc->start_y ) );
2105  line->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
2106  }
2107 
2108  line->SetWidth( lsrc->width );
2109  line->SetLocalCoord();
2110 
2111  if( lsrc->width == 0 )
2112  line->SetWidth( ds.GetLineThickness( line->GetLayer() ) );
2113 
2114  fp->Add( line, ADD_MODE::APPEND );
2115  break;
2116  }
2117  case GR_SHAPE_CIRCLE:
2118  {
2119  const GRAPHIC_ARC* lsrc = static_cast<const GRAPHIC_ARC*>( seg.get() );
2120 
2121  FP_SHAPE* circle = new FP_SHAPE( fp, SHAPE_T::CIRCLE );
2122 
2123  circle->SetLayer( layer );
2124  circle->SetCenter( wxPoint( lsrc->center_x, lsrc->center_y ) );
2125  circle->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
2126  circle->SetWidth( lsrc->width );
2127  circle->SetLocalCoord();
2128 
2129  if( lsrc->width == 0 )
2130  circle->SetWidth( ds.GetLineThickness( circle->GetLayer() ) );
2131 
2132  if( src->mirror )
2133  circle->Flip( circle->GetCenter(), false );
2134 
2135  fp->Add( circle, ADD_MODE::APPEND );
2136  break;
2137  }
2138  case GR_SHAPE_ARC:
2139  {
2140  const GRAPHIC_ARC* lsrc = static_cast<const GRAPHIC_ARC*>( seg.get() );
2141 
2142  FP_SHAPE* arc = new FP_SHAPE( fp, SHAPE_T::ARC );
2143 
2144  arc->SetLayer( layer );
2145  arc->SetArcGeometry( (wxPoint) lsrc->result.GetP0(),
2146  (wxPoint) lsrc->result.GetArcMid(),
2147  (wxPoint) lsrc->result.GetP1() );
2148  arc->SetWidth( lsrc->width );
2149  arc->SetLocalCoord();
2150 
2151  if( lsrc->width == 0 )
2152  arc->SetWidth( ds.GetLineThickness( arc->GetLayer() ) );
2153 
2154  if( src->mirror )
2155  arc->Flip( arc->GetCenter(), false );
2156 
2157  fp->Add( arc, ADD_MODE::APPEND );
2158  break;
2159  }
2160  case GR_SHAPE_RECTANGLE:
2161  {
2162  const GRAPHIC_RECTANGLE *lsrc =
2163  static_cast<const GRAPHIC_RECTANGLE*>( seg.get() );
2164 
2165  FP_SHAPE* rect = new FP_SHAPE( fp, SHAPE_T::RECT );
2166 
2167  if( src->mirror )
2168  {
2169  rect->SetLayer( FlipLayer( layer ) );
2170  rect->SetStart( wxPoint( lsrc->start_x, 2 * src->y - lsrc->start_y ) );
2171  rect->SetEnd( wxPoint( lsrc->end_x, 2 * src->y - lsrc->end_y ) );
2172  }
2173  else
2174  {
2175  rect->SetLayer( layer );
2176  rect->SetStart( wxPoint( lsrc->start_x, lsrc->start_y ) );
2177  rect->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
2178  }
2179 
2180  rect->SetWidth( ds.GetLineThickness( rect->GetLayer() ) );
2181  rect->SetLocalCoord();
2182 
2183  fp->Add( rect, ADD_MODE::APPEND );
2184  break;
2185  }
2186  case GR_SHAPE_TEXT:
2187  {
2188  const GRAPHIC_TEXT *lsrc =
2189  static_cast<const GRAPHIC_TEXT*>( seg.get() );
2190 
2191  FP_TEXT* txt = new FP_TEXT( fp );
2192 
2193  if( src->mirror )
2194  {
2195  txt->SetLayer( FlipLayer( layer ) );
2196  txt->SetTextPos( wxPoint( lsrc->start_x, 2 * src->y - ( lsrc->start_y - lsrc->height / 2 ) ) );
2197  }
2198  else
2199  {
2200  txt->SetLayer( layer );
2201  txt->SetTextPos( wxPoint( lsrc->start_x, lsrc->start_y - lsrc->height / 2 ) );
2202  }
2203 
2204  txt->SetText( lsrc->text );
2205  txt->SetItalic( lsrc->ital );
2206  txt->SetTextThickness( lsrc->thickness );
2207  txt->SetTextHeight( lsrc->height );
2208  txt->SetTextWidth( lsrc->width );
2209  txt->SetHorizJustify( lsrc->orient );
2210  txt->SetLocalCoord();
2211 
2212  // FABMASTER doesn't have visibility flags but layers that are not silk should be hidden
2213  // by default to prevent clutter.
2214  if( txt->GetLayer() != F_SilkS && txt->GetLayer() != B_SilkS )
2215  txt->SetVisible( false );
2216 
2217  fp->Add( txt, ADD_MODE::APPEND );
2218  break;
2219  }
2220  default:
2221  continue;
2222  }
2223  }
2224  }
2225 
2226  auto pin_it = pins.find( src->refdes );
2227 
2228  if( pin_it != pins.end() )
2229  {
2230  for( auto& pin : pin_it->second )
2231  {
2232  auto pin_net_it = pin_nets.find( std::make_pair( pin->refdes, pin->pin_number ) );
2233  auto padstack = pads.find( pin->padstack );
2234  std::string netname = "";
2235 
2236  if( pin_net_it != pin_nets.end() )
2237  netname = pin_net_it->second.name;
2238 
2239  auto net_it = netinfo.find( netname );
2240 
2241  PAD* newpad = new PAD( fp );
2242 
2243  if( net_it != netinfo.end() )
2244  newpad->SetNet( net_it->second );
2245  else
2246  newpad->SetNetCode( 0 );
2247 
2248  newpad->SetX( pin->pin_x );
2249 
2250  if( src->mirror )
2251  newpad->SetY( 2 * src->y - pin->pin_y );
2252  else
2253  newpad->SetY( pin->pin_y );
2254 
2255  newpad->SetNumber( pin->pin_number );
2256 
2257  if( padstack == pads.end() )
2258  {
2260  delete newpad;
2261  continue;
2262  }
2263  else
2264  {
2265  auto& pad = padstack->second;
2266 
2267  newpad->SetShape( pad.shape );
2268 
2269  if( pad.shape == PAD_SHAPE::CUSTOM )
2270  {
2271  // Choose the smaller dimension to ensure the base pad
2272  // is fully hidden by the custom pad
2273  int pad_size = std::min( pad.width, pad.height );
2274 
2275  newpad->SetSize( wxSize( pad_size / 2, pad_size / 2 ) );
2276 
2277  std::string custom_name = pad.custom_name + "_" + pin->refdes + "_" + pin->pin_number;
2278  auto custom_it = pad_shapes.find( custom_name );
2279 
2280  if( custom_it != pad_shapes.end() )
2281  {
2282 
2283  SHAPE_POLY_SET poly_outline;
2284  int last_subseq = 0;
2285  int hole_idx = -1;
2286 
2287  poly_outline.NewOutline();
2288 
2289  // Custom pad shapes have a group of elements
2290  // that are a list of graphical polygons
2291  for( const auto& el : (*custom_it).second.elements )
2292  {
2293  // For now, we are only processing the custom pad for the top layer
2294  // TODO: Use full padstacks when implementing in KiCad
2295  PCB_LAYER_ID primary_layer = src->mirror ? B_Cu : F_Cu;
2296 
2297  if( getLayer( ( *( el.second.begin() ) )->layer ) != primary_layer )
2298  continue;
2299 
2300  for( const auto& seg : el.second )
2301  {
2302  if( seg->subseq > 0 || seg->subseq != last_subseq )
2303  {
2304  poly_outline.Polygon(0).back().SetClosed( true );
2305  hole_idx = poly_outline.AddHole( SHAPE_LINE_CHAIN{} );
2306  }
2307 
2308  if( seg->shape == GR_SHAPE_LINE )
2309  {
2310  const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2311 
2312  if( poly_outline.VertexCount( 0, hole_idx ) == 0 )
2313  poly_outline.Append( src->start_x, src->start_y, 0, hole_idx );
2314 
2315  poly_outline.Append( src->end_x, src->end_y, 0, hole_idx );
2316  }
2317  else if( seg->shape == GR_SHAPE_ARC )
2318  {
2319  const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2320  SHAPE_LINE_CHAIN& chain = poly_outline.Hole( 0, hole_idx );
2321 
2322  chain.Append( src->result );
2323  }
2324  }
2325  }
2326 
2327  if( poly_outline.OutlineCount() < 1
2328  || poly_outline.Outline( 0 ).PointCount() < 3 )
2329  {
2330  wxLogError( _( "Invalid custom pad '%s'. Replacing with "
2331  "circular pad." ),
2332  custom_name.c_str() );
2333  newpad->SetShape( PAD_SHAPE::CIRCLE );
2334  }
2335  else
2336  {
2337  poly_outline.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
2338 
2339  poly_outline.Move( -newpad->GetPosition() );
2340 
2341  if( src->mirror )
2342  {
2343  poly_outline.Mirror( false, true, VECTOR2I( 0, ( pin->pin_y - src->y ) ) );
2344  poly_outline.Rotate( ( -src->rotate + pin->rotation ) * M_PI / 180.0 );
2345  }
2346  else
2347  {
2348  poly_outline.Rotate( ( src->rotate - pin->rotation ) * M_PI / 180.0 );
2349  }
2350 
2351  newpad->AddPrimitivePoly( poly_outline, 0, true );
2352  }
2353 
2354  SHAPE_POLY_SET mergedPolygon;
2355  newpad->MergePrimitivesAsPolygon( &mergedPolygon );
2356 
2357  if( mergedPolygon.OutlineCount() > 1 )
2358  {
2359  wxLogError( _( "Invalid custom pad '%s'. Replacing with "
2360  "circular pad." ),
2361  custom_name.c_str() );
2362  newpad->SetShape( PAD_SHAPE::CIRCLE );
2363  }
2364  }
2365  else
2366  {
2367  wxLogError( _( "Could not find custom pad '%s'." ),
2368  custom_name.c_str() );
2369  }
2370  }
2371  else
2372  newpad->SetSize( wxSize( pad.width, pad.height ) );
2373 
2374  if( pad.drill )
2375  {
2376  if( pad.plated )
2377  {
2378  newpad->SetAttribute( PAD_ATTRIB::PTH );
2379  newpad->SetLayerSet( PAD::PTHMask() );
2380  }
2381  else
2382  {
2383  newpad->SetAttribute( PAD_ATTRIB::NPTH );
2384  newpad->SetLayerSet( PAD::UnplatedHoleMask() );
2385  }
2386 
2387  if( pad.drill_size_x == pad.drill_size_y )
2389  else
2391 
2392  newpad->SetDrillSize( wxSize( pad.drill_size_x, pad.drill_size_y ) );
2393  }
2394  else
2395  {
2396  newpad->SetAttribute( PAD_ATTRIB::SMD );
2397 
2398  if( pad.top )
2399  newpad->SetLayerSet( PAD::SMDMask() );
2400  else if( pad.bottom )
2401  newpad->SetLayerSet( FlipLayerMask( PAD::SMDMask() ) );
2402  }
2403  }
2404 
2405  newpad->SetLocalCoord();
2406 
2407  if( src->mirror )
2408  newpad->SetOrientation( ( -src->rotate + pin->rotation ) * 10.0 );
2409  else
2410  newpad->SetOrientation( ( src->rotate - pin->rotation ) * 10.0 );
2411 
2412  fp->Add( newpad, ADD_MODE::APPEND );
2413  }
2414  }
2415 
2416  if( src->mirror )
2417  {
2418  fp->SetOrientationDegrees( 180.0 - src->rotate );
2419  fp->Flip( fp->GetPosition(), true );
2420  }
2421 
2422  aBoard->Add( fp, ADD_MODE::APPEND );
2423  }
2424  }
2425 
2426  return true;
2427 }
void SetReference(const wxString &aReference)
Definition: footprint.h:472
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint.
Definition: lset.cpp:576
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void SetAttribute(PAD_ATTRIB aAttribute)
Definition: pad.cpp:611
std::map< std::string, std::map< int, GEOM_GRAPHIC > > comp_graphics
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
std::map< std::string, std::vector< std::unique_ptr< COMPONENT > > > components
void SetItalic(bool isItalic)
Definition: eda_text.h:200
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:530
Smd pad, appears on the solder paste layer (default)
int VertexCount(int aOutline=-1, int aHole=-1) const
Return the number of points in the shape poly set.
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:267
PCB_LAYER_ID getLayer(const std::string &aLayerName)
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:680
void SetOrientationDegrees(double aOrientation)
Definition: footprint.h:190
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
void SetSize(const wxSize &aSize)
Definition: pad.h:232
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
int PointCount() const
Return the number of points (vertices) in this line chain.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
bool IsPcbLayer(LAYER_NUM aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:797
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Plated through hole pad.
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:499
const NETNAMES_MAP & NetsByName() const
Return the name map, at least for python.
Definition: netinfo.h:365
FP_TEXT & Reference()
Definition: footprint.h:500
virtual void SetVisible(bool aVisible)
Definition: eda_text.h:206
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
like PAD_PTH, but not plated
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
std::map< std::pair< std::string, std::string >, NETNAME > pin_nets
void Move(const VECTOR2I &aVector) override
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
void SetLocalCoord()
< Set relative coordinates.
Definition: pad.cpp:596
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
void SetDrillSize(const wxSize &aSize)
Definition: pad.h:242
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: footprint.cpp:1491
static LSET PTHMask()
layer set for a through hole pad
Definition: pad.cpp:159
#define _(s)
void SetValue(const wxString &aValue)
Definition: footprint.h:493
int NewOutline()
Creates a new hole in a given outline.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
void SetDrillShape(PAD_DRILL_SHAPE_T aShape)
Definition: pad.h:353
std::map< std::string, std::set< std::unique_ptr< PIN >, PIN::BY_NUM > > pins
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void SetTextWidth(int aWidth)
Definition: eda_text.h:261
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:196
std::unordered_map< std::string, FM_PAD > pads
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:49
std::unordered_map< std::string, FABMASTER_PAD_SHAPE > pad_shapes
void SetLayerSet(LSET aLayers) override
Definition: pad.h:367
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
wxFileName m_filename
wxPoint GetPosition() const override
Definition: pad.h:178
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:222
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
Definition: pad.h:128
Definition: layer_ids.h:71
void AddPrimitivePoly(const SHAPE_POLY_SET &aPoly, int aThickness, bool aFilled)
Has meaning only for custom shape pads.
void SetY(int y)
Definition: pad.h:223
void SetTextHeight(int aHeight)
Definition: eda_text.h:264
void SetLocalCoord()
Definition: fp_text.cpp:209
wxPoint GetPosition() const override
Definition: footprint.h:187
void MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Merge all basic shapes to a SHAPE_POLY_SET.
void SetShape(PAD_SHAPE aShape)
Set the new shape of this pad.
Definition: pad.h:161
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:180
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: pad.cpp:180
POLYGON & Polygon(int aIndex)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
Definition: pad.h:57
void SetPosition(const wxPoint &aPos) override
Definition: footprint.cpp:1562
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: pad.cpp:166
! Not actually in Fabmaster but we use for 360° arcs
void SetOrientation(double aAngle)
Set the rotation angle of the pad.
Definition: pad.cpp:630
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > refdes
void SetX(int x)
Definition: pad.h:224
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...

References _, FOOTPRINT::Add(), BOARD::Add(), SHAPE_POLY_SET::AddHole(), PAD::AddPrimitivePoly(), APPEND, SHAPE_LINE_CHAIN::Append(), SHAPE_POLY_SET::Append(), ARC, B_Cu, B_SilkS, FABMASTER::GRAPHIC_ARC::center_x, FABMASTER::GRAPHIC_ARC::center_y, checkpoint(), CIRCLE, comp_graphics, components, CUSTOM, Dwgs_User, FABMASTER::GRAPHIC_LINE::end_x, FABMASTER::GRAPHIC_ARC::end_x, FABMASTER::GRAPHIC_RECTANGLE::end_x, FABMASTER::GRAPHIC_LINE::end_y, FABMASTER::GRAPHIC_ARC::end_y, FABMASTER::GRAPHIC_RECTANGLE::end_y, F_Cu, F_Fab, F_SilkS, FOOTPRINT::Flip(), FlipLayer(), FlipLayerMask(), Format(), SHAPE_POLY_SET::Fracture(), SHAPE_ARC::GetArcMid(), BOARD::GetDesignSettings(), getLayer(), BOARD::GetNetInfo(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), PAD::GetPosition(), FOOTPRINT::GetPosition(), GR_SHAPE_ARC, GR_SHAPE_CIRCLE, GR_SHAPE_LINE, GR_SHAPE_RECTANGLE, GR_SHAPE_TEXT, FABMASTER::GRAPHIC_TEXT::height, SHAPE_POLY_SET::Hole(), IsPcbLayer(), FABMASTER::GRAPHIC_TEXT::ital, m_filename, PAD::MergePrimitivesAsPolygon(), SHAPE_POLY_SET::Mirror(), SHAPE_POLY_SET::Move(), NETINFO_LIST::NetsByName(), SHAPE_POLY_SET::NewOutline(), NPTH, FABMASTER::GRAPHIC_TEXT::orient, SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), PAD, pad, PAD_DRILL_SHAPE_CIRCLE, PAD_DRILL_SHAPE_OBLONG, pad_shapes, pads, LIB_ID::Parse(), pin, pin_nets, pins, SHAPE_LINE_CHAIN::PointCount(), SHAPE_POLY_SET::Polygon(), PTH, PAD::PTHMask(), RECT, refdes, FOOTPRINT::Reference(), ReplaceIllegalFileNameChars(), FABMASTER::GRAPHIC_ARC::result, SHAPE_POLY_SET::Rotate(), SEGMENT, PAD::SetAttribute(), PAD::SetDrillShape(), PAD::SetDrillSize(), FOOTPRINT::SetFPID(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetItalic(), BOARD_ITEM::SetLayer(), PAD::SetLayerSet(), FP_TEXT::SetLocalCoord(), PAD::SetLocalCoord(), BOARD_CONNECTED_ITEM::SetNet(), BOARD_CONNECTED_ITEM::SetNetCode(), PAD::SetNumber(), PAD::SetOrientation(), FOOTPRINT::SetOrientationDegrees(), FOOTPRINT::SetPosition(), FOOTPRINT::SetReference(), PAD::SetShape(), PAD::SetSize(), EDA_TEXT::SetText(), EDA_TEXT::SetTextHeight(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetTextWidth(), FOOTPRINT::SetValue(), EDA_TEXT::SetVisible(), PAD::SetX(), PAD::SetY(), SMD, PAD::SMDMask(), FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, FABMASTER::GRAPHIC_TEXT::text, FABMASTER::GRAPHIC_TEXT::thickness, PAD::UnplatedHoleMask(), FOOTPRINT::Value(), SHAPE_POLY_SET::VertexCount(), and FABMASTER::GRAPHIC_ITEM::width.

Referenced by LoadBoard().

◆ loadGraphics()

bool FABMASTER::loadGraphics ( BOARD aBoard)
private

Zero-width segments/arcs are polygon outlines

Definition at line 2863 of file import_fabmaster.cpp.

2864 {
2865 
2866  for( auto& geom : board_graphics )
2867  {
2868  checkpoint();
2869 
2870  PCB_LAYER_ID layer;
2871 
2872  // The pin numbers are not useful for us outside of the footprints
2873  if( geom.subclass == "PIN_NUMBER" )
2874  continue;
2875 
2876  layer = getLayer( geom.subclass );
2877 
2878  if( !IsPcbLayer( layer ) )
2879  layer = Cmts_User;
2880 
2881  if( !geom.elements->empty() )
2882  {
2884  if( ( *( geom.elements->begin() ) )->width == 0 )
2885  {
2886  SHAPE_POLY_SET poly_outline = loadShapePolySet( *( geom.elements ) );
2887 
2888  if( poly_outline.OutlineCount() < 1 || poly_outline.COutline( 0 ).PointCount() < 3 )
2889  continue;
2890 
2891  PCB_SHAPE* new_poly = new PCB_SHAPE( aBoard, SHAPE_T::POLY );
2892  new_poly->SetLayer( layer );
2893  new_poly->SetPolyShape( poly_outline );
2894  new_poly->SetWidth( 0 );
2895 
2896  if( layer == F_SilkS || layer == B_SilkS )
2897  new_poly->SetFilled( true );
2898 
2899  aBoard->Add( new_poly, ADD_MODE::APPEND );
2900  }
2901  }
2902 
2903  for( auto& seg : *geom.elements )
2904  {
2905  switch( seg->shape )
2906  {
2907 
2908  case GR_SHAPE_LINE:
2909  {
2910  const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2911 
2912  PCB_SHAPE* line = new PCB_SHAPE( aBoard, SHAPE_T::SEGMENT );
2913  line->SetLayer( layer );
2914  line->SetStart( wxPoint( src->start_x, src->start_y ) );
2915  line->SetEnd( wxPoint( src->end_x, src->end_y ) );
2916  line->SetWidth( src->width );
2917 
2918  aBoard->Add( line, ADD_MODE::APPEND );
2919  break;
2920  }
2921  case GR_SHAPE_CIRCLE:
2922  {
2923  const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2924 
2925  PCB_SHAPE* circle = new PCB_SHAPE( aBoard, SHAPE_T::CIRCLE );
2926 
2927  circle->SetLayer( layer );
2928  circle->SetCenter( wxPoint( src->center_x, src->center_y ) );
2929  circle->SetEnd( wxPoint( src->end_x, src->end_y ) );
2930  circle->SetWidth( src->width );
2931 
2932  aBoard->Add( circle, ADD_MODE::APPEND );
2933  break;
2934  }
2935  case GR_SHAPE_ARC:
2936  {
2937  const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2938 
2939  PCB_SHAPE* arc = new PCB_SHAPE( aBoard, SHAPE_T::ARC );
2940  arc->SetLayer( layer );
2941  arc->SetArcGeometry( (wxPoint) src->result.GetP0(),
2942  (wxPoint) src->result.GetArcMid(),
2943  (wxPoint) src->result.GetP1() );
2944  arc->SetWidth( src->width );
2945 
2946  aBoard->Add( arc, ADD_MODE::APPEND );
2947  break;
2948  }
2949  case GR_SHAPE_RECTANGLE:
2950  {
2951  const GRAPHIC_RECTANGLE *src =
2952  static_cast<const GRAPHIC_RECTANGLE*>( seg.get() );
2953 
2954  PCB_SHAPE* rect = new PCB_SHAPE( aBoard, SHAPE_T::RECT );
2955  rect->SetLayer( layer );
2956  rect->SetStart( wxPoint( src->start_x, src->start_y ) );
2957  rect->SetEnd( wxPoint( src->end_x, src->end_y ) );
2958  rect->SetWidth( 0 );
2959  rect->SetFilled( true );
2960  aBoard->Add( rect, ADD_MODE::APPEND );
2961  break;
2962  }
2963  case GR_SHAPE_TEXT:
2964  {
2965  const GRAPHIC_TEXT *src =
2966  static_cast<const GRAPHIC_TEXT*>( seg.get() );
2967 
2968  PCB_TEXT* txt = new PCB_TEXT( aBoard );
2969  txt->SetLayer( layer );
2970  txt->SetTextPos( wxPoint( src->start_x, src->start_y - src->height / 2 ) );
2971  txt->SetText( src->text );
2972  txt->SetItalic( src->ital );
2973  txt->SetTextThickness( src->thickness );
2974  txt->SetTextHeight( src->height );
2975  txt->SetTextWidth( src->width );
2976  txt->SetHorizJustify( src->orient );
2977  aBoard->Add( txt, ADD_MODE::APPEND );
2978  break;
2979  }
2980  default:
2981  return false;
2982  }
2983  }
2984  }
2985 
2986  return true;
2987 
2988 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void SetFilled(bool aFlag)
Definition: eda_shape.h:92
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: eda_shape.h:235
PCB_LAYER_ID getLayer(const std::string &aLayerName)
int PointCount() const
Return the number of points (vertices) in this line chain.
bool IsPcbLayer(LAYER_NUM aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:797
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
std::vector< GEOM_GRAPHIC > board_graphics
Represent a set of closed polygons.
void SetWidth(int aWidth)
Definition: eda_shape.h:97
SHAPE_POLY_SET loadShapePolySet(const graphic_element &aLine)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
! Not actually in Fabmaster but we use for 360° arcs

References BOARD::Add(), APPEND, ARC, B_SilkS, board_graphics, FABMASTER::GRAPHIC_ARC::center_x, FABMASTER::GRAPHIC_ARC::center_y, checkpoint(), CIRCLE, Cmts_User, SHAPE_POLY_SET::COutline(), FABMASTER::GRAPHIC_LINE::end_x, FABMASTER::GRAPHIC_ARC::end_x, FABMASTER::GRAPHIC_RECTANGLE::end_x, FABMASTER::GRAPHIC_LINE::end_y, FABMASTER::GRAPHIC_ARC::end_y, FABMASTER::GRAPHIC_RECTANGLE::end_y, F_SilkS, SHAPE_ARC::GetArcMid(), getLayer(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), GR_SHAPE_ARC, GR_SHAPE_CIRCLE, GR_SHAPE_LINE, GR_SHAPE_RECTANGLE, GR_SHAPE_TEXT, FABMASTER::GRAPHIC_TEXT::height, IsPcbLayer(), FABMASTER::GRAPHIC_TEXT::ital, loadShapePolySet(), FABMASTER::GRAPHIC_TEXT::orient, SHAPE_POLY_SET::OutlineCount(), SHAPE_LINE_CHAIN::PointCount(), POLY, RECT, FABMASTER::GRAPHIC_ARC::result, SEGMENT, EDA_SHAPE::SetFilled(), BOARD_ITEM::SetLayer(), EDA_SHAPE::SetPolyShape(), EDA_SHAPE::SetWidth(), FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, FABMASTER::GRAPHIC_TEXT::text, FABMASTER::GRAPHIC_TEXT::thickness, and FABMASTER::GRAPHIC_ITEM::width.

Referenced by LoadBoard().

◆ loadLayers()

bool FABMASTER::loadLayers ( BOARD aBoard)
private

The basic layers that get enabled for normal boards

Definition at line 2430 of file import_fabmaster.cpp.

2431 {
2432  LSET layer_set;
2433 
2435  layer_set |= LSET::AllTechMask() | LSET::UserMask();
2436 
2437  for( auto& layer : layers )
2438  {
2439  checkpoint();
2440 
2441  if( layer.second.layerid >= PCBNEW_LAYER_ID_START )
2442  layer_set.set( layer.second.layerid );
2443  }
2444 
2445  aBoard->SetEnabledLayers( layer_set );
2446 
2447  for( auto& layer : layers )
2448  {
2449  if( layer.second.conductive )
2450  {
2451  aBoard->SetLayerName( static_cast<PCB_LAYER_ID>( layer.second.layerid ),
2452  layer.second.name );
2453  }
2454  }
2455 
2456  return true;
2457 }
std::map< std::string, FABMASTER_LAYER > layers
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:829
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:516
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition: board.cpp:378
static LSET UserMask()
Definition: lset.cpp:843
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:487

References LSET::AllTechMask(), checkpoint(), layers, PCBNEW_LAYER_ID_START, BOARD::SetEnabledLayers(), BOARD::SetLayerName(), and LSET::UserMask().

Referenced by LoadBoard().

◆ loadNets()

bool FABMASTER::loadNets ( BOARD aBoard)
private

Definition at line 2507 of file import_fabmaster.cpp.

2508 {
2509  for( auto& net : netnames )
2510  {
2511  checkpoint();
2512 
2513  NETINFO_ITEM *newnet = new NETINFO_ITEM( aBoard, net );
2514  aBoard->Add( newnet, ADD_MODE::APPEND );
2515  }
2516 
2517  return true;
2518 }
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
std::set< std::string > netnames
Handle the data for a net.
Definition: netinfo.h:66

References BOARD::Add(), APPEND, checkpoint(), and netnames.

Referenced by LoadBoard().

◆ loadOutline()

bool FABMASTER::loadOutline ( BOARD aBoard,
const std::unique_ptr< TRACE > &  aLine 
)
private

Definition at line 2757 of file import_fabmaster.cpp.

2758 {
2759  PCB_LAYER_ID layer;
2760 
2761  if( aLine->lclass == "BOARD GEOMETRY" )
2762  layer = Edge_Cuts;
2763  else if( aLine->lclass == "DRAWING FORMAT" )
2764  layer = Dwgs_User;
2765  else
2766  layer = Cmts_User;
2767 
2768  for( auto& seg : aLine->segment )
2769  {
2770  switch( seg->shape )
2771  {
2772 
2773  case GR_SHAPE_LINE:
2774  {
2775  const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2776 
2777  PCB_SHAPE* line = new PCB_SHAPE( aBoard, SHAPE_T::SEGMENT );
2778  line->SetLayer( layer );
2779  line->SetStart( wxPoint( src->start_x, src->start_y ) );
2780  line->SetEnd( wxPoint( src->end_x, src->end_y ) );
2781  line->SetWidth( src->width );
2782 
2783  if( line->GetWidth() == 0 )
2784  line->SetWidth( aBoard->GetDesignSettings().GetLineThickness( layer ) );
2785 
2786  aBoard->Add( line, ADD_MODE::APPEND );
2787  break;
2788  }
2789  case GR_SHAPE_CIRCLE:
2790  {
2791  const GRAPHIC_ARC* lsrc = static_cast<const GRAPHIC_ARC*>( seg.get() );
2792 
2793  PCB_SHAPE* circle = new PCB_SHAPE( aBoard, SHAPE_T::CIRCLE );
2794 
2795  circle->SetLayer( layer );
2796  circle->SetCenter( wxPoint( lsrc->center_x, lsrc->center_y ) );
2797  circle->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
2798  circle->SetWidth( lsrc->width );
2799 
2800  if( lsrc->width == 0 )
2801  circle->SetWidth( aBoard->GetDesignSettings().GetLineThickness( circle->GetLayer() ) );
2802 
2803  aBoard->Add( circle, ADD_MODE::APPEND );
2804  break;
2805  }
2806  case GR_SHAPE_ARC:
2807  {
2808  const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2809 
2810  PCB_SHAPE* arc = new PCB_SHAPE( aBoard, SHAPE_T::ARC );
2811  arc->SetLayer( layer );
2812  arc->SetArcGeometry( (wxPoint) src->result.GetP0(),
2813  (wxPoint) src->result.GetArcMid(),
2814  (wxPoint) src->result.GetP1() );
2815  arc->SetWidth( src->width );
2816 
2817  if( arc->GetWidth() == 0 )
2818  arc->SetWidth( aBoard->GetDesignSettings().GetLineThickness( layer ) );
2819 
2820  aBoard->Add( arc, ADD_MODE::APPEND );
2821  break;
2822  }
2823  case GR_SHAPE_RECTANGLE:
2824  {
2825  const GRAPHIC_RECTANGLE *src =
2826  static_cast<const GRAPHIC_RECTANGLE*>( seg.get() );
2827 
2828  PCB_SHAPE* rect = new PCB_SHAPE( aBoard, SHAPE_T::RECT );
2829  rect->SetLayer( layer );
2830  rect->SetStart( wxPoint( src->start_x, src->start_y ) );
2831  rect->SetEnd( wxPoint( src->end_x, src->end_y ) );
2832  rect->SetWidth( aBoard->GetDesignSettings().GetLineThickness( layer ) );
2833 
2834  aBoard->Add( rect, ADD_MODE::APPEND );
2835  break;
2836  }
2837  case GR_SHAPE_TEXT:
2838  {
2839  const GRAPHIC_TEXT *src = static_cast<const GRAPHIC_TEXT*>( seg.get() );
2840 
2841  PCB_TEXT* txt = new PCB_TEXT( aBoard );
2842  txt->SetLayer( layer );
2843  txt->SetTextPos( wxPoint( src->start_x, src->start_y - src->height / 2 ) );
2844  txt->SetText( src->text );
2845  txt->SetItalic( src->ital );
2846  txt->SetTextThickness( src->thickness );
2847  txt->SetTextHeight( src->height );
2848  txt->SetTextWidth( src->width );
2849  txt->SetHorizJustify( src->orient );
2850 
2851  aBoard->Add( txt, ADD_MODE::APPEND );
2852  break;
2853  }
2854  default:
2855  return false;
2856  }
2857  }
2858 
2859  return true;
2860 }
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
! Not actually in Fabmaster but we use for 360° arcs

References BOARD::Add(), APPEND, ARC, FABMASTER::GRAPHIC_ARC::center_x, FABMASTER::GRAPHIC_ARC::center_y, CIRCLE, Cmts_User, Dwgs_User, Edge_Cuts, FABMASTER::GRAPHIC_LINE::end_x, FABMASTER::GRAPHIC_ARC::end_x, FABMASTER::GRAPHIC_RECTANGLE::end_x, FABMASTER::GRAPHIC_LINE::end_y, FABMASTER::GRAPHIC_ARC::end_y, FABMASTER::GRAPHIC_RECTANGLE::end_y, SHAPE_ARC::GetArcMid(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetLineThickness(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), GR_SHAPE_ARC, GR_SHAPE_CIRCLE, GR_SHAPE_LINE, GR_SHAPE_RECTANGLE, GR_SHAPE_TEXT, FABMASTER::GRAPHIC_TEXT::height, FABMASTER::GRAPHIC_TEXT::ital, FABMASTER::GRAPHIC_TEXT::orient, RECT, FABMASTER::GRAPHIC_ARC::result, SEGMENT, FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, FABMASTER::GRAPHIC_TEXT::text, FABMASTER::GRAPHIC_TEXT::thickness, and FABMASTER::GRAPHIC_ITEM::width.

Referenced by LoadBoard(), and loadZones().

◆ loadPolygon()

bool FABMASTER::loadPolygon ( BOARD aBoard,
const std::unique_ptr< FABMASTER::TRACE > &  aLine 
)
private

Definition at line 2612 of file import_fabmaster.cpp.

2613 {
2614  if( aLine->segment.size() < 3 )
2615  return false;
2616 
2617  PCB_LAYER_ID layer = Cmts_User;
2618 
2619  auto new_layer = getLayer( aLine->layer );
2620 
2621  if( IsPcbLayer( new_layer ) )
2622  layer = new_layer;
2623 
2624  SHAPE_POLY_SET poly_outline = loadShapePolySet( aLine->segment );
2625 
2626  if( poly_outline.OutlineCount() < 1 || poly_outline.COutline( 0 ).PointCount() < 3 )
2627  return false;
2628 
2629  PCB_SHAPE* new_poly = new PCB_SHAPE( aBoard );
2630 
2631  new_poly->SetShape( SHAPE_T::POLY );
2632  new_poly->SetLayer( layer );
2633 
2634  // Polygons on the silk layer are filled but other layers are not/fill doesn't make sense
2635  if( layer == F_SilkS || layer == B_SilkS )
2636  {
2637  new_poly->SetFilled( true );
2638  new_poly->SetWidth( 0 );
2639  }
2640  else
2641  {
2642  new_poly->SetWidth( ( *( aLine->segment.begin() ) )->width );
2643 
2644  if( new_poly->GetWidth() == 0 )
2645  new_poly->SetWidth( aBoard->GetDesignSettings().GetLineThickness( layer ) );
2646  }
2647 
2648  new_poly->SetPolyShape( poly_outline );
2649  aBoard->Add( new_poly, ADD_MODE::APPEND );
2650 
2651  return true;
2652 
2653 }
int GetWidth() const
Definition: eda_shape.h:98
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void SetFilled(bool aFlag)
Definition: eda_shape.h:92
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: eda_shape.h:235
PCB_LAYER_ID getLayer(const std::string &aLayerName)
int PointCount() const
Return the number of points (vertices) in this line chain.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
bool IsPcbLayer(LAYER_NUM aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:797
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
Represent a set of closed polygons.
void SetWidth(int aWidth)
Definition: eda_shape.h:97
SHAPE_POLY_SET loadShapePolySet(const graphic_element &aLine)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:100

References BOARD::Add(), APPEND, B_SilkS, Cmts_User, SHAPE_POLY_SET::COutline(), F_SilkS, BOARD::GetDesignSettings(), getLayer(), BOARD_DESIGN_SETTINGS::GetLineThickness(), EDA_SHAPE::GetWidth(), IsPcbLayer(), loadShapePolySet(), SHAPE_POLY_SET::OutlineCount(), SHAPE_LINE_CHAIN::PointCount(), POLY, EDA_SHAPE::SetFilled(), BOARD_ITEM::SetLayer(), EDA_SHAPE::SetPolyShape(), EDA_SHAPE::SetShape(), and EDA_SHAPE::SetWidth().

Referenced by loadZones().

◆ loadShapePolySet()

SHAPE_POLY_SET FABMASTER::loadShapePolySet ( const graphic_element aLine)
private

Definition at line 2576 of file import_fabmaster.cpp.

2577 {
2578  SHAPE_POLY_SET poly_outline;
2579  int last_subseq = 0;
2580  int hole_idx = -1;
2581 
2582  poly_outline.NewOutline();
2583 
2584  for( const auto& seg : aElement )
2585  {
2586  if( seg->subseq > 0 || seg->subseq != last_subseq )
2587  hole_idx = poly_outline.AddHole( SHAPE_LINE_CHAIN{} );
2588 
2589  if( seg->shape == GR_SHAPE_LINE )
2590  {
2591  const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2592 
2593  if( poly_outline.VertexCount( 0, hole_idx ) == 0 )
2594  poly_outline.Append( src->start_x, src->start_y, 0, hole_idx );
2595 
2596  poly_outline.Append( src->end_x, src->end_y, 0, hole_idx );
2597  }
2598  else if( seg->shape == GR_SHAPE_ARC )
2599  {
2600  const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2601  SHAPE_LINE_CHAIN& chain = poly_outline.Hole( 0, hole_idx );
2602 
2603  chain.Append( src->result );
2604  }
2605  }
2606 
2607  poly_outline.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
2608  return poly_outline;
2609 }
int VertexCount(int aOutline=-1, int aHole=-1) const
Return the number of points in the shape poly set.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
int NewOutline()
Creates a new hole in a given outline.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...

References SHAPE_POLY_SET::AddHole(), SHAPE_LINE_CHAIN::Append(), SHAPE_POLY_SET::Append(), FABMASTER::GRAPHIC_LINE::end_x, FABMASTER::GRAPHIC_LINE::end_y, SHAPE_POLY_SET::Fracture(), GR_SHAPE_ARC, GR_SHAPE_LINE, SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::NewOutline(), FABMASTER::GRAPHIC_ARC::result, FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, and SHAPE_POLY_SET::VertexCount().

Referenced by loadGraphics(), and loadPolygon().

◆ loadVias()

bool FABMASTER::loadVias ( BOARD aBoard)
private

Definition at line 2460 of file import_fabmaster.cpp.

2461 {
2462  const NETNAMES_MAP& netinfo = aBoard->GetNetInfo().NetsByName();
2463  const auto& ds = aBoard->GetDesignSettings();
2464 
2465  for( auto& via : vias )
2466  {
2467  checkpoint();
2468 
2469  auto net_it = netinfo.find( via->net );
2470  auto padstack = pads.find( via->padstack );
2471 
2472  PCB_VIA* new_via = new PCB_VIA( aBoard );
2473 
2474  new_via->SetPosition( wxPoint( via->x, via->y ) );
2475 
2476  if( net_it != netinfo.end() )
2477  new_via->SetNet( net_it->second );
2478 
2479  if( padstack == pads.end() )
2480  {
2481  new_via->SetDrillDefault();
2482 
2483  if( !ds.m_ViasDimensionsList.empty() )
2484  {
2485  new_via->SetWidth( ds.m_ViasDimensionsList[0].m_Diameter );
2486  new_via->SetDrill( ds.m_ViasDimensionsList[0].m_Drill );
2487  }
2488  else
2489  {
2490  new_via->SetDrillDefault();
2491  new_via->SetWidth( ds.m_ViasMinSize );
2492  }
2493  }
2494  else
2495  {
2496  new_via->SetDrill( padstack->second.drill_size_x );
2497  new_via->SetWidth( padstack->second.width );
2498  }
2499 
2500  aBoard->Add( new_via, ADD_MODE::APPEND );
2501  }
2502 
2503  return true;
2504 }
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: pcb_track.h:455
void SetPosition(const wxPoint &aPoint) override
Definition: pcb_track.h:393
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:680
std::vector< std::unique_ptr< FM_VIA > > vias
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
const NETNAMES_MAP & NetsByName() const
Return the name map, at least for python.
Definition: netinfo.h:365
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
void SetDrillDefault()
Function SetDrillDefault sets the drill value for vias to the default value UNDEFINED_DRILL_DIAMETER.
Definition: pcb_track.h:476
std::unordered_map< std::string, FM_PAD > pads
void SetWidth(int aWidth)
Definition: pcb_track.h:101
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.

References BOARD::Add(), APPEND, checkpoint(), BOARD::GetDesignSettings(), BOARD::GetNetInfo(), NETINFO_LIST::NetsByName(), pads, PCB_VIA::SetDrill(), PCB_VIA::SetDrillDefault(), BOARD_CONNECTED_ITEM::SetNet(), PCB_VIA::SetPosition(), PCB_TRACK::SetWidth(), via, and vias.

Referenced by LoadBoard().

◆ loadZone()

bool FABMASTER::loadZone ( BOARD aBoard,
const std::unique_ptr< FABMASTER::TRACE > &  aLine 
)
private

Don't knock holes in the BOUNDARY systems. These are the outer layers for zone fills.

Definition at line 2656 of file import_fabmaster.cpp.

2657 {
2658  if( aLine->segment.size() < 3 )
2659  return false;
2660 
2661  int last_subseq = 0;
2662  int hole_idx = -1;
2663  SHAPE_POLY_SET* zone_outline = nullptr;
2664  ZONE* zone = nullptr;
2665 
2666  const NETNAMES_MAP& netinfo = aBoard->GetNetInfo().NetsByName();
2667  auto net_it = netinfo.find( aLine->netname );
2668  PCB_LAYER_ID layer = Cmts_User;
2669  auto new_layer = getLayer( aLine->layer );
2670 
2671  if( IsPcbLayer( new_layer ) )
2672  layer = new_layer;
2673 
2674  zone = new ZONE( aBoard );
2675  zone_outline = new SHAPE_POLY_SET;
2676 
2677  if( net_it != netinfo.end() )
2678  zone->SetNet( net_it->second );
2679 
2680  if( aLine->layer == "ALL" )
2681  zone->SetLayerSet( aBoard->GetLayerSet() & LSET::AllCuMask() );
2682  else
2683  zone->SetLayer( layer );
2684 
2685  zone->SetIsRuleArea( false );
2686  zone->SetDoNotAllowTracks( false );
2687  zone->SetDoNotAllowVias( false );
2688  zone->SetDoNotAllowPads( false );
2689  zone->SetDoNotAllowFootprints( false );
2690  zone->SetDoNotAllowCopperPour( false );
2691 
2692  if( aLine->lclass == "ROUTE KEEPOUT")
2693  {
2694  zone->SetIsRuleArea( true );
2695  zone->SetDoNotAllowTracks( true );
2696  }
2697  else if( aLine->lclass == "VIA KEEPOUT")
2698  {
2699  zone->SetIsRuleArea( true );
2700  zone->SetDoNotAllowVias( true );
2701  }
2702  else
2703  {
2704  zone->SetPriority( 50 );
2705  }
2706 
2707  zone->SetLocalClearance( 0 );
2709 
2710  zone_outline->NewOutline();
2711 
2712 
2713  for( const auto& seg : aLine->segment )
2714  {
2715  if( seg->subseq > 0 && seg->subseq != last_subseq )
2716  {
2718  if( aLine->lclass == "BOUNDARY" )
2719  break;
2720 
2721  hole_idx = zone_outline->AddHole( SHAPE_LINE_CHAIN{} );
2722  last_subseq = seg->subseq;
2723  last_subseq = seg->subseq;
2724  }
2725 
2726  if( seg->shape == GR_SHAPE_LINE )
2727  {
2728  const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2729 
2730  if( zone_outline->VertexCount( 0, hole_idx ) == 0 )
2731  zone_outline->Append( src->start_x, src->start_y, 0, hole_idx );
2732 
2733  zone_outline->Append( src->end_x, src->end_y, 0, hole_idx );
2734  }
2735  else if( seg->shape == GR_SHAPE_ARC )
2736  {
2737  const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2738  zone_outline->Hole( 0, hole_idx ).Append( src->result );
2739  }
2740  }
2741 
2742  if( zone_outline->Outline( 0 ).PointCount() >= 3 )
2743  {
2744  zone->SetOutline( zone_outline );
2745  aBoard->Add( zone, ADD_MODE::APPEND );
2746  }
2747  else
2748  {
2749  delete( zone_outline );
2750  delete( zone );
2751  }
2752 
2753  return true;
2754 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:759
void SetDoNotAllowTracks(bool aEnable)
Definition: zone.h:747
void SetLayerSet(LSET aLayerSet) override
Definition: zone.cpp:250
int VertexCount(int aOutline=-1, int aHole=-1) const
Return the number of points in the shape poly set.
PCB_LAYER_ID getLayer(const std::string &aLayerName)
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:680
int PointCount() const
Return the number of points (vertices) in this line chain.
void SetPriority(unsigned aPriority)
Definition: zone.h:117
bool IsPcbLayer(LAYER_NUM aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:797
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const NETNAMES_MAP & NetsByName() const
Return the name map, at least for python.
Definition: netinfo.h:365
void SetIsRuleArea(bool aEnable)
Definition: zone.h:744
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:608
pads are covered by copper
void SetDoNotAllowPads(bool aEnable)
Definition: zone.h:748
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
void SetOutline(SHAPE_POLY_SET *aOutline)
Definition: zone.h:323
void SetDoNotAllowVias(bool aEnable)
Definition: zone.h:746
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
int NewOutline()
Creates a new hole in a given outline.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition: zone.h:242
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
void SetDoNotAllowCopperPour(bool aEnable)
Definition: zone.h:745
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:242
void SetLocalClearance(int aClearance)
Definition: zone.h:158
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:148
void SetDoNotAllowFootprints(bool aEnable)
Definition: zone.h:749
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...

References BOARD::Add(), SHAPE_POLY_SET::AddHole(), LSET::AllCuMask(), APPEND, SHAPE_LINE_CHAIN::Append(), SHAPE_POLY_SET::Append(), Cmts_User, FABMASTER::GRAPHIC_LINE::end_x, FABMASTER::GRAPHIC_LINE::end_y, FULL, getLayer(), BOARD_ITEM::GetLayerSet(), BOARD::GetNetInfo(), GR_SHAPE_ARC, GR_SHAPE_LINE, SHAPE_POLY_SET::Hole(), IsPcbLayer(), NETINFO_LIST::NetsByName(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::Outline(), SHAPE_LINE_CHAIN::PointCount(), FABMASTER::GRAPHIC_ARC::result, ZONE::SetDoNotAllowCopperPour(), ZONE::SetDoNotAllowFootprints(), ZONE::SetDoNotAllowPads(), ZONE::SetDoNotAllowTracks(), ZONE::SetDoNotAllowVias(), ZONE::SetIsRuleArea(), ZONE::SetLayer(), ZONE::SetLayerSet(), ZONE::SetLocalClearance(), BOARD_CONNECTED_ITEM::SetNet(), ZONE::SetOutline(), ZONE::SetPadConnection(), ZONE::SetPriority(), FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, and SHAPE_POLY_SET::VertexCount().

Referenced by loadZones().

◆ loadZones()

bool FABMASTER::loadZones ( BOARD aBoard)
private

Loads sections of the database into the board.

Parameters
aBoard
Returns
True if successful

Zones in FABMASTER come in two varieties:

  • Outlines with no net code attached
  • Filled areas with net code attached

In pcbnew, we want the outline with net code attached. To determine which outline should have which netcode, we look for overlapping areas. Each unnetted zone outline will be assigned the netcode that with the most hits on the edge of their outline.

Remove the filled areas in favor of the outlines

Zone1 will be the destination zone for the new net

We're looking for the netcode with the most overlaps to the un-netted zone

The overlap between outline1 and outline2 isn't perfect, so look for overlaps in both directions

Definition at line 1861 of file import_fabmaster.cpp.

1862 {
1863  for( auto& zone : zones )
1864  {
1865  checkpoint();
1866 
1867  if( IsCopperLayer( getLayer( zone->layer ) ) || zone->layer == "ALL" )
1868  {
1869  loadZone( aBoard, zone );
1870  }
1871  else
1872  {
1873  if( zone->layer == "OUTLINE" || zone->layer == "DESIGN_OUTLINE" )
1874  {
1875  loadOutline( aBoard, zone );
1876  }
1877  else
1878  {
1879  loadPolygon( aBoard, zone );
1880  }
1881  }
1882  }
1883 
1894  std::set<ZONE*> zones_to_delete;
1895 
1896  for( auto zone : aBoard->Zones() )
1897  {
1899  if( zone->GetNetCode() > 0 )
1900  {
1901  zones_to_delete.insert( zone );
1902  }
1903  }
1904 
1905  for( auto zone1 : aBoard->Zones() )
1906  {
1908  if( zone1->GetNetCode() > 0 )
1909  continue;
1910 
1911  SHAPE_LINE_CHAIN& outline1 = zone1->Outline()->Outline( 0 );
1912  std::vector<size_t> overlaps( aBoard->GetNetInfo().GetNetCount() + 1, 0 );
1913  std::vector<std::vector<ZONE*>> possible_deletions( overlaps.size() );
1914 
1915  for( auto zone2 : aBoard->Zones() )
1916  {
1917  if( zone2->GetNetCode() <= 0 )
1918  continue;
1919 
1920  SHAPE_LINE_CHAIN& outline2 = zone2->Outline()->Outline( 0 );
1921 
1922  if( zone1->GetLayer() != zone2->GetLayer() )
1923  continue;
1924 
1925  if( !outline1.BBox().Intersects( outline2.BBox() ) )
1926  continue;
1927 
1928  for( auto& pt1 : outline1.CPoints() )
1929  {
1931  if( outline2.PointOnEdge( pt1, 1 ) )
1932  overlaps[ zone2->GetNetCode() ]++;
1933  }
1934 
1935  for( auto& pt2 : outline2.CPoints() )
1936  {
1939  if( outline1.PointOnEdge( pt2, 1 ) )
1940  overlaps[ zone2->GetNetCode() ]++;
1941  }
1942  }
1943 
1944  size_t max_net = 0;
1945  size_t max_net_id = 0;
1946 
1947  for( size_t el = 1; el < overlaps.size(); ++el )
1948  {
1949  if( overlaps[el] > max_net )
1950  {
1951  max_net = overlaps[el];
1952  max_net_id = el;
1953  }
1954  }
1955 
1956  if( max_net > 0 )
1957  zone1->SetNetCode( max_net_id );
1958  }
1959 
1960  for( auto zone : zones_to_delete )
1961  {
1962  aBoard->Remove( zone );
1963  delete zone;
1964  }
1965 
1966  return true;
1967 }
ZONES & Zones()
Definition: board.h:240
PCB_LAYER_ID getLayer(const std::string &aLayerName)
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:680
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
bool loadZone(BOARD *aBoard, const std::unique_ptr< FABMASTER::TRACE > &aLine)
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:217
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
const std::vector< VECTOR2I > & CPoints() const
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > zones
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:808
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: board.cpp:710
unsigned GetNetCount() const
Definition: netinfo.h:346
bool loadPolygon(BOARD *aBoard, const std::unique_ptr< FABMASTER::TRACE > &aLine)
bool loadOutline(BOARD *aBoard, const std::unique_ptr< TRACE > &aLine)

References SHAPE_LINE_CHAIN::BBox(), checkpoint(), SHAPE_LINE_CHAIN::CPoints(), getLayer(), NETINFO_LIST::GetNetCount(), BOARD::GetNetInfo(), BOX2< Vec >::Intersects(), IsCopperLayer(), loadOutline(), loadPolygon(), loadZone(), SHAPE_LINE_CHAIN_BASE::PointOnEdge(), BOARD::Remove(), BOARD::Zones(), and zones.

Referenced by LoadBoard().

◆ orderZones()

bool FABMASTER::orderZones ( BOARD aBoard)
private

Sets zone priorities based on zone BB size.

Larger bounding boxes get smaller priorities so smaller zones can knock out areas where they overlap.

Parameters
aBoard
Returns
True if successful

Rule areas do not have priorities

Definition at line 2991 of file import_fabmaster.cpp.

2992 {
2993  std::vector<ZONE*> zones = aBoard->Zones();
2994 
2995  std::sort( zones.begin(), zones.end(),
2996  [&]( const ZONE* a, const ZONE* b )
2997  {
2998  if( a->GetLayer() == b->GetLayer() )
2999  return a->GetBoundingBox().GetArea() > b->GetBoundingBox().GetArea();
3000 
3001  return a->GetLayer() < b->GetLayer();
3002  } );
3003 
3004  PCB_LAYER_ID layer = UNDEFINED_LAYER;
3005  unsigned int priority = 0;
3006 
3007  for( ZONE* zone : zones )
3008  {
3010  if( zone->GetIsRuleArea() )
3011  continue;
3012 
3013  if( zone->GetLayer() != layer )
3014  {
3015  layer = zone->GetLayer();
3016  priority = 0;
3017  }
3018 
3019  zone->SetPriority( priority );
3020  priority += 10;
3021  }
3022 
3023  return true;
3024 }
ZONES & Zones()
Definition: board.h:240
const EDA_RECT GetBoundingBox() const override
Definition: zone.cpp:320
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: zone.cpp:222
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > zones
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
double GetArea() const
Return the area of the rectangle.
Definition: eda_rect.cpp:483
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65

References EDA_RECT::GetArea(), ZONE::GetBoundingBox(), ZONE::GetLayer(), UNDEFINED_LAYER, BOARD::Zones(), and zones.

Referenced by LoadBoard().

◆ parseCompClass()

FABMASTER::COMPCLASS FABMASTER::parseCompClass ( const std::string &  aCompClass)
private

Definition at line 1531 of file import_fabmaster.cpp.

1532 {
1533  if( aCmpClass == "IO" )
1534  return COMPCLASS_IO;
1535  else if( aCmpClass == "IC" )
1536  return COMPCLASS_IC;
1537  else if( aCmpClass == "DISCRETE" )
1538  return COMPCLASS_DISCRETE;
1539 
1540  return COMPCLASS_NONE;
1541 }

References COMPCLASS_DISCRETE, COMPCLASS_IC, COMPCLASS_IO, and COMPCLASS_NONE.

Referenced by processFootprints().

◆ parseSymType()

FABMASTER::SYMTYPE FABMASTER::parseSymType ( const std::string &  aSymType)
private

Definition at line 1516 of file import_fabmaster.cpp.

1517 {
1518  if( aSymType == "PACKAGE" )
1519  return SYMTYPE_PACKAGE;
1520  else if( aSymType == "DRAFTING")
1521  return SYMTYPE_DRAFTING;
1522  else if( aSymType == "MECHANICAL" )
1523  return SYMTYPE_MECH;
1524  else if( aSymType == "FORMAT" )
1525  return SYMTYPE_FORMAT;
1526 
1527  return SYMTYPE_NONE;
1528 }

References SYMTYPE_DRAFTING, SYMTYPE_FORMAT, SYMTYPE_MECH, SYMTYPE_NONE, and SYMTYPE_PACKAGE.

Referenced by processFootprints().

◆ Process()

bool FABMASTER::Process ( )

We extract the basic layers from the padstacks first as this is the only place the stackup is kept in the basic fabmaster export

Definition at line 1757 of file import_fabmaster.cpp.

1758 {
1759 
1760  for( size_t i = 0; i < rows.size(); )
1761  {
1762  auto type = detectType( i );
1763 
1764  switch( type )
1765  {
1766  case EXTRACT_PADSTACKS:
1767  {
1770  processPadStackLayers( i );
1771  assignLayers();
1772  int retval = processPadStacks( i );
1773 
1774  i += std::max( retval, 1 );
1775  break;
1776  }
1777 
1778  case EXTRACT_FULL_LAYERS:
1779  {
1780  int retval = processLayers( i );
1781 
1782  i += std::max( retval, 1 );
1783  break;
1784  }
1785 
1786  case EXTRACT_BASIC_LAYERS:
1787  {
1788  int retval = processSimpleLayers( i );
1789 
1790  i += std::max( retval, 1 );
1791  break;
1792  }
1793 
1794  case EXTRACT_VIAS:
1795  {
1796  int retval = processVias( i );
1797 
1798  i += std::max( retval, 1 );
1799  break;
1800  }
1801 
1802  case EXTRACT_TRACES:
1803  {
1804  int retval = processTraces( i );
1805 
1806  i += std::max( retval, 1 );
1807  break;
1808  }
1809 
1810  case EXTRACT_REFDES:
1811  {
1812  int retval = processFootprints( i );
1813 
1814  i += std::max( retval, 1 );
1815  break;
1816  }
1817 
1818  case EXTRACT_NETS:
1819  {
1820  int retval = processNets( i );
1821 
1822  i += std::max( retval, 1 );
1823  break;
1824  }
1825 
1826  case EXTRACT_GRAPHICS:
1827  {
1828  int retval = processGeometry( i );
1829 
1830  i += std::max( retval, 1 );
1831  break;
1832  }
1833 
1834  case EXTRACT_PINS:
1835  {
1836  int retval = processPins( i );
1837 
1838  i += std::max( retval, 1 );
1839  break;
1840  }
1841 
1842  case EXTRACT_PAD_SHAPES:
1843  {
1844  int retval = processCustomPads( i );
1845 
1846  i += std::max( retval, 1 );
1847  break;
1848  }
1849 
1850  default:
1851  ++i;
1852  break;
1853  }
1854 
1855  }
1856 
1857  return true;
1858 }
size_t processSimpleLayers(size_t aRow)
size_t processFootprints(size_t aRow)
A!REFDES!COMP_CLASS!COMP_PART_NUMBER!COMP_HEIGHT!COMP_DEVICE_LABEL!COMP_INSERTION_CODE!...
section_type detectType(size_t aOffset)
size_t processGeometry(size_t aRow)
A!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2!GRAPHIC_DATA_3!...
size_t processVias(size_t aRow)
A!VIA_X!VIA_Y!PAD_STACK_NAME!NET_NAME!TEST_POINT!
size_t processPadStacks(size_t aRow)
A!PADNAME!RECNUMBER!LAYER!FIXFLAG!VIAFLAG!PADSHAPE1!PADWIDTH!PADHGHT! PADXOFF!PADYOFF!...
size_t processPins(size_t aRow)
A!SYM_NAME!SYM_MIRROR!PIN_NAME!PIN_NUMBER!PIN_X!PIN_Y!PAD_STACK_NAME!REFDES!PIN_ROTATION!...
size_t processCustomPads(size_t aRow)
A!SUBCLASS!PAD_SHAPE_NAME!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!...
size_t processNets(size_t aRow)
A!NET_NAME!REFDES!PIN_NUMBER!PIN_NAME!PIN_GROUND!PIN_POWER!
size_t processLayers(size_t aRow)
A!LAYER_SORT!LAYER_SUBCLASS!LAYER_ARTWORK!LAYER_USE!LAYER_CONDUCTOR!LAYER_DIELECTRIC_CONSTANT!...
size_t processTraces(size_t aRow)
A!CLASS!SUBCLASS!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2!...
size_t processPadStackLayers(size_t aRow)
std::deque< single_row > rows

References assignLayers(), detectType(), EXTRACT_BASIC_LAYERS, EXTRACT_FULL_LAYERS, EXTRACT_GRAPHICS, EXTRACT_NETS, EXTRACT_PAD_SHAPES, EXTRACT_PADSTACKS, EXTRACT_PINS, EXTRACT_REFDES, EXTRACT_TRACES, EXTRACT_VIAS, processCustomPads(), processFootprints(), processGeometry(), processLayers(), processNets(), processPadStackLayers(), processPadStacks(), processPins(), processSimpleLayers(), processTraces(), processVias(), and rows.

Referenced by FABMASTER_PLUGIN::Load().

◆ processArc()

FABMASTER::GRAPHIC_ARC * FABMASTER::processArc ( const GRAPHIC_DATA aData,
double  aScale 
)
private

Definition at line 1038 of file import_fabmaster.cpp.

1039 {
1040  GRAPHIC_ARC* new_arc = new GRAPHIC_ARC ;
1041 
1042  new_arc->shape = GR_SHAPE_ARC;
1043  new_arc->start_x = KiROUND( readDouble( aData.graphic_data1 ) * aScale );
1044  new_arc->start_y = -KiROUND( readDouble( aData.graphic_data2 ) * aScale );
1045  new_arc->end_x = KiROUND( readDouble( aData.graphic_data3 ) * aScale );
1046  new_arc->end_y = -KiROUND( readDouble( aData.graphic_data4 ) * aScale );
1047  new_arc->center_x = KiROUND( readDouble( aData.graphic_data5 ) * aScale );
1048  new_arc->center_y = -KiROUND( readDouble( aData.graphic_data6 ) * aScale );
1049  new_arc->radius = KiROUND( readDouble( aData.graphic_data7 ) * aScale );
1050  new_arc->width = KiROUND( readDouble( aData.graphic_data8 ) * aScale );
1051 
1052  new_arc->clockwise = ( aData.graphic_data9 != "COUNTERCLOCKWISE" );
1053 
1054  double startangle = NormalizeAnglePos( RAD2DECIDEG(
1055  atan2( new_arc->start_y - new_arc->center_y,
1056  new_arc->start_x - new_arc->center_x ) ) );
1057  double endangle = NormalizeAnglePos( RAD2DECIDEG(
1058  atan2( new_arc->end_y - new_arc->center_y,
1059  new_arc->end_x - new_arc->center_x ) ) );
1060  double angle;
1061 
1062  VECTOR2I center( new_arc->center_x, new_arc->center_y );
1063  VECTOR2I start( new_arc->start_x, new_arc->start_y );
1064  VECTOR2I mid( new_arc->start_x, new_arc->start_y );
1065  VECTOR2I end( new_arc->end_x, new_arc->end_y );
1066 
1067  angle = endangle - startangle;
1068 
1069  if( new_arc->clockwise && angle < 0.0 )
1070  angle += 3600.0;
1071  if( !new_arc->clockwise && angle > 0.0 )
1072  angle -= 3600.0;
1073 
1074  if( start == end )
1075  angle = -3600.0;
1076 
1077  RotatePoint( mid, center, -angle / 2.0 );
1078 
1079  if( start == end )
1080  new_arc->shape = GR_SHAPE_CIRCLE;
1081 
1082  new_arc->result = SHAPE_ARC( start, mid, end, 0 );
1083 
1084  return new_arc;
1085 }
double readDouble(const std::string &aStr) const
Reads the double/integer value from a std string independent of the user locale.
double RAD2DECIDEG(double rad)
Definition: trigo.h:234
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
T NormalizeAnglePos(T Angle)
Normalize angle to be in the 0.0 .. 360.0 range: angle is in 1/10 degrees.
Definition: trigo.h:281
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
! Not actually in Fabmaster but we use for 360° arcs

References PNS::angle(), FABMASTER::GRAPHIC_ARC::center_x, FABMASTER::GRAPHIC_ARC::center_y, FABMASTER::GRAPHIC_ARC::clockwise, FABMASTER::GRAPHIC_ARC::end_x, FABMASTER::GRAPHIC_ARC::end_y, GR_SHAPE_ARC, GR_SHAPE_CIRCLE, FABMASTER::GRAPHIC_DATA::graphic_data1, FABMASTER::GRAPHIC_DATA::graphic_data2, FABMASTER::GRAPHIC_DATA::graphic_data3, FABMASTER::GRAPHIC_DATA::graphic_data4, FABMASTER::GRAPHIC_DATA::graphic_data5, FABMASTER::GRAPHIC_DATA::graphic_data6, FABMASTER::GRAPHIC_DATA::graphic_data7, FABMASTER::GRAPHIC_DATA::graphic_data8, FABMASTER::GRAPHIC_DATA::graphic_data9, KiROUND(), NormalizeAnglePos(), RAD2DECIDEG(), FABMASTER::GRAPHIC_ARC::radius, readDouble(), FABMASTER::GRAPHIC_ARC::result, RotatePoint(), FABMASTER::GRAPHIC_ITEM::shape, FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, and FABMASTER::GRAPHIC_ITEM::width.

Referenced by processGraphic().

◆ processCustomPads()

size_t FABMASTER::processCustomPads ( size_t  aRow)
private

A!SUBCLASS!PAD_SHAPE_NAME!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1! GRAPHIC_DATA_2!GRAPHIC_DATA_3!GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7! GRAPHIC_DATA_8!GRAPHIC_DATA_9!PAD_STACK_NAME!REFDES!PIN_NUMBER!

emplace may fail here, in which case, it returns the correct position to use for the existing map

Definition at line 876 of file import_fabmaster.cpp.

877 {
878  size_t rownum = aRow + 2;
879 
880  if( rownum >= rows.size() )
881  return -1;
882 
883  auto header = rows[aRow];
884  double scale_factor = processScaleFactor( aRow + 1 );
885 
886  if( scale_factor <= 0.0 )
887  return -1;
888 
889  int pad_subclass_col = getColFromName( aRow, "SUBCLASS" );
890  int pad_shape_name_col = getColFromName( aRow, "PADSHAPENAME" );
891  int pad_grdata_name_col = getColFromName( aRow, "GRAPHICDATANAME" );
892  int pad_grdata_num_col = getColFromName( aRow, "GRAPHICDATANUMBER" );
893  int pad_record_tag_col = getColFromName( aRow, "RECORDTAG" );
894  int pad_grdata1_col = getColFromName( aRow, "GRAPHICDATA1" );
895  int pad_grdata2_col = getColFromName( aRow, "GRAPHICDATA2" );
896  int pad_grdata3_col = getColFromName( aRow, "GRAPHICDATA3" );
897  int pad_grdata4_col = getColFromName( aRow, "GRAPHICDATA4" );
898  int pad_grdata5_col = getColFromName( aRow, "GRAPHICDATA5" );
899  int pad_grdata6_col = getColFromName( aRow, "GRAPHICDATA6" );
900  int pad_grdata7_col = getColFromName( aRow, "GRAPHICDATA7" );
901  int pad_grdata8_col = getColFromName( aRow, "GRAPHICDATA8" );
902  int pad_grdata9_col = getColFromName( aRow, "GRAPHICDATA9" );
903  int pad_stack_name_col = getColFromName( aRow, "PADSTACKNAME" );
904  int pad_refdes_col = getColFromName( aRow, "REFDES" );
905  int pad_pin_num_col = getColFromName( aRow, "PINNUMBER" );
906 
907  if( pad_subclass_col < 0 || pad_shape_name_col < 0 || pad_grdata1_col < 0 || pad_grdata2_col < 0
908  || pad_grdata3_col < 0 || pad_grdata4_col < 0 || pad_grdata5_col < 0
909  || pad_grdata6_col < 0 || pad_grdata7_col < 0 || pad_grdata8_col < 0
910  || pad_grdata9_col < 0 || pad_stack_name_col < 0 || pad_refdes_col < 0
911  || pad_pin_num_col < 0 )
912  return -1;
913 
914  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
915  {
916  const single_row& row = rows[rownum];
917 
918  if( row.size() != header.size() )
919  {
920  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
921  rownum,
922  header.size(),
923  row.size() );
924 
925  continue;
926  }
927 
928  auto pad_layer = row[pad_subclass_col];
929  auto pad_shape_name = row[pad_shape_name_col];
930  auto pad_record_tag = row[pad_record_tag_col];
931 
932  GRAPHIC_DATA gr_data;
933  gr_data.graphic_dataname = row[pad_grdata_name_col];
934  gr_data.graphic_datanum = row[pad_grdata_num_col];
935  gr_data.graphic_data1 = row[pad_grdata1_col];
936  gr_data.graphic_data2 = row[pad_grdata2_col];
937  gr_data.graphic_data3 = row[pad_grdata3_col];
938  gr_data.graphic_data4 = row[pad_grdata4_col];
939  gr_data.graphic_data5 = row[pad_grdata5_col];
940  gr_data.graphic_data6 = row[pad_grdata6_col];
941  gr_data.graphic_data7 = row[pad_grdata7_col];
942  gr_data.graphic_data8 = row[pad_grdata8_col];
943  gr_data.graphic_data9 = row[pad_grdata9_col];
944 
945  auto pad_stack_name = row[pad_stack_name_col];
946  auto pad_refdes = row[pad_refdes_col];
947  auto pad_pin_num = row[pad_pin_num_col];
948 
949  // N.B. We get the FIGSHAPE records as "FIG_SHAPE name". We only want "name"
950  // and we don't process other pad shape records
951  std::string prefix( "FIG_SHAPE " );
952 
953  if( pad_shape_name.length() <= prefix.length()
954  || !std::equal( prefix.begin(), prefix.end(), pad_shape_name.begin() ) )
955  {
956  continue;
957  }
958 
959  // Custom pads are a series of records with the same record ID but incrementing
960  // Sequence numbers.
961  int id = -1;
962  int seq = -1;
963 
964  if( std::sscanf( pad_record_tag.c_str(), "%d %d", &id, &seq ) != 2 )
965  {
966  wxLogError( _( "Invalid format for id string '%s' in custom pad row %zu." ),
967  pad_record_tag.c_str(),
968  rownum );
969  continue;
970  }
971 
972  auto name = pad_shape_name.substr( prefix.length() );
973  name += "_" + pad_refdes + "_" + pad_pin_num;
974  auto ret = pad_shapes.emplace( name, FABMASTER_PAD_SHAPE{} );
975 
976  auto& custom_pad = ret.first->second;
977 
978  // If we were able to insert the pad name, then we need to initialize the
979  // record
980  if( ret.second )
981  {
982  custom_pad.name = name;
983  custom_pad.padstack = pad_stack_name;
984  custom_pad.pinnum = pad_pin_num;
985  custom_pad.refdes = pad_refdes;
986  }
987 
988  // At this point we extract the individual graphical elements for processing the complex pad. The
989  // coordinates are in board origin format, so we'll need to fix the offset later when we assign them
990  // to the modules.
991 
992  auto gr_item = std::unique_ptr<GRAPHIC_ITEM>( processGraphic( gr_data, scale_factor ) );
993 
994  if( gr_item )
995  {
996  gr_item->layer = pad_layer;
997  gr_item->refdes = pad_refdes;
998  gr_item->seq = seq;
999  gr_item->subseq = 0;
1000 
1002  auto pad_it = custom_pad.elements.emplace( id, graphic_element{} );
1003  auto retval = pad_it.first->second.insert( std::move(gr_item ) );
1004 
1005  if( !retval.second )
1006  {
1007  wxLogError( _( "Could not insert graphical item %d into padstack '%s'." ),
1008  seq,
1009  pad_stack_name.c_str() );
1010  }
1011  }
1012  else
1013  {
1014  wxLogError( _( "Unrecognized pad shape primitive '%s' in row %zu." ),
1015  gr_data.graphic_dataname,
1016  rownum );
1017  }
1018  }
1019 
1020  return rownum - aRow;
1021 }
std::vector< std::string > single_row
GRAPHIC_ITEM * processGraphic(const GRAPHIC_DATA &aData, double aScale)
Specialty functions for processing graphical data rows into the internal database.
std::set< std::unique_ptr< GRAPHIC_ITEM >, GRAPHIC_ITEM::SEQ_CMP > graphic_element
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
std::unordered_map< std::string, FABMASTER_PAD_SHAPE > pad_shapes
const char * name
Definition: DXF_plotter.cpp:56
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, getColFromName(), FABMASTER::GRAPHIC_DATA::graphic_data1, FABMASTER::GRAPHIC_DATA::graphic_data2, FABMASTER::GRAPHIC_DATA::graphic_data3, FABMASTER::GRAPHIC_DATA::graphic_data4, FABMASTER::GRAPHIC_DATA::graphic_data5, FABMASTER::GRAPHIC_DATA::graphic_data6, FABMASTER::GRAPHIC_DATA::graphic_data7, FABMASTER::GRAPHIC_DATA::graphic_data8, FABMASTER::GRAPHIC_DATA::graphic_data9, FABMASTER::GRAPHIC_DATA::graphic_dataname, FABMASTER::GRAPHIC_DATA::graphic_datanum, name, pad_shapes, processGraphic(), processScaleFactor(), and rows.

Referenced by Process().

◆ processFootprints()

size_t FABMASTER::processFootprints ( size_t  aRow)
private

A!REFDES!COMP_CLASS!COMP_PART_NUMBER!COMP_HEIGHT!COMP_DEVICE_LABEL!COMP_INSERTION_CODE!SYM_TYPE! SYM_NAME!SYM_MIRROR!SYM_ROTATE!SYM_X!SYM_Y!COMP_VALUE!COMP_TOL!COMP_VOLTAGE!

Definition at line 1547 of file import_fabmaster.cpp.

1548 {
1549  size_t rownum = aRow + 2;
1550 
1551  if( rownum >= rows.size() )
1552  return -1;
1553 
1554  const single_row& header = rows[aRow];
1555  double scale_factor = processScaleFactor( aRow + 1 );
1556 
1557  if( scale_factor <= 0.0 )
1558  return -1;
1559 
1560  int refdes_col = getColFromName( aRow, "REFDES" );
1561  int compclass_col = getColFromName( aRow, "COMPCLASS" );
1562  int comppartnum_col = getColFromName( aRow, "COMPPARTNUMBER" );
1563  int compheight_col = getColFromName( aRow, "COMPHEIGHT" );
1564  int compdevlabelcol = getColFromName( aRow, "COMPDEVICELABEL" );
1565  int compinscode_col = getColFromName( aRow, "COMPINSERTIONCODE" );
1566  int symtype_col = getColFromName( aRow, "SYMTYPE" );
1567  int symname_col = getColFromName( aRow, "SYMNAME" );
1568  int symmirror_col = getColFromName( aRow, "SYMMIRROR" );
1569  int symrotate_col = getColFromName( aRow, "SYMROTATE" );
1570  int symx_col = getColFromName( aRow, "SYMX" );
1571  int symy_col = getColFromName( aRow, "SYMY" );
1572  int compvalue_col = getColFromName( aRow, "COMPVALUE" );
1573  int comptol_col = getColFromName( aRow, "COMPTOL" );
1574  int compvolt_col = getColFromName( aRow, "COMPVOLTAGE" );
1575 
1576  if( refdes_col < 0 || compclass_col < 0 || comppartnum_col < 0 || compheight_col < 0
1577  || compdevlabelcol < 0 || compinscode_col < 0 || symtype_col < 0 || symname_col < 0
1578  || symmirror_col < 0 || symrotate_col < 0 || symx_col < 0 || symy_col < 0
1579  || compvalue_col < 0 || comptol_col < 0 || compvolt_col < 0 )
1580  return -1;
1581 
1582  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
1583  {
1584  const single_row& row = rows[rownum];
1585 
1586  if( row.size() != header.size() )
1587  {
1588  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
1589  rownum,
1590  header.size(),
1591  row.size() );
1592  continue;
1593  }
1594 
1595  auto cmp = std::make_unique<COMPONENT>();
1596 
1597  cmp->refdes = row[refdes_col];
1598  cmp->cclass = parseCompClass( row[compclass_col] );
1599  cmp->pn = row[comppartnum_col];
1600  cmp->height = row[compheight_col];
1601  cmp->dev_label = row[compdevlabelcol];
1602  cmp->insert_code = row[compinscode_col];
1603  cmp->type = parseSymType( row[symtype_col] );
1604  cmp->name = row[symname_col];
1605  cmp->mirror = ( row[symmirror_col] == "YES" );
1606  cmp->rotate = readDouble( row[symrotate_col] );
1607  cmp->x = KiROUND( readDouble( row[symx_col] ) * scale_factor );
1608  cmp->y = -KiROUND( readDouble( row[symy_col] ) * scale_factor );
1609  cmp->value = row[compvalue_col];
1610  cmp->tol = row[comptol_col];
1611  cmp->voltage = row[compvolt_col];
1612 
1613  auto vec = components.find( cmp->refdes );
1614 
1615  if( vec == components.end() )
1616  {
1617  auto retval = components.insert( std::make_pair( cmp->refdes, std::vector<std::unique_ptr<COMPONENT>>{} ) );
1618 
1619  vec = retval.first;
1620  }
1621 
1622  vec->second.push_back( std::move( cmp ) );
1623  }
1624 
1625  return rownum - aRow;
1626 }
std::vector< std::string > single_row
std::map< std::string, std::vector< std::unique_ptr< COMPONENT > > > components
double readDouble(const std::string &aStr) const
Reads the double/integer value from a std string independent of the user locale.
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
COMPCLASS parseCompClass(const std::string &aCompClass)
SYMTYPE parseSymType(const std::string &aSymType)
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, components, getColFromName(), KiROUND(), parseCompClass(), parseSymType(), processScaleFactor(), readDouble(), and rows.

Referenced by Process().

◆ processGeometry()

size_t FABMASTER::processGeometry ( size_t  aRow)
private

A!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2!GRAPHIC_DATA_3! GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7!GRAPHIC_DATA_8!GRAPHIC_DATA_9! SUBCLASS!SYM_NAME!REFDES!

Definition at line 1185 of file import_fabmaster.cpp.

1186 {
1187  size_t rownum = aRow + 2;
1188 
1189  if( rownum >= rows.size() )
1190  return -1;
1191 
1192  const single_row& header = rows[aRow];
1193  double scale_factor = processScaleFactor( aRow + 1 );
1194 
1195  if( scale_factor <= 0.0 )
1196  return -1;
1197 
1198  int geo_name_col = getColFromName( aRow, "GRAPHICDATANAME" );
1199  int geo_num_col = getColFromName( aRow, "GRAPHICDATANUMBER" );
1200  int geo_tag_col = getColFromName( aRow, "RECORDTAG" );
1201  int geo_grdata1_col = getColFromName( aRow, "GRAPHICDATA1" );
1202  int geo_grdata2_col = getColFromName( aRow, "GRAPHICDATA2" );
1203  int geo_grdata3_col = getColFromName( aRow, "GRAPHICDATA3" );
1204  int geo_grdata4_col = getColFromName( aRow, "GRAPHICDATA4" );
1205  int geo_grdata5_col = getColFromName( aRow, "GRAPHICDATA5" );
1206  int geo_grdata6_col = getColFromName( aRow, "GRAPHICDATA6" );
1207  int geo_grdata7_col = getColFromName( aRow, "GRAPHICDATA7" );
1208  int geo_grdata8_col = getColFromName( aRow, "GRAPHICDATA8" );
1209  int geo_grdata9_col = getColFromName( aRow, "GRAPHICDATA9" );
1210  int geo_subclass_col = getColFromName( aRow, "SUBCLASS" );
1211  int geo_sym_name_col = getColFromName( aRow, "SYMNAME" );
1212  int geo_refdes_col = getColFromName( aRow, "REFDES" );
1213 
1214  if( geo_name_col < 0 || geo_num_col < 0 || geo_grdata1_col < 0 || geo_grdata2_col < 0
1215  || geo_grdata3_col < 0 || geo_grdata4_col < 0 || geo_grdata5_col < 0
1216  || geo_grdata6_col < 0 || geo_grdata7_col < 0 || geo_grdata8_col < 0
1217  || geo_grdata9_col < 0 || geo_subclass_col < 0 || geo_sym_name_col < 0
1218  || geo_refdes_col < 0 )
1219  return -1;
1220 
1221  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
1222  {
1223  const single_row& row = rows[rownum];
1224 
1225  if( row.size() != header.size() )
1226  {
1227  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
1228  rownum,
1229  header.size(),
1230  row.size() );
1231  continue;
1232  }
1233 
1234  auto geo_tag = row[geo_tag_col];
1235 
1236  GRAPHIC_DATA gr_data;
1237  gr_data.graphic_dataname = row[geo_name_col];
1238  gr_data.graphic_datanum = row[geo_num_col];
1239  gr_data.graphic_data1 = row[geo_grdata1_col];
1240  gr_data.graphic_data2 = row[geo_grdata2_col];
1241  gr_data.graphic_data3 = row[geo_grdata3_col];
1242  gr_data.graphic_data4 = row[geo_grdata4_col];
1243  gr_data.graphic_data5 = row[geo_grdata5_col];
1244  gr_data.graphic_data6 = row[geo_grdata6_col];
1245  gr_data.graphic_data7 = row[geo_grdata7_col];
1246  gr_data.graphic_data8 = row[geo_grdata8_col];
1247  gr_data.graphic_data9 = row[geo_grdata9_col];
1248 
1249  auto geo_refdes = row[geo_refdes_col];
1250 
1251  // Grouped graphics are a series of records with the same record ID but incrementing
1252  // Sequence numbers.
1253  int id = -1;
1254  int seq = -1;
1255  int subseq = 0;
1256 
1257  if( std::sscanf( geo_tag.c_str(), "%d %d %d", &id, &seq, &subseq ) < 2 )
1258  {
1259  wxLogError( _( "Invalid format for record_tag string '%s' in row %zu." ),
1260  geo_tag.c_str(),
1261  rownum );
1262  continue;
1263  }
1264 
1265  auto gr_item = std::unique_ptr<GRAPHIC_ITEM>( processGraphic( gr_data, scale_factor ) );
1266 
1267  if( !gr_item )
1268  {
1269  wxLogDebug( wxT( "Unhandled graphic item '%s' in row %zu." ),
1270  gr_data.graphic_dataname.c_str(),
1271  geo_tag.c_str(),
1272  rownum );
1273  continue;
1274  }
1275 
1276  gr_item->layer = row[geo_subclass_col];
1277  gr_item->seq = seq;
1278  gr_item->subseq = subseq;
1279 
1280  if( geo_refdes.empty() )
1281  {
1282  if( board_graphics.empty() || board_graphics.back().id != id )
1283  {
1284  GEOM_GRAPHIC new_gr;
1285  new_gr.subclass = row[geo_subclass_col];
1286  new_gr.refdes = row[geo_refdes_col];
1287  new_gr.name = row[geo_sym_name_col];
1288  new_gr.id = id;
1289  new_gr.elements = std::make_unique<graphic_element>();
1290  board_graphics.push_back( std::move( new_gr ) );
1291  }
1292 
1293  GEOM_GRAPHIC& graphic = board_graphics.back();
1294  graphic.elements->emplace( std::move( gr_item ) );
1295  }
1296  else
1297  {
1298  auto sym_gr_it = comp_graphics.emplace( geo_refdes,
1299  std::map<int, GEOM_GRAPHIC>{} );
1300  auto map_it = sym_gr_it.first->second.emplace( id, GEOM_GRAPHIC{} );
1301  auto& gr = map_it.first;
1302 
1303  if( map_it.second )
1304  {
1305  gr->second.subclass = row[geo_subclass_col];
1306  gr->second.refdes = row[geo_refdes_col];
1307  gr->second.name = row[geo_sym_name_col];
1308  gr->second.id = id;
1309  gr->second.elements = std::make_unique<graphic_element>();
1310  }
1311 
1312  auto result = gr->second.elements->emplace( std::move( gr_item ) );
1313  }
1314  }
1315 
1316  return rownum - aRow;
1317 }
std::vector< std::string > single_row
std::map< std::string, std::map< int, GEOM_GRAPHIC > > comp_graphics
std::vector< GEOM_GRAPHIC > board_graphics
GRAPHIC_ITEM * processGraphic(const GRAPHIC_DATA &aData, double aScale)
Specialty functions for processing graphical data rows into the internal database.
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, board_graphics, comp_graphics, FABMASTER::GEOM_GRAPHIC::elements, getColFromName(), FABMASTER::GRAPHIC_DATA::graphic_data1, FABMASTER::GRAPHIC_DATA::graphic_data2, FABMASTER::GRAPHIC_DATA::graphic_data3, FABMASTER::GRAPHIC_DATA::graphic_data4, FABMASTER::GRAPHIC_DATA::graphic_data5, FABMASTER::GRAPHIC_DATA::graphic_data6, FABMASTER::GRAPHIC_DATA::graphic_data7, FABMASTER::GRAPHIC_DATA::graphic_data8, FABMASTER::GRAPHIC_DATA::graphic_data9, FABMASTER::GRAPHIC_DATA::graphic_dataname, FABMASTER::GRAPHIC_DATA::graphic_datanum, FABMASTER::GEOM_GRAPHIC::id, FABMASTER::GEOM_GRAPHIC::name, processGraphic(), processScaleFactor(), FABMASTER::GEOM_GRAPHIC::refdes, rows, and FABMASTER::GEOM_GRAPHIC::subclass.

Referenced by Process().

◆ processGraphic()

FABMASTER::GRAPHIC_ITEM * FABMASTER::processGraphic ( const GRAPHIC_DATA aData,
double  aScale 
)
private

Specialty functions for processing graphical data rows into the internal database.

Parameters
aDataLoaded data vector
aScalePrior loaded scale factor
Returns
Pointer to newly allocated graphical item or nullptr on failure

Definition at line 1147 of file import_fabmaster.cpp.

1148 {
1149  GRAPHIC_ITEM* retval = nullptr;
1150 
1151  if( aData.graphic_dataname == "LINE" )
1152  retval = processLine( aData, aScale );
1153  else if( aData.graphic_dataname == "ARC" )
1154  retval = processArc( aData, aScale );
1155  else if( aData.graphic_dataname == "RECTANGLE" )
1156  retval = processRectangle( aData, aScale );
1157  else if( aData.graphic_dataname == "TEXT" )
1158  retval = processText( aData, aScale );
1159 
1160  if( retval && !aData.graphic_data10.empty() )
1161  {
1162  if( aData.graphic_data10 == "CONNECT" )
1163  retval->type = GR_TYPE_CONNECT;
1164  else if( aData.graphic_data10 == "NOTCONNECT" )
1165  retval->type = GR_TYPE_NOTCONNECT;
1166  else if( aData.graphic_data10 == "SHAPE" )
1167  retval->type = GR_TYPE_NOTCONNECT;
1168  else if( aData.graphic_data10 == "VOID" )
1169  retval->type = GR_TYPE_NOTCONNECT;
1170  else if( aData.graphic_data10 == "POLYGON" )
1171  retval->type = GR_TYPE_NOTCONNECT;
1172  else
1173  retval->type = GR_TYPE_NONE;
1174  }
1175 
1176  return retval;
1177 }
GRAPHIC_LINE * processLine(const GRAPHIC_DATA &aData, double aScale)
GRAPHIC_RECTANGLE * processRectangle(const GRAPHIC_DATA &aData, double aScale)
GRAPHIC_ARC * processArc(const GRAPHIC_DATA &aData, double aScale)
GRAPHIC_TEXT * processText(const GRAPHIC_DATA &aData, double aScale)

References GR_TYPE_CONNECT, GR_TYPE_NONE, GR_TYPE_NOTCONNECT, FABMASTER::GRAPHIC_DATA::graphic_data10, FABMASTER::GRAPHIC_DATA::graphic_dataname, processArc(), processLine(), processRectangle(), processText(), and FABMASTER::GRAPHIC_ITEM::type.

Referenced by processCustomPads(), processGeometry(), and processTraces().

◆ processLayers()

size_t FABMASTER::processLayers ( size_t  aRow)
private

A!LAYER_SORT!LAYER_SUBCLASS!LAYER_ARTWORK!LAYER_USE!LAYER_CONDUCTOR!LAYER_DIELECTRIC_CONSTANT! LAYER_ELECTRICAL_CONDUCTIVITY!LAYER_MATERIAL!LAYER_SHIELD_LAYER!LAYER_THERMAL_CONDUCTIVITY! LAYER_THICKNESS!

Definition at line 801 of file import_fabmaster.cpp.

802 {
803  size_t rownum = aRow + 2;
804 
805  if( rownum >= rows.size() )
806  return -1;
807 
808  auto header = rows[aRow];
809  double scale_factor = processScaleFactor( aRow + 1 );
810 
811  if( scale_factor <= 0.0 )
812  return -1;
813 
814  int layer_sort_col = getColFromName( aRow, "LAYERSORT" );
815  int layer_subclass_col = getColFromName( aRow, "LAYERSUBCLASS" );
816  int layer_art_col = getColFromName( aRow, "LAYERARTWORK" );
817  int layer_use_col = getColFromName( aRow, "LAYERUSE" );
818  int layer_cond_col = getColFromName( aRow, "LAYERCONDUCTOR" );
819  int layer_er_col = getColFromName( aRow, "LAYERDIELECTRICCONSTANT" );
820  int layer_rho_col = getColFromName( aRow, "LAYERELECTRICALCONDUCTIVITY" );
821  int layer_mat_col = getColFromName( aRow, "LAYERMATERIAL" );
822 
823  if( layer_sort_col < 0 || layer_subclass_col < 0 || layer_art_col < 0 || layer_use_col < 0
824  || layer_cond_col < 0 || layer_er_col < 0 || layer_rho_col < 0 || layer_mat_col < 0 )
825  return -1;
826 
827  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
828  {
829  const single_row& row = rows[rownum];
830 
831  if( row.size() != header.size() )
832  {
833  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
834  rownum,
835  header.size(),
836  row.size() );
837  continue;
838  }
839 
840  auto layer_sort = row[layer_sort_col];
841  auto layer_subclass = row[layer_subclass_col];
842  auto layer_art = row[layer_art_col];
843  auto layer_use = row[layer_use_col];
844  auto layer_cond = row[layer_cond_col];
845  auto layer_er = row[layer_er_col];
846  auto layer_rho = row[layer_rho_col];
847  auto layer_mat = row[layer_mat_col];
848 
849  if( layer_mat == "AIR" )
850  continue;
851 
852  FABMASTER_LAYER layer;
853 
854  if( layer_subclass.empty() )
855  {
856  if( layer_cond != "NO" )
857  layer.name = "In.Cu" + layer_sort;
858  else
859  layer.name = "Dielectric" + layer_sort;
860  }
861 
862  layer.positive = ( layer_art != "NEGATIVE" );
863 
864  layers.emplace( layer.name, layer );
865  }
866 
867  return rownum - aRow;
868 }
std::vector< std::string > single_row
std::map< std::string, FABMASTER_LAYER > layers
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, getColFromName(), layers, FABMASTER::FABMASTER_LAYER::name, FABMASTER::FABMASTER_LAYER::positive, processScaleFactor(), and rows.

Referenced by Process().

◆ processLine()

FABMASTER::GRAPHIC_LINE * FABMASTER::processLine ( const GRAPHIC_DATA aData,
double  aScale 
)
private

Definition at line 1024 of file import_fabmaster.cpp.

1025 {
1026  GRAPHIC_LINE* new_line = new GRAPHIC_LINE ;
1027 
1028  new_line->shape = GR_SHAPE_LINE;
1029  new_line->start_x = KiROUND( readDouble( aData.graphic_data1 ) * aScale );
1030  new_line->start_y = -KiROUND( readDouble( aData.graphic_data2 ) * aScale );
1031  new_line->end_x = KiROUND( readDouble( aData.graphic_data3 ) * aScale );
1032  new_line->end_y = -KiROUND( readDouble( aData.graphic_data4 ) * aScale );
1033  new_line->width = KiROUND( readDouble( aData.graphic_data5 ) * aScale );
1034 
1035  return new_line;
1036 }
double readDouble(const std::string &aStr) const
Reads the double/integer value from a std string independent of the user locale.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73

References FABMASTER::GRAPHIC_LINE::end_x, FABMASTER::GRAPHIC_LINE::end_y, GR_SHAPE_LINE, FABMASTER::GRAPHIC_DATA::graphic_data1, FABMASTER::GRAPHIC_DATA::graphic_data2, FABMASTER::GRAPHIC_DATA::graphic_data3, FABMASTER::GRAPHIC_DATA::graphic_data4, FABMASTER::GRAPHIC_DATA::graphic_data5, KiROUND(), readDouble(), FABMASTER::GRAPHIC_ITEM::shape, FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, and FABMASTER::GRAPHIC_ITEM::width.

Referenced by processGraphic().

◆ processNets()

size_t FABMASTER::processNets ( size_t  aRow)
private

A!NET_NAME!REFDES!PIN_NUMBER!PIN_NAME!PIN_GROUND!PIN_POWER!

Definition at line 1704 of file import_fabmaster.cpp.

1705 {
1706  size_t rownum = aRow + 2;
1707 
1708  if( rownum >= rows.size() )
1709  return -1;
1710 
1711  const single_row& header = rows[aRow];
1712  double scale_factor = processScaleFactor( aRow + 1 );
1713 
1714  if( scale_factor <= 0.0 )
1715  return -1;
1716 
1717  int netname_col = getColFromName( aRow, "NETNAME" );
1718  int refdes_col = getColFromName( aRow, "REFDES" );
1719  int pinnum_col = getColFromName( aRow, "PINNUMBER" );
1720  int pinname_col = getColFromName( aRow, "PINNAME" );
1721  int pingnd_col = getColFromName( aRow, "PINGROUND" );
1722  int pinpwr_col = getColFromName( aRow, "PINPOWER" );
1723 
1724  if( netname_col < 0 || refdes_col < 0 || pinnum_col < 0 || pinname_col < 0 || pingnd_col < 0
1725  || pinpwr_col < 0 )
1726  return -1;
1727 
1728  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
1729  {
1730  const single_row& row = rows[rownum];
1731 
1732  if( row.size() != header.size() )
1733  {
1734  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
1735  rownum,
1736  header.size(),
1737  row.size() );
1738  continue;
1739  }
1740 
1741  NETNAME new_net;
1742  new_net.name = row[netname_col];
1743  new_net.refdes = row[refdes_col];
1744  new_net.pin_num = row[pinnum_col];
1745  new_net.pin_name = row[pinname_col];
1746  new_net.pin_gnd = ( row[pingnd_col] == "YES" );
1747  new_net.pin_pwr = ( row[pinpwr_col] == "YES" );
1748 
1749  pin_nets.emplace( std::make_pair( new_net.refdes, new_net.pin_num ), new_net );
1750  netnames.insert( row[netname_col] );
1751  }
1752 
1753  return rownum - aRow;
1754 }
std::vector< std::string > single_row
std::map< std::pair< std::string, std::string >, NETNAME > pin_nets
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
std::set< std::string > netnames
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, getColFromName(), FABMASTER::NETNAME::name, netnames, FABMASTER::NETNAME::pin_gnd, FABMASTER::NETNAME::pin_name, pin_nets, FABMASTER::NETNAME::pin_num, FABMASTER::NETNAME::pin_pwr, processScaleFactor(), FABMASTER::NETNAME::refdes, and rows.

Referenced by Process().

◆ processPadStackLayers()

size_t FABMASTER::processPadStackLayers ( size_t  aRow)
private

If the layer ids have not yet been assigned

Definition at line 331 of file import_fabmaster.cpp.

332 {
333  size_t rownum = aRow + 2;
334 
335  if( rownum >= rows.size() )
336  return -1;
337 
338  const single_row& header = rows[aRow];
339 
340  int pad_name_col = getColFromName( aRow, "PADNAME" );
341  int pad_num_col = getColFromName( aRow, "RECNUMBER" );
342  int pad_lay_col = getColFromName( aRow, "LAYER" );
343  int pad_fix_col = getColFromName( aRow, "FIXFLAG" );
344  int pad_via_col = getColFromName( aRow, "VIAFLAG" );
345  int pad_shape_col = getColFromName( aRow, "PADSHAPE1" );
346  int pad_width_col = getColFromName( aRow, "PADWIDTH" );
347  int pad_height_col = getColFromName( aRow, "PADHGHT" );
348  int pad_xoff_col = getColFromName( aRow, "PADXOFF" );
349  int pad_yoff_col = getColFromName( aRow, "PADYOFF" );
350  int pad_flash_col = getColFromName( aRow, "PADFLASH" );
351  int pad_shape_name_col = getColFromName( aRow, "PADSHAPENAME" );
352 
353  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
354  {
355  const single_row& row = rows[rownum];
356 
357  if( row.size() != header.size() )
358  {
359  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
360  rownum,
361  header.size(),
362  row.size() );
363  continue;
364  }
365 
366  auto pad_name = row[pad_name_col];
367  auto pad_num = row[pad_num_col];
368  auto pad_layer = row[pad_lay_col];
369  auto pad_is_fixed = row[pad_fix_col];
370  auto pad_is_via = row[pad_via_col];
371  auto pad_shape = row[pad_shape_col];
372  auto pad_width = row[pad_width_col];
373  auto pad_height = row[pad_height_col];
374  auto pad_xoff = row[pad_xoff_col];
375  auto pad_yoff = row[pad_yoff_col];
376  auto pad_flash = row[pad_flash_col];
377  auto pad_shapename = row[pad_shape_name_col];
378 
379  // This layer setting seems to be unused
380  if( pad_layer == "INTERNAL_PAD_DEF" || pad_layer == "internal_pad_def" )
381  continue;
382 
383  // Skip the technical layers
384  if( pad_layer[0] == '~' )
385  break;
386 
387  auto result = layers.emplace( pad_layer, FABMASTER_LAYER{} );
388  FABMASTER_LAYER& layer = result.first->second;
389 
391  if( layer.id == 0 )
392  {
393  layer.name = pad_layer;
394  layer.id = readInt( pad_num );
395  layer.conductive = true;
396  }
397  }
398 
399  return 0;
400 }
std::vector< std::string > single_row
std::map< std::string, FABMASTER_LAYER > layers
int readInt(const std::string &aStr) const
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
std::deque< single_row > rows

References _, FABMASTER::FABMASTER_LAYER::conductive, getColFromName(), FABMASTER::FABMASTER_LAYER::id, layers, FABMASTER::FABMASTER_LAYER::name, readInt(), and rows.

Referenced by Process().

◆ processPadStacks()

size_t FABMASTER::processPadStacks ( size_t  aRow)
private

A!PADNAME!RECNUMBER!LAYER!FIXFLAG!VIAFLAG!PADSHAPE1!PADWIDTH!PADHGHT! PADXOFF!PADYOFF!PADFLASH!PADSHAPENAME!TRELSHAPE1!TRELWIDTH!TRELHGHT! TRELXOFF!TRELYOFF!TRELFLASH!TRELSHAPENAME!APADSHAPE1!APADWIDTH!APADHGHT! APADXOFF!APADYOFF!APADFLASH!APADSHAPENAME!

Handle the drill layer

This is to account for broken fabmaster outputs where circle drill hits don't actually get the drill hit value.

All remaining technical layers are not handled

Definition at line 409 of file import_fabmaster.cpp.

410 {
411  size_t rownum = aRow + 2;
412 
413  if( rownum >= rows.size() )
414  return -1;
415 
416  const single_row& header = rows[aRow];
417  double scale_factor = processScaleFactor( aRow + 1 );
418 
419  if( scale_factor <= 0.0 )
420  return -1;
421 
422  int pad_name_col = getColFromName( aRow, "PADNAME" );
423  int pad_num_col = getColFromName( aRow, "RECNUMBER" );
424  int pad_lay_col = getColFromName( aRow, "LAYER" );
425  int pad_fix_col = getColFromName( aRow, "FIXFLAG" );
426  int pad_via_col = getColFromName( aRow, "VIAFLAG" );
427  int pad_shape_col = getColFromName( aRow, "PADSHAPE1" );
428  int pad_width_col = getColFromName( aRow, "PADWIDTH" );
429  int pad_height_col = getColFromName( aRow, "PADHGHT" );
430  int pad_xoff_col = getColFromName( aRow, "PADXOFF" );
431  int pad_yoff_col = getColFromName( aRow, "PADYOFF" );
432  int pad_flash_col = getColFromName( aRow, "PADFLASH" );
433  int pad_shape_name_col = getColFromName( aRow, "PADSHAPENAME" );
434 
435  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
436  {
437  const single_row& row = rows[rownum];
438  FM_PAD* pad;
439 
440  if( row.size() != header.size() )
441  {
442  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
443  rownum,
444  header.size(),
445  row.size() );
446  continue;
447  }
448 
449  auto pad_name = row[pad_name_col];
450  auto pad_num = row[pad_num_col];
451  auto pad_layer = row[pad_lay_col];
452  auto pad_is_fixed = row[pad_fix_col];
453  auto pad_is_via = row[pad_via_col];
454  auto pad_shape = row[pad_shape_col];
455  auto pad_width = row[pad_width_col];
456  auto pad_height = row[pad_height_col];
457  auto pad_xoff = row[pad_xoff_col];
458  auto pad_yoff = row[pad_yoff_col];
459  auto pad_flash = row[pad_flash_col];
460  auto pad_shapename = row[pad_shape_name_col];
461 
462  // This layer setting seems to be unused
463  if( pad_layer == "INTERNAL_PAD_DEF" || pad_layer == "internal_pad_def" )
464  continue;
465 
466  int recnum = KiROUND( readDouble( pad_num ) );
467 
468  auto new_pad = pads.find( pad_name );
469 
470  if( new_pad != pads.end() )
471  pad = &new_pad->second;
472  else
473  {
474  pads[pad_name] = FM_PAD();
475  pad = &pads[pad_name];
476  pad->name = pad_name;
477  }
478 
480  if( pad_layer == "~DRILL" )
481  {
482  int drill_hit;
483  int drill_x;
484  int drill_y;
485 
486  try
487  {
488  drill_hit = KiROUND( std::fabs( readDouble( pad_shape ) * scale_factor ) );
489  drill_x = KiROUND( std::fabs( readDouble( pad_width ) * scale_factor ) );
490  drill_y = KiROUND( std::fabs( readDouble( pad_height ) * scale_factor ) );
491  }
492  catch( ... )
493  {
494  wxLogError( _( "Expecting drill size value but found %s!%s!%s in row %zu." ),
495  pad_shape.c_str(),
496  pad_width.c_str(),
497  pad_height.c_str(),
498  rownum );
499  continue;
500  }
501 
502  if( drill_hit == 0 )
503  {
504  pad->drill = false;
505  continue;
506  }
507 
508  pad->drill = true;
509 
512  if( drill_x == drill_y )
513  {
514  pad->drill_size_x = drill_hit;
515  pad->drill_size_y = drill_hit;
516  }
517  else
518  {
519  pad->drill_size_x = drill_x;
520  pad->drill_size_y = drill_y;
521  }
522 
523  if( !pad_shapename.empty() && pad_shapename[0] == 'P' )
524  pad->plated = true;
525 
526  continue;
527  }
528 
529  if( pad_shape.empty() )
530  continue;
531 
532  double w;
533  double h;
534 
535  try
536  {
537  w = readDouble( pad_width ) * scale_factor;
538  h = readDouble( pad_height ) * scale_factor;
539  }
540  catch( ... )
541  {
542  wxLogError( _( "Expecting pad size values but found %s : %s in row %zu." ),
543  pad_width.c_str(),
544  pad_height.c_str(),
545  rownum );
546  continue;
547  }
548 
549  if( w <= 0.0 )
550  continue;
551 
552  auto layer = layers.find( pad_layer );
553 
554  if( layer != layers.end() )
555  {
556  if( layer->second.layerid == F_Cu )
557  pad->top = true;
558  else if( layer->second.layerid == B_Cu )
559  pad->bottom = true;
560  }
561 
562  if( w > std::numeric_limits<int>::max() || h > std::numeric_limits<int>::max() )
563  {
564  wxLogError( _( "Invalid pad size in row %zu." ), rownum );
565  continue;
566  }
567 
568  if( pad_layer == "~TSM" || pad_layer == "~BSM" )
569  {
570  if( w > 0.0 && h > 0.0 )
571  {
572  pad->mask_width = KiROUND( w );
573  pad->mask_height = KiROUND( h );
574  }
575  continue;
576  }
577 
578  if( pad_layer == "~TSP" || pad_layer == "~BSP" )
579  {
580  if( w > 0.0 && h > 0.0 )
581  {
582  pad->paste_width = KiROUND( w );
583  pad->paste_height = KiROUND( h );
584  }
585  continue;
586  }
587 
589  if( pad_layer[0] == '~' )
590  continue;
591 
592  try
593  {
594  pad->x_offset = KiROUND( readDouble( pad_xoff ) * scale_factor );
595  pad->y_offset = -KiROUND( readDouble( pad_yoff ) * scale_factor );
596  }
597  catch( ... )
598  {
599  wxLogError( _( "Expecting pad offset values but found %s:%s in row %zu." ),
600  pad_xoff.c_str(),
601  pad_yoff.c_str(),
602  rownum );
603  continue;
604  }
605 
606  if( w > 0.0 && h > 0.0 && recnum == 1 )
607  {
608  pad->width = KiROUND( w );
609  pad->height = KiROUND( h );
610  pad->via = ( std::toupper( pad_is_via[0] ) != 'V' );
611 
612  if( pad_shape == "CIRCLE" )
613  {
614  pad->height = pad->width;
615  pad->shape = PAD_SHAPE::CIRCLE;
616  }
617  else if( pad_shape == "RECTANGLE" )
618  {
619  pad->shape = PAD_SHAPE::RECT;
620  }
621  else if( pad_shape == "ROUNDED_RECT" )
622  {
623  pad->shape = PAD_SHAPE::ROUNDRECT;
624  }
625  else if( pad_shape == "SQUARE" )
626  {
627  pad->shape = PAD_SHAPE::RECT;
628  pad->height = pad->width;
629  }
630  else if( pad_shape == "OBLONG" || pad_shape == "OBLONG_X" || pad_shape == "OBLONG_Y" )
631  pad->shape = PAD_SHAPE::OVAL;
632  else if( pad_shape == "OCTAGON" )
633  {
634  pad->shape = PAD_SHAPE::RECT;
635  pad->is_octogon = true;
636  }
637  else if( pad_shape == "SHAPE" )
638  {
639  pad->shape = PAD_SHAPE::CUSTOM;
640  pad->custom_name = pad_shapename;
641  }
642  else
643  {
644  wxLogError( _( "Unknown pad shape name '%s' on layer '%s' in row %zu." ),
645  pad_shape.c_str(),
646  pad_layer.c_str(),
647  rownum );
648  continue;
649  }
650  }
651  }
652 
653  return rownum - aRow;
654 }
std::vector< std::string > single_row
double readDouble(const std::string &aStr) const
Reads the double/integer value from a std string independent of the user locale.
std::map< std::string, FABMASTER_LAYER > layers
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
std::unordered_map< std::string, FM_PAD > pads
Definition: layer_ids.h:71
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, B_Cu, CIRCLE, CUSTOM, F_Cu, getColFromName(), KiROUND(), layers, OVAL, pad, pads, processScaleFactor(), readDouble(), RECT, ROUNDRECT, and rows.

Referenced by Process().

◆ processPins()

size_t FABMASTER::processPins ( size_t  aRow)
private

A!SYM_NAME!SYM_MIRROR!PIN_NAME!PIN_NUMBER!PIN_X!PIN_Y!PAD_STACK_NAME!REFDES!PIN_ROTATION!TEST_POINT!

Definition at line 1632 of file import_fabmaster.cpp.

1633 {
1634  size_t rownum = aRow + 2;
1635 
1636  if( rownum >= rows.size() )
1637  return -1;
1638 
1639  const single_row& header = rows[aRow];
1640  double scale_factor = processScaleFactor( aRow + 1 );
1641 
1642  if( scale_factor <= 0.0 )
1643  return -1;
1644 
1645  int symname_col = getColFromName( aRow, "SYMNAME" );
1646  int symmirror_col = getColFromName( aRow, "SYMMIRROR" );
1647  int pinname_col = getColFromName( aRow, "PINNAME" );
1648  int pinnum_col = getColFromName( aRow, "PINNUMBER" );
1649  int pinx_col = getColFromName( aRow, "PINX" );
1650  int piny_col = getColFromName( aRow, "PINY" );
1651  int padstack_col = getColFromName( aRow, "PADSTACKNAME" );
1652  int refdes_col = getColFromName( aRow, "REFDES" );
1653  int pinrot_col = getColFromName( aRow, "PINROTATION" );
1654  int testpoint_col = getColFromName( aRow, "TESTPOINT" );
1655 
1656  if( symname_col < 0 ||symmirror_col < 0 || pinname_col < 0 || pinnum_col < 0 || pinx_col < 0
1657  || piny_col < 0 || padstack_col < 0 || refdes_col < 0 || pinrot_col < 0
1658  || testpoint_col < 0 )
1659  return -1;
1660 
1661  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
1662  {
1663  const single_row& row = rows[rownum];
1664 
1665  if( row.size() != header.size() )
1666  {
1667  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
1668  rownum,
1669  header.size(),
1670  row.size() );
1671  continue;
1672  }
1673 
1674  auto pin = std::make_unique<PIN>();
1675 
1676  pin->name = row[symname_col];
1677  pin->mirror = ( row[symmirror_col] == "YES" );
1678  pin->pin_name = row[pinname_col];
1679  pin->pin_number = row[pinnum_col];
1680  pin->pin_x = KiROUND( readDouble( row[pinx_col] ) * scale_factor );
1681  pin->pin_y = -KiROUND( readDouble( row[piny_col] ) * scale_factor );
1682  pin->padstack = row[padstack_col];
1683  pin->refdes = row[refdes_col];
1684  pin->rotation = readDouble( row[pinrot_col] );
1685 
1686  auto map_it = pins.find( pin->refdes );
1687 
1688  if( map_it == pins.end() )
1689  {
1690  auto retval = pins.insert( std::make_pair( pin->refdes, std::set<std::unique_ptr<PIN>, PIN::BY_NUM>{} ) );
1691  map_it = retval.first;
1692  }
1693 
1694  map_it->second.insert( std::move( pin ) );
1695  }
1696 
1697  return rownum - aRow;
1698 }
std::vector< std::string > single_row
double readDouble(const std::string &aStr) const
Reads the double/integer value from a std string independent of the user locale.
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
std::map< std::string, std::set< std::unique_ptr< PIN >, PIN::BY_NUM > > pins
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, getColFromName(), KiROUND(), pin, pins, processScaleFactor(), readDouble(), and rows.

Referenced by Process().

◆ processRectangle()

FABMASTER::GRAPHIC_RECTANGLE * FABMASTER::processRectangle ( const GRAPHIC_DATA aData,
double  aScale 
)
private

Definition at line 1087 of file import_fabmaster.cpp.

1088 {
1089  GRAPHIC_RECTANGLE* new_rect = new GRAPHIC_RECTANGLE;
1090 
1091  new_rect->shape = GR_SHAPE_RECTANGLE;
1092  new_rect->start_x = KiROUND( readDouble( aData.graphic_data1 ) * aScale );
1093  new_rect->start_y = -KiROUND( readDouble( aData.graphic_data2 ) * aScale );
1094  new_rect->end_x = KiROUND( readDouble( aData.graphic_data3 ) * aScale );
1095  new_rect->end_y = -KiROUND( readDouble( aData.graphic_data4 ) * aScale );
1096  new_rect->fill = aData.graphic_data5 == "1";
1097  new_rect->width = 0;
1098 
1099  return new_rect;
1100 }
double readDouble(const std::string &aStr) const
Reads the double/integer value from a std string independent of the user locale.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73

References FABMASTER::GRAPHIC_RECTANGLE::end_x, FABMASTER::GRAPHIC_RECTANGLE::end_y, FABMASTER::GRAPHIC_RECTANGLE::fill, GR_SHAPE_RECTANGLE, FABMASTER::GRAPHIC_DATA::graphic_data1, FABMASTER::GRAPHIC_DATA::graphic_data2, FABMASTER::GRAPHIC_DATA::graphic_data3, FABMASTER::GRAPHIC_DATA::graphic_data4, FABMASTER::GRAPHIC_DATA::graphic_data5, KiROUND(), readDouble(), FABMASTER::GRAPHIC_ITEM::shape, FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, and FABMASTER::GRAPHIC_ITEM::width.

Referenced by processGraphic().

◆ processScaleFactor()

double FABMASTER::processScaleFactor ( size_t  aRow)
private

Processes data from text vectors into internal database for further ordering.

Parameters
aRowvector offset being processed
Returns
Count of the number of rows processed, return -1 on error

Definition at line 259 of file import_fabmaster.cpp.

260 {
261  double retval = 0.0;
262 
263  if( aRow >= rows.size() )
264  return -1.0;
265 
266  if( rows[aRow].size() < 11 )
267  {
268  wxLogError( _( "Invalid row size in J row %zu. Expecting 11 elements but found %zu." ),
269  aRow,
270  rows[aRow].size() );
271  return -1.0;
272  }
273 
274  for( int i = 7; i < 10 && retval < 1.0; ++i )
275  {
276  std::string units = rows[aRow][i];
277  std::transform(units.begin(), units.end(),units.begin(), ::toupper);
278 
279  if( units == "MILS" )
280  retval = IU_PER_MILS;
281  else if( units == "MILLIMETERS" )
282  retval = IU_PER_MM;
283  else if( units == "MICRONS" )
284  retval = IU_PER_MM * 10.0;
285  else if( units == "INCHES" )
286  retval = IU_PER_MILS * 1000.0;
287  }
288 
289  if( retval < 1.0 )
290  {
291  wxLogError( _( "Could not find units value, defaulting to mils." ) );
292  retval = IU_PER_MILS;
293  }
294 
295  return retval;
296 }
static constexpr double IU_PER_MM
Mock up a conversion function.
#define _(s)
#define IU_PER_MILS
Definition: plotter.cpp:130
std::deque< single_row > rows

References _, IU_PER_MILS, IU_PER_MM, and rows.

Referenced by processCustomPads(), processFootprints(), processGeometry(), processLayers(), processNets(), processPadStacks(), processPins(), processSimpleLayers(), processTraces(), and processVias().

◆ processSimpleLayers()

size_t FABMASTER::processSimpleLayers ( size_t  aRow)
private

Definition at line 657 of file import_fabmaster.cpp.

658 {
659  size_t rownum = aRow + 2;
660 
661  if( rownum >= rows.size() )
662  return -1;
663 
664  auto header = rows[aRow];
665  double scale_factor = processScaleFactor( aRow + 1 );
666 
667  if( scale_factor <= 0.0 )
668  return -1;
669 
670  int layer_class_col = getColFromName( aRow, "CLASS" );
671  int layer_subclass_col = getColFromName( aRow, "SUBCLASS" );
672 
673  if( layer_class_col < 0 || layer_subclass_col < 0 )
674  return -1;
675 
676  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
677  {
678  const single_row& row = rows[rownum];
679 
680  if( row.size() != header.size() )
681  {
682  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
683  rownum,
684  header.size(),
685  row.size() );
686  continue;
687  }
688 
689  auto result = layers.emplace( row[layer_subclass_col], FABMASTER_LAYER{} );
690  FABMASTER_LAYER& layer = result.first->second;
691 
692  layer.name = row[layer_subclass_col];
693  layer.positive = true;
694  layer.conductive = false;
695 
696  if( row[layer_class_col] == "ANTI ETCH" )
697  {
698  layer.positive = false;
699  layer.conductive = true;
700  }
701  else if( row[layer_class_col] == "ETCH" )
702  {
703  layer.conductive = true;
704  }
705  }
706 
707  return rownum - aRow;
708 }
std::vector< std::string > single_row
std::map< std::string, FABMASTER_LAYER > layers
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, FABMASTER::FABMASTER_LAYER::conductive, getColFromName(), layers, FABMASTER::FABMASTER_LAYER::name, FABMASTER::FABMASTER_LAYER::positive, processScaleFactor(), and rows.

Referenced by Process().

◆ processSymbols()

size_t FABMASTER::processSymbols ( size_t  aRow)
private

◆ processText()

FABMASTER::GRAPHIC_TEXT * FABMASTER::processText ( const GRAPHIC_DATA aData,
double  aScale 
)
private

Definition at line 1102 of file import_fabmaster.cpp.

1103 {
1104  GRAPHIC_TEXT* new_text = new GRAPHIC_TEXT;
1105 
1106  new_text->shape = GR_SHAPE_TEXT;
1107  new_text->start_x = KiROUND( readDouble( aData.graphic_data1 ) * aScale );
1108  new_text->start_y = -KiROUND( readDouble( aData.graphic_data2 ) * aScale );
1109  new_text->rotation = KiROUND( readDouble( aData.graphic_data3 ) );
1110  new_text->mirror = ( aData.graphic_data4 == "YES" );
1111 
1112  if( aData.graphic_data5 == "RIGHT" )
1113  new_text->orient = GR_TEXT_HJUSTIFY_RIGHT;
1114  else if( aData.graphic_data5 == "CENTER" )
1115  new_text->orient = GR_TEXT_HJUSTIFY_CENTER;
1116  else
1117  new_text->orient = GR_TEXT_HJUSTIFY_LEFT;
1118 
1119  std::vector<std::string> toks = split( aData.graphic_data6, " \t" );
1120 
1121  if( toks.size() < 8 )
1122  {
1123  // We log the error here but continue in the case of too few tokens
1124  wxLogError( _( "Invalid token count. Expected 8 but found %zu." ), toks.size() );
1125  new_text->height = 0;
1126  new_text->width = 0;
1127  new_text->ital = false;
1128  new_text->thickness = 0;
1129  }
1130  else
1131  {
1132  // 0 = size
1133  // 1 = font
1134  new_text->height = KiROUND( readDouble( toks[2] ) * aScale );
1135  new_text->width = KiROUND( readDouble( toks[3] ) * aScale );
1136  new_text->ital = readDouble( toks[4] ) != 0.0;
1137  // 5 = character spacing
1138  // 6 = line spacing
1139  new_text->thickness = KiROUND( readDouble( toks[7] ) * aScale );
1140  }
1141 
1142  new_text->text = aData.graphic_data7;
1143  return new_text;
1144 }
double readDouble(const std::string &aStr) const
Reads the double/integer value from a std string independent of the user locale.
#define _(s)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
static std::vector< std::string > split(const std::string &aStr, const std::string &aDelim)
Split the input string into a vector of output strings.
Definition: string_utils.h:293

References _, GR_SHAPE_TEXT, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, FABMASTER::GRAPHIC_DATA::graphic_data1, FABMASTER::GRAPHIC_DATA::graphic_data2, FABMASTER::GRAPHIC_DATA::graphic_data3, FABMASTER::GRAPHIC_DATA::graphic_data4, FABMASTER::GRAPHIC_DATA::graphic_data5, FABMASTER::GRAPHIC_DATA::graphic_data6, FABMASTER::GRAPHIC_DATA::graphic_data7, FABMASTER::GRAPHIC_TEXT::height, FABMASTER::GRAPHIC_TEXT::ital, KiROUND(), FABMASTER::GRAPHIC_TEXT::mirror, FABMASTER::GRAPHIC_TEXT::orient, readDouble(), FABMASTER::GRAPHIC_TEXT::rotation, FABMASTER::GRAPHIC_ITEM::shape, split(), FABMASTER::GRAPHIC_ITEM::start_x, FABMASTER::GRAPHIC_ITEM::start_y, FABMASTER::GRAPHIC_TEXT::text, FABMASTER::GRAPHIC_TEXT::thickness, and FABMASTER::GRAPHIC_ITEM::width.

Referenced by processGraphic().

◆ processTraces()

size_t FABMASTER::processTraces ( size_t  aRow)
private

A!CLASS!SUBCLASS!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2! GRAPHIC_DATA_3!GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7!GRAPHIC_DATA_8! GRAPHIC_DATA_9!NET_NAME!

Definition at line 1378 of file import_fabmaster.cpp.

1379 {
1380  size_t rownum = aRow + 2;
1381 
1382  if( rownum >= rows.size() )
1383  return -1;
1384 
1385  const single_row& header = rows[aRow];
1386  double scale_factor = processScaleFactor( aRow + 1 );
1387 
1388  if( scale_factor <= 0.0 )
1389  return -1;
1390 
1391  int class_col = getColFromName( aRow, "CLASS" );
1392  int layer_col = getColFromName( aRow, "SUBCLASS" );
1393  int grdata_name_col = getColFromName( aRow, "GRAPHICDATANAME" );
1394  int grdata_num_col = getColFromName( aRow, "GRAPHICDATANUMBER" );
1395  int tag_col = getColFromName( aRow, "RECORDTAG" );
1396  int grdata1_col = getColFromName( aRow, "GRAPHICDATA1" );
1397  int grdata2_col = getColFromName( aRow, "GRAPHICDATA2" );
1398  int grdata3_col = getColFromName( aRow, "GRAPHICDATA3" );
1399  int grdata4_col = getColFromName( aRow, "GRAPHICDATA4" );
1400  int grdata5_col = getColFromName( aRow, "GRAPHICDATA5" );
1401  int grdata6_col = getColFromName( aRow, "GRAPHICDATA6" );
1402  int grdata7_col = getColFromName( aRow, "GRAPHICDATA7" );
1403  int grdata8_col = getColFromName( aRow, "GRAPHICDATA8" );
1404  int grdata9_col = getColFromName( aRow, "GRAPHICDATA9" );
1405  int netname_col = getColFromName( aRow, "NETNAME" );
1406 
1407  if( class_col < 0 || layer_col < 0 || grdata_name_col < 0 || grdata_num_col < 0
1408  || tag_col < 0 || grdata1_col < 0 || grdata2_col < 0 || grdata3_col < 0
1409  || grdata4_col < 0 || grdata5_col < 0 || grdata6_col < 0 || grdata7_col < 0
1410  || grdata8_col < 0 || grdata9_col < 0 || netname_col < 0 )
1411  return -1;
1412 
1413  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
1414  {
1415  const single_row& row = rows[rownum];
1416 
1417  if( row.size() != header.size() )
1418  {
1419  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
1420  rownum,
1421  header.size(),
1422  row.size() );
1423  continue;
1424  }
1425 
1426  GRAPHIC_DATA gr_data;
1427  gr_data.graphic_dataname = row[grdata_name_col];
1428  gr_data.graphic_datanum = row[grdata_num_col];
1429  gr_data.graphic_data1 = row[grdata1_col];
1430  gr_data.graphic_data2 = row[grdata2_col];
1431  gr_data.graphic_data3 = row[grdata3_col];
1432  gr_data.graphic_data4 = row[grdata4_col];
1433  gr_data.graphic_data5 = row[grdata5_col];
1434  gr_data.graphic_data6 = row[grdata6_col];
1435  gr_data.graphic_data7 = row[grdata7_col];
1436  gr_data.graphic_data8 = row[grdata8_col];
1437  gr_data.graphic_data9 = row[grdata9_col];
1438 
1439  const std::string& geo_tag = row[tag_col];
1440  // Grouped graphics are a series of records with the same record ID but incrementing
1441  // Sequence numbers.
1442  int id = -1;
1443  int seq = -1;
1444  int subseq = 0;
1445 
1446  if( std::sscanf( geo_tag.c_str(), "%d %d %d", &id, &seq, &subseq ) < 2 )
1447  {
1448  wxLogError( _( "Invalid format for record_tag string '%s' in row %zu." ),
1449  geo_tag.c_str(),
1450  rownum );
1451  continue;
1452  }
1453 
1454  auto gr_item = std::unique_ptr<GRAPHIC_ITEM>( processGraphic( gr_data, scale_factor ) );
1455 
1456  if( !gr_item )
1457  {
1458  wxLogDebug( _( "Unhandled graphic item '%s' in row %zu." ),
1459  gr_data.graphic_dataname.c_str(),
1460  rownum );
1461  continue;
1462  }
1463 
1464  auto new_trace = std::make_unique<TRACE>();
1465  new_trace->id = id;
1466  new_trace->layer = row[layer_col];
1467  new_trace->netname = row[netname_col];
1468  new_trace->lclass = row[class_col];
1469 
1470  gr_item->layer = row[layer_col];
1471  gr_item->seq = seq;
1472  gr_item->subseq = subseq;
1473 
1474  // Collect the reference designator positions for the footprints later
1475  if( new_trace->lclass == "REF DES" )
1476  {
1477  auto result = refdes.emplace( std::move( new_trace ) );
1478  auto& ref = *result.first;
1479  ref->segment.emplace( std::move( gr_item ) );
1480  }
1481  else if( gr_item->width == 0 )
1482  {
1483  auto result = zones.emplace( std::move( new_trace ) );
1484  auto& zone = *result.first;
1485  auto gr_result = zone->segment.emplace( std::move( gr_item ) );
1486 
1487  if( !gr_result.second )
1488  {
1489  wxLogError( _( "Duplicate item for ID %d and sequence %d in row %zu." ),
1490  id,
1491  seq,
1492  rownum );
1493  }
1494 
1495  }
1496  else
1497  {
1498  auto result = traces.emplace( std::move( new_trace ) );
1499  auto& trace = *result.first;
1500  auto gr_result = trace->segment.emplace( std::move( gr_item ) );
1501 
1502  if( !gr_result.second )
1503  {
1504  wxLogError( _( "Duplicate item for ID %d and sequence %d in row %zu." ),
1505  id,
1506  seq,
1507  rownum );
1508  }
1509  }
1510  }
1511 
1512  return rownum - aRow;
1513 }
std::vector< std::string > single_row
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > traces
GRAPHIC_ITEM * processGraphic(const GRAPHIC_DATA &aData, double aScale)
Specialty functions for processing graphical data rows into the internal database.
#define _(s)
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > zones
int getColFromName(size_t aRow, const std::string &aStr)
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > refdes
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, getColFromName(), FABMASTER::GRAPHIC_DATA::graphic_data1, FABMASTER::GRAPHIC_DATA::graphic_data2, FABMASTER::GRAPHIC_DATA::graphic_data3, FABMASTER::GRAPHIC_DATA::graphic_data4, FABMASTER::GRAPHIC_DATA::graphic_data5, FABMASTER::GRAPHIC_DATA::graphic_data6, FABMASTER::GRAPHIC_DATA::graphic_data7, FABMASTER::GRAPHIC_DATA::graphic_data8, FABMASTER::GRAPHIC_DATA::graphic_data9, FABMASTER::GRAPHIC_DATA::graphic_dataname, FABMASTER::GRAPHIC_DATA::graphic_datanum, processGraphic(), processScaleFactor(), refdes, rows, traces, and zones.

Referenced by Process().

◆ processVias()

size_t FABMASTER::processVias ( size_t  aRow)
private

A!VIA_X!VIA_Y!PAD_STACK_NAME!NET_NAME!TEST_POINT!

Definition at line 1323 of file import_fabmaster.cpp.

1324 {
1325  size_t rownum = aRow + 2;
1326 
1327  if( rownum >= rows.size() )
1328  return -1;
1329 
1330  const single_row& header = rows[aRow];
1331  double scale_factor = processScaleFactor( aRow + 1 );
1332 
1333  if( scale_factor <= 0.0 )
1334  return -1;
1335 
1336  int viax_col = getColFromName( aRow, "VIAX" );
1337  int viay_col = getColFromName( aRow, "VIAY" );
1338  int padstack_name_col = getColFromName( aRow, "PADSTACKNAME" );
1339  int net_name_col = getColFromName( aRow, "NETNAME" );
1340  int test_point_col = getColFromName( aRow, "TESTPOINT" );
1341 
1342  if( viax_col < 0 || viay_col < 0 || padstack_name_col < 0 || net_name_col < 0
1343  || test_point_col < 0 )
1344  return -1;
1345 
1346  for( ; rownum < rows.size() && rows[rownum].size() > 0 && rows[rownum][0] == "S"; ++rownum )
1347  {
1348  const single_row& row = rows[rownum];
1349 
1350  if( row.size() != header.size() )
1351  {
1352  wxLogError( _( "Invalid row size in row %zu. Expecting %zu elements but found %zu." ),
1353  rownum,
1354  header.size(),
1355  row.size() );
1356  continue;
1357  }
1358 
1359  vias.emplace_back( std::make_unique<FM_VIA>() );
1360  auto& via = vias.back();
1361 
1362  via->x = KiROUND( readDouble( row[viax_col] ) * scale_factor );
1363  via->y = -KiROUND( readDouble( row[viay_col] ) * scale_factor );
1364  via->padstack = row[padstack_name_col];
1365  via->net = row[net_name_col];
1366  via->test_point = ( row[test_point_col] == "YES" );
1367  }
1368 
1369  return rownum - aRow;
1370 }
std::vector< std::string > single_row
double readDouble(const std::string &aStr) const
Reads the double/integer value from a std string independent of the user locale.
std::vector< std::unique_ptr< FM_VIA > > vias
#define _(s)
int getColFromName(size_t aRow, const std::string &aStr)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
double processScaleFactor(size_t aRow)
Processes data from text vectors into internal database for further ordering.
std::deque< single_row > rows

References _, getColFromName(), KiROUND(), processScaleFactor(), readDouble(), rows, via, and vias.

Referenced by Process().

◆ Read()

bool FABMASTER::Read ( const std::string &  aFile)

Rows end with "!" and we don't want to keep the empty cell

Definition at line 103 of file import_fabmaster.cpp.

104 {
105 
106  std::ifstream ifs( aFile, std::ios::in | std::ios::binary );
107 
108  if( !ifs.is_open() )
109  return false;
110 
111  m_filename = aFile;
112 
113  // Read/ignore all bytes in the file to find the size and then go back to the beginning
114  ifs.ignore( std::numeric_limits<std::streamsize>::max() );
115  std::streamsize length = ifs.gcount();
116  ifs.clear();
117  ifs.seekg( 0, std::ios_base::beg );
118 
119  std::string buffer( std::istreambuf_iterator<char>{ ifs }, {} );
120 
121  std::vector < std::string > row;
122 
123  // Reserve an estimate of the number of rows to prevent continual re-allocation
124  // crashing (Looking at you MSVC)
125  row.reserve( length / 100 );
126  std::string cell;
127  cell.reserve( 100 );
128 
129  bool quoted = false;
130 
131  for( auto ch : buffer )
132  {
133  switch( ch )
134  {
135  case '"':
136 
137  if( cell.empty() || cell[0] == '"' )
138  quoted = !quoted;
139 
140  cell += ch;
141  break;
142 
143  case '!':
144  if( !quoted )
145  {
146  row.push_back( cell );
147  cell.clear();
148  }
149  else
150  cell += ch;
151 
152  break;
153 
154  case '\n':
155 
157  if( !cell.empty() )
158  row.push_back( cell );
159 
160  cell.clear();
161  rows.push_back( row );
162  row.clear();
163  quoted = false;
164  break;
165 
166  case '\r':
167  break;
168 
169  default:
170  cell += std::toupper( ch );
171  }
172  }
173 
174  // Handle last line without linebreak
175  if( !cell.empty() || !row.empty() )
176  {
177  row.push_back( cell );
178  cell.clear();
179  rows.push_back( row );
180  row.clear();
181  }
182 
183  return true;
184 }
wxFileName m_filename
std::deque< single_row > rows

References m_filename, and rows.

Referenced by FABMASTER_PLUGIN::Load().

◆ readDouble()

double FABMASTER::readDouble ( const std::string &  aStr) const
private

Reads the double/integer value from a std string independent of the user locale.

Parameters
aStrstring to generate value from
Returns
0 if value cannot be created

Definition at line 81 of file import_fabmaster.cpp.

82 {
83  std::istringstream istr( aStr );
84  istr.imbue( std::locale::classic() );
85 
86  double doubleValue;
87  istr >> doubleValue;
88  return doubleValue;
89 }

Referenced by processArc(), processFootprints(), processLine(), processPadStacks(), processPins(), processRectangle(), processText(), and processVias().

◆ readInt()

int FABMASTER::readInt ( const std::string &  aStr) const
private

Definition at line 92 of file import_fabmaster.cpp.

93 {
94  std::istringstream istr( aStr );
95  istr.imbue( std::locale::classic() );
96 
97  int intValue;
98  istr >> intValue;
99  return intValue;
100 }

Referenced by processPadStackLayers().

Member Data Documentation

◆ board_graphics

std::vector<GEOM_GRAPHIC> FABMASTER::board_graphics
private

Definition at line 400 of file import_fabmaster.h.

Referenced by LoadBoard(), loadGraphics(), and processGeometry().

◆ comp_graphics

std::map<std::string, std::map<int, GEOM_GRAPHIC> > FABMASTER::comp_graphics
private

Definition at line 401 of file import_fabmaster.h.

Referenced by loadFootprints(), and processGeometry().

◆ components

std::map<std::string, std::vector<std::unique_ptr<COMPONENT> > > FABMASTER::components
private

Definition at line 477 of file import_fabmaster.h.

Referenced by LoadBoard(), loadFootprints(), and processFootprints().

◆ has_comps

bool FABMASTER::has_comps
private

Definition at line 97 of file import_fabmaster.h.

◆ has_graphic

bool FABMASTER::has_graphic
private

Definition at line 98 of file import_fabmaster.h.

◆ has_nets

bool FABMASTER::has_nets
private

Definition at line 99 of file import_fabmaster.h.

◆ has_pads

bool FABMASTER::has_pads
private

Definition at line 96 of file import_fabmaster.h.

◆ has_pins

bool FABMASTER::has_pins
private

Definition at line 100 of file import_fabmaster.h.

◆ layer_map

std::map<std::string, PCB_LAYER_ID> FABMASTER::layer_map
private

Definition at line 506 of file import_fabmaster.h.

◆ layers

std::map<std::string, FABMASTER_LAYER> FABMASTER::layers
private

◆ m_doneCount

unsigned FABMASTER::m_doneCount
private

Definition at line 588 of file import_fabmaster.h.

Referenced by checkpoint(), and LoadBoard().

◆ m_filename

wxFileName FABMASTER::m_filename
private

Definition at line 76 of file import_fabmaster.h.

Referenced by LoadBoard(), loadFootprints(), and Read().

◆ m_lastProgressCount

unsigned FABMASTER::m_lastProgressCount
private

Definition at line 589 of file import_fabmaster.h.

Referenced by checkpoint().

◆ m_progressReporter

PROGRESS_REPORTER* FABMASTER::m_progressReporter
private

optional; may be nullptr

Definition at line 587 of file import_fabmaster.h.

Referenced by checkpoint(), and LoadBoard().

◆ m_totalCount

unsigned FABMASTER::m_totalCount
private

for progress reporting

Definition at line 590 of file import_fabmaster.h.

Referenced by checkpoint(), and LoadBoard().

◆ netnames

std::set<std::string> FABMASTER::netnames
private

Definition at line 180 of file import_fabmaster.h.

Referenced by LoadBoard(), loadNets(), and processNets().

◆ pad_shapes

std::unordered_map<std::string, FABMASTER_PAD_SHAPE> FABMASTER::pad_shapes
private

Definition at line 332 of file import_fabmaster.h.

Referenced by loadFootprints(), and processCustomPads().

◆ pads

std::unordered_map<std::string, FM_PAD> FABMASTER::pads
private

Definition at line 138 of file import_fabmaster.h.

Referenced by loadFootprints(), loadVias(), and processPadStacks().

◆ pin_nets

std::map<std::pair<std::string, std::string>, NETNAME> FABMASTER::pin_nets
private

Definition at line 179 of file import_fabmaster.h.

Referenced by loadFootprints(), and processNets().

◆ pins

std::map<std::string, std::set<std::unique_ptr<PIN>, PIN::BY_NUM> > FABMASTER::pins
private

Definition at line 504 of file import_fabmaster.h.

Referenced by loadFootprints(), and processPins().

◆ polygons

std::set<std::unique_ptr<TRACE>, TRACE::BY_ID> FABMASTER::polygons
private

Definition at line 442 of file import_fabmaster.h.

◆ refdes

std::set<std::unique_ptr<TRACE>, TRACE::BY_ID> FABMASTER::refdes
private

Definition at line 444 of file import_fabmaster.h.

Referenced by loadFootprints(), and processTraces().

◆ rows

◆ symbols

std::unordered_map<std::string, SYMBOL> FABMASTER::symbols
private

Definition at line 375 of file import_fabmaster.h.

◆ traces

std::set<std::unique_ptr<TRACE>, TRACE::BY_ID> FABMASTER::traces
private

Definition at line 438 of file import_fabmaster.h.

Referenced by LoadBoard(), and processTraces().

◆ vias

std::vector<std::unique_ptr<FM_VIA> > FABMASTER::vias
private

Definition at line 415 of file import_fabmaster.h.

Referenced by LoadBoard(), loadVias(), and processVias().

◆ zones

std::set<std::unique_ptr<TRACE>, TRACE::BY_ID> FABMASTER::zones
private

Definition at line 440 of file import_fabmaster.h.

Referenced by LoadBoard(), loadZones(), orderZones(), and processTraces().


The documentation for this class was generated from the following files: