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 49 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 278 of file import_fabmaster.h.

◆ single_row

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

Definition at line 53 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 139 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 188 of file import_fabmaster.h.

189 {
195 };
@ GR_SHAPE_CIRCLE
! Not actually in Fabmaster but we use for 360° arcs

◆ GRAPHIC_TYPE

Enumerator
GR_TYPE_NONE 
GR_TYPE_CONNECT 
GR_TYPE_NOTCONNECT 
GR_TYPE_SHAPE 
GR_TYPE_POLYGON 
GR_TYPE_VOID 

Definition at line 197 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 77 of file import_fabmaster.h.

◆ SYMTYPE

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

Definition at line 147 of file import_fabmaster.h.

Constructor & Destructor Documentation

◆ FABMASTER()

FABMASTER::FABMASTER ( )
inline

Definition at line 54 of file import_fabmaster.h.

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

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 710 of file import_fabmaster.cpp.

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

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 60 of file import_fabmaster.cpp.

61{
62 const unsigned PROGRESS_DELTA = 250;
63
65 {
66 if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA )
67 {
69 / std::max( 1U, m_totalCount ) );
70
72 THROW_IO_ERROR( _( "Open cancelled by user." ) );
73
75 }
76 }
77}
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
#define _(s)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

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 185 of file import_fabmaster.cpp.

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

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 297 of file import_fabmaster.cpp.

298{
299 if( aRow >= rows.size() )
300 return -1;
301
302 std::vector<std::string> header = rows[aRow];
303
304 for( size_t i = 0; i < header.size(); i++ )
305 {
308 alg::delete_if( header[i], []( const char c ) { return c == '_'; } );
309
310 if( header[i] == aStr )
311 return i;
312 }
313
314 THROW_IO_ERROR( wxString::Format( _( "Could not find column label %s." ), aStr.c_str() ) );
315 return -1;
316}
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

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 319 of file import_fabmaster.cpp.

320{
321 const auto& kicad_layer = layers.find( aLayerName);
322
323 if( kicad_layer == layers.end() )
324 return UNDEFINED_LAYER;
325 else
326 return static_cast<PCB_LAYER_ID>( kicad_layer->second.layerid );
327}
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ UNDEFINED_LAYER
Definition: layer_ids.h:60

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 3039 of file import_fabmaster.cpp.

3040{
3041 aBoard->SetFileName( m_filename.GetFullPath() );
3042 m_progressReporter = aProgressReporter;
3043
3044 m_totalCount = netnames.size()
3045 + layers.size()
3046 + vias.size()
3047 + components.size()
3048 + zones.size()
3049 + board_graphics.size()
3050 + traces.size();
3051 m_doneCount = 0;
3052
3053 loadNets( aBoard );
3054 loadLayers( aBoard );
3055 loadVias( aBoard );
3056 loadFootprints( aBoard );
3057 loadZones( aBoard );
3058 loadGraphics( aBoard );
3059
3060 for( auto& track : traces )
3061 {
3062 checkpoint();
3063
3064 if( track->lclass == "ETCH" )
3065 loadEtch( aBoard, track);
3066 else if( track->layer == "OUTLINE" )
3067 loadOutline( aBoard, track );
3068 }
3069
3070 orderZones( aBoard );
3071
3072 return true;
3073}
void SetFileName(const wxString &aFileName)
Definition: board.h:300
wxFileName m_filename
bool loadNets(BOARD *aBoard)
bool loadLayers(BOARD *aBoard)
bool loadZones(BOARD *aBoard)
Loads sections of the database into the board.
bool loadFootprints(BOARD *aBoard)
bool loadVias(BOARD *aBoard)
bool loadEtch(BOARD *aBoard, const std::unique_ptr< TRACE > &aLine)
bool loadOutline(BOARD *aBoard, const std::unique_ptr< TRACE > &aLine)
std::vector< GEOM_GRAPHIC > board_graphics
bool loadGraphics(BOARD *aBoard)
std::vector< std::unique_ptr< FM_VIA > > vias
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > traces
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > zones
std::map< std::string, std::vector< std::unique_ptr< COMPONENT > > > components
std::set< std::string > netnames
bool orderZones(BOARD *aBoard)
Sets zone priorities based on zone BB size.

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 2531 of file import_fabmaster.cpp.

2532{
2533 const NETNAMES_MAP& netinfo = aBoard->GetNetInfo().NetsByName();
2534 auto net_it = netinfo.find( aLine->netname );
2535
2536 int last_subseq = 0;
2537 ZONE* new_zone = nullptr;
2538
2539 for( const auto& seg : aLine->segment )
2540 {
2541 PCB_LAYER_ID layer = getLayer( seg->layer );
2542
2543 if( IsCopperLayer( layer ) )
2544 {
2545 if( seg->shape == GR_SHAPE_LINE )
2546 {
2547 const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2548
2549 PCB_TRACK* trk = new PCB_TRACK( aBoard );
2550
2551 trk->SetLayer( layer );
2552 trk->SetStart( wxPoint( src->start_x, src->start_y ) );
2553 trk->SetEnd( wxPoint( src->end_x, src->end_y ) );
2554 trk->SetWidth( src->width );
2555
2556 if( net_it != netinfo.end() )
2557 trk->SetNet( net_it->second );
2558
2559 aBoard->Add( trk, ADD_MODE::APPEND );
2560 }
2561 else if( seg->shape == GR_SHAPE_ARC )
2562 {
2563 const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2564
2565 PCB_ARC* trk = new PCB_ARC( aBoard, &src->result );
2566 trk->SetLayer( layer );
2567 trk->SetWidth( src->width );
2568
2569 if( net_it != netinfo.end() )
2570 trk->SetNet( net_it->second );
2571
2572 aBoard->Add( trk, ADD_MODE::APPEND );
2573 }
2574 }
2575 else
2576 {
2577 wxLogError( _( "Expecting etch data to be on copper layer. Row found on layer '%s'" ),
2578 seg->layer.c_str() );
2579 }
2580 }
2581
2582 return true;
2583}
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:201
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:763
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:686
PCB_LAYER_ID getLayer(const std::string &aLayerName)
const NETNAMES_MAP & NetsByName() const
Return the name map, at least for python.
Definition: netinfo.h:366
void SetWidth(int aWidth)
Definition: pcb_track.h:104
void SetEnd(const VECTOR2I &aEnd)
Definition: pcb_track.h:107
void SetStart(const VECTOR2I &aStart)
Definition: pcb_track.h:110
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:823

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, PCB_TRACK::SetEnd(), BOARD_ITEM::SetLayer(), BOARD_CONNECTED_ITEM::SetNet(), PCB_TRACK::SetStart(), PCB_TRACK::SetWidth(), 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

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 STROKE_PARAMS defaultStroke( ds.GetLineThickness( layer ) );
2087
2088 switch( seg->shape )
2089 {
2090
2091 case GR_SHAPE_LINE:
2092 {
2093 const GRAPHIC_LINE* lsrc = static_cast<const GRAPHIC_LINE*>( seg.get() );
2094
2095 FP_SHAPE* line = new FP_SHAPE( fp, SHAPE_T::SEGMENT );
2096
2097 if( src->mirror )
2098 {
2099 line->SetLayer( FlipLayer( layer ) );
2100 line->SetStart( wxPoint( lsrc->start_x, 2 * src->y - lsrc->start_y ) );
2101 line->SetEnd( wxPoint( lsrc->end_x, 2 * src->y - lsrc->end_y ) );
2102 }
2103 else
2104 {
2105 line->SetLayer( layer );
2106 line->SetStart( wxPoint( lsrc->start_x, lsrc->start_y ) );
2107 line->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
2108 }
2109
2110 line->SetStroke( STROKE_PARAMS( lsrc->width, PLOT_DASH_TYPE::SOLID ) );
2111 line->SetLocalCoord();
2112
2113 if( lsrc->width == 0 )
2114 line->SetStroke( defaultStroke );
2115
2116 fp->Add( line, ADD_MODE::APPEND );
2117 break;
2118 }
2119 case GR_SHAPE_CIRCLE:
2120 {
2121 const GRAPHIC_ARC* lsrc = static_cast<const GRAPHIC_ARC*>( seg.get() );
2122
2123 FP_SHAPE* circle = new FP_SHAPE( fp, SHAPE_T::CIRCLE );
2124
2125 circle->SetLayer( layer );
2126 circle->SetCenter( wxPoint( lsrc->center_x, lsrc->center_y ) );
2127 circle->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
2128 circle->SetWidth( lsrc->width );
2129 circle->SetLocalCoord();
2130
2131 if( lsrc->width == 0 )
2132 circle->SetWidth( ds.GetLineThickness( circle->GetLayer() ) );
2133
2134 if( src->mirror )
2135 circle->Flip( circle->GetCenter(), false );
2136
2137 fp->Add( circle, ADD_MODE::APPEND );
2138 break;
2139 }
2140 case GR_SHAPE_ARC:
2141 {
2142 const GRAPHIC_ARC* lsrc = static_cast<const GRAPHIC_ARC*>( seg.get() );
2143
2144 FP_SHAPE* arc = new FP_SHAPE( fp, SHAPE_T::ARC );
2145
2146 arc->SetLayer( layer );
2147 arc->SetArcGeometry( lsrc->result.GetP0(),
2148 lsrc->result.GetArcMid(),
2149 lsrc->result.GetP1() );
2150 arc->SetStroke( STROKE_PARAMS( lsrc->width, PLOT_DASH_TYPE::SOLID ) );
2151 arc->SetLocalCoord();
2152
2153 if( lsrc->width == 0 )
2154 arc->SetStroke( defaultStroke );
2155
2156 if( src->mirror )
2157 arc->Flip( arc->GetCenter(), false );
2158
2159 fp->Add( arc, ADD_MODE::APPEND );
2160 break;
2161 }
2162 case GR_SHAPE_RECTANGLE:
2163 {
2164 const GRAPHIC_RECTANGLE *lsrc =
2165 static_cast<const GRAPHIC_RECTANGLE*>( seg.get() );
2166
2167 FP_SHAPE* rect = new FP_SHAPE( fp, SHAPE_T::RECT );
2168
2169 if( src->mirror )
2170 {
2171 rect->SetLayer( FlipLayer( layer ) );
2172 rect->SetStart( wxPoint( lsrc->start_x, 2 * src->y - lsrc->start_y ) );
2173 rect->SetEnd( wxPoint( lsrc->end_x, 2 * src->y - lsrc->end_y ) );
2174 }
2175 else
2176 {
2177 rect->SetLayer( layer );
2178 rect->SetStart( wxPoint( lsrc->start_x, lsrc->start_y ) );
2179 rect->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
2180 }
2181
2182 rect->SetStroke( defaultStroke );
2183 rect->SetLocalCoord();
2184
2185 fp->Add( rect, ADD_MODE::APPEND );
2186 break;
2187 }
2188 case GR_SHAPE_TEXT:
2189 {
2190 const GRAPHIC_TEXT *lsrc =
2191 static_cast<const GRAPHIC_TEXT*>( seg.get() );
2192
2193 FP_TEXT* txt = new FP_TEXT( fp );
2194
2195 if( src->mirror )
2196 {
2197 txt->SetLayer( FlipLayer( layer ) );
2198 txt->SetTextPos( wxPoint( lsrc->start_x, 2 * src->y - ( lsrc->start_y - lsrc->height / 2 ) ) );
2199 }
2200 else
2201 {
2202 txt->SetLayer( layer );
2203 txt->SetTextPos( wxPoint( lsrc->start_x, lsrc->start_y - lsrc->height / 2 ) );
2204 }
2205
2206 txt->SetText( lsrc->text );
2207 txt->SetItalic( lsrc->ital );
2208 txt->SetTextThickness( lsrc->thickness );
2209 txt->SetTextHeight( lsrc->height );
2210 txt->SetTextWidth( lsrc->width );
2211 txt->SetHorizJustify( lsrc->orient );
2212 txt->SetLocalCoord();
2213
2214 // FABMASTER doesn't have visibility flags but layers that are not silk should be hidden
2215 // by default to prevent clutter.
2216 if( txt->GetLayer() != F_SilkS && txt->GetLayer() != B_SilkS )
2217 txt->SetVisible( false );
2218
2219 fp->Add( txt, ADD_MODE::APPEND );
2220 break;
2221 }
2222 default:
2223 continue;
2224 }
2225 }
2226 }
2227
2228 auto pin_it = pins.find( src->refdes );
2229
2230 if( pin_it != pins.end() )
2231 {
2232 for( auto& pin : pin_it->second )
2233 {
2234 auto pin_net_it = pin_nets.find( std::make_pair( pin->refdes, pin->pin_number ) );
2235 auto padstack = pads.find( pin->padstack );
2236 std::string netname = "";
2237
2238 if( pin_net_it != pin_nets.end() )
2239 netname = pin_net_it->second.name;
2240
2241 auto net_it = netinfo.find( netname );
2242
2243 std::unique_ptr<PAD> newpad = std::make_unique<PAD>( fp );
2244
2245 if( net_it != netinfo.end() )
2246 newpad->SetNet( net_it->second );
2247 else
2248 newpad->SetNetCode( 0 );
2249
2250 newpad->SetX( pin->pin_x );
2251
2252 if( src->mirror )
2253 newpad->SetY( 2 * src->y - pin->pin_y );
2254 else
2255 newpad->SetY( pin->pin_y );
2256
2257 newpad->SetNumber( pin->pin_number );
2258
2259 if( padstack == pads.end() )
2260 {
2261 wxLogError( _( "Unable to locate padstack %s in file %s\n" ),
2262 pin->padstack.c_str(), aBoard->GetFileName().wc_str() );
2263 continue;
2264 }
2265 else
2266 {
2267 auto& pad = padstack->second;
2268
2269 newpad->SetShape( pad.shape );
2270
2271 if( pad.shape == PAD_SHAPE::CUSTOM )
2272 {
2273 // Choose the smaller dimension to ensure the base pad
2274 // is fully hidden by the custom pad
2275 int pad_size = std::min( pad.width, pad.height );
2276
2277 newpad->SetSize( wxSize( pad_size / 2, pad_size / 2 ) );
2278
2279 std::string custom_name = pad.custom_name + "_" + pin->refdes + "_" + pin->pin_number;
2280 auto custom_it = pad_shapes.find( custom_name );
2281
2282 if( custom_it != pad_shapes.end() )
2283 {
2284
2285 SHAPE_POLY_SET poly_outline;
2286 int last_subseq = 0;
2287 int hole_idx = -1;
2288
2289 poly_outline.NewOutline();
2290
2291 // Custom pad shapes have a group of elements
2292 // that are a list of graphical polygons
2293 for( const auto& el : (*custom_it).second.elements )
2294 {
2295 // For now, we are only processing the custom pad for the top layer
2296 // TODO: Use full padstacks when implementing in KiCad
2297 PCB_LAYER_ID primary_layer = src->mirror ? B_Cu : F_Cu;
2298
2299 if( getLayer( ( *( el.second.begin() ) )->layer ) != primary_layer )
2300 continue;
2301
2302 for( const auto& seg : el.second )
2303 {
2304 if( seg->subseq > 0 || seg->subseq != last_subseq )
2305 {
2306 poly_outline.Polygon(0).back().SetClosed( true );
2307 hole_idx = poly_outline.AddHole( SHAPE_LINE_CHAIN{} );
2308 }
2309
2310 if( seg->shape == GR_SHAPE_LINE )
2311 {
2312 const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2313
2314 if( poly_outline.VertexCount( 0, hole_idx ) == 0 )
2315 poly_outline.Append( src->start_x, src->start_y, 0, hole_idx );
2316
2317 poly_outline.Append( src->end_x, src->end_y, 0, hole_idx );
2318 }
2319 else if( seg->shape == GR_SHAPE_ARC )
2320 {
2321 const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2322 SHAPE_LINE_CHAIN& chain = poly_outline.Hole( 0, hole_idx );
2323
2324 chain.Append( src->result );
2325 }
2326 }
2327 }
2328
2329 if( poly_outline.OutlineCount() < 1
2330 || poly_outline.Outline( 0 ).PointCount() < 3 )
2331 {
2332 wxLogError( _( "Invalid custom pad '%s'. Replacing with "
2333 "circular pad." ),
2334 custom_name.c_str() );
2335 newpad->SetShape( PAD_SHAPE::CIRCLE );
2336 }
2337 else
2338 {
2339 poly_outline.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
2340
2341 poly_outline.Move( -newpad->GetPosition() );
2342
2343 if( src->mirror )
2344 {
2345 poly_outline.Mirror( false, true, VECTOR2I( 0, ( pin->pin_y - src->y ) ) );
2346 poly_outline.Rotate( EDA_ANGLE( src->rotate - pin->rotation, DEGREES_T ) );
2347 }
2348 else
2349 {
2350 poly_outline.Rotate( EDA_ANGLE( -src->rotate + pin->rotation, DEGREES_T ) );
2351 }
2352
2353 newpad->AddPrimitivePoly( poly_outline, 0, true );
2354 }
2355
2356 SHAPE_POLY_SET mergedPolygon;
2357 newpad->MergePrimitivesAsPolygon( &mergedPolygon );
2358
2359 if( mergedPolygon.OutlineCount() > 1 )
2360 {
2361 wxLogError( _( "Invalid custom pad '%s'. Replacing with "
2362 "circular pad." ),
2363 custom_name.c_str() );
2364 newpad->SetShape( PAD_SHAPE::CIRCLE );
2365 }
2366 }
2367 else
2368 {
2369 wxLogError( _( "Could not find custom pad '%s'." ),
2370 custom_name.c_str() );
2371 }
2372 }
2373 else
2374 newpad->SetSize( wxSize( pad.width, pad.height ) );
2375
2376 if( pad.drill )
2377 {
2378 if( pad.plated )
2379 {
2380 newpad->SetAttribute( PAD_ATTRIB::PTH );
2381 newpad->SetLayerSet( PAD::PTHMask() );
2382 }
2383 else
2384 {
2385 newpad->SetAttribute( PAD_ATTRIB::NPTH );
2386 newpad->SetLayerSet( PAD::UnplatedHoleMask() );
2387 }
2388
2389 if( pad.drill_size_x == pad.drill_size_y )
2390 newpad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
2391 else
2392 newpad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );
2393
2394 newpad->SetDrillSize( wxSize( pad.drill_size_x, pad.drill_size_y ) );
2395 }
2396 else
2397 {
2398 newpad->SetAttribute( PAD_ATTRIB::SMD );
2399
2400 if( pad.top )
2401 newpad->SetLayerSet( PAD::SMDMask() );
2402 else if( pad.bottom )
2403 newpad->SetLayerSet( FlipLayerMask( PAD::SMDMask() ) );
2404 }
2405 }
2406
2407 newpad->SetLocalCoord();
2408
2409 if( src->mirror )
2410 newpad->SetOrientation( EDA_ANGLE( -src->rotate + pin->rotation, DEGREES_T ) );
2411 else
2412 newpad->SetOrientation( EDA_ANGLE( src->rotate - pin->rotation, DEGREES_T ) );
2413
2414 if( newpad->GetSizeX() > 0 || newpad->GetSizeY() > 0 )
2415 {
2416 fp->Add( newpad.release(), ADD_MODE::APPEND );
2417 }
2418 else
2419 {
2420 wxLogError( _( "Invalid zero-sized pad ignored in\nfile: %s" ),
2421 aBoard->GetFileName().wc_str() );
2422 }
2423 }
2424 }
2425
2426 if( src->mirror )
2427 {
2428 fp->SetOrientationDegrees( 180.0 - src->rotate );
2429 fp->Flip( fp->GetPosition(), true );
2430 }
2431
2432 aBoard->Add( fp, ADD_MODE::APPEND );
2433 }
2434 }
2435
2436 return true;
2437}
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:167
const wxString & GetFileName() const
Definition: board.h:302
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:618
void SetCenter(const VECTOR2I &aCenter)
Definition: eda_shape.cpp:423
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:120
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:145
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
Definition: eda_shape.cpp:508
void SetWidth(int aWidth)
Definition: eda_shape.h:106
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:371
void SetTextWidth(int aWidth)
Definition: eda_text.cpp:355
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:217
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:185
void SetTextHeight(int aHeight)
Definition: eda_text.cpp:363
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:163
void SetItalic(bool aItalic)
Definition: eda_text.cpp:201
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:240
std::map< std::string, std::map< int, GEOM_GRAPHIC > > comp_graphics
std::unordered_map< std::string, FM_PAD > pads
std::map< std::string, std::set< std::unique_ptr< PIN >, PIN::BY_NUM > > pins
std::map< std::pair< std::string, std::string >, NETNAME > pin_nets
std::unordered_map< std::string, FABMASTER_PAD_SHAPE > pad_shapes
std::set< std::unique_ptr< TRACE >, TRACE::BY_ID > refdes
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:1636
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:208
void SetOrientationDegrees(double aOrientation)
Definition: footprint.h:198
void SetReference(const wxString &aReference)
Definition: footprint.h:528
void SetValue(const wxString &aValue)
Definition: footprint.h:549
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:555
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: footprint.cpp:549
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: footprint.cpp:1553
VECTOR2I GetPosition() const override
Definition: footprint.h:192
FP_TEXT & Reference()
Definition: footprint.h:556
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip entity relative to aCentre.
Definition: fp_shape.cpp:219
virtual void SetLocalCoord()
Set relative coordinates from draw coordinates.
Definition: fp_shape.cpp:52
void SetLocalCoord()
Definition: fp_text.cpp:217
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:50
static LSET PTHMask()
layer set for a through hole pad
Definition: pad.cpp:174
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: pad.cpp:195
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: pad.cpp:181
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:65
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:70
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
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.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
int VertexCount(int aOutline=-1, int aHole=-1) const
Return the number of points in the shape poly set.
POLYGON & Polygon(int aIndex)
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...
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
SHAPE_LINE_CHAIN & Outline(int aIndex)
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
int NewOutline()
Creates a new hole in a given outline.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void Move(const VECTOR2I &aVector) override
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
@ DEGREES_T
Definition: eda_angle.h:31
bool IsPcbLayer(int aLayer)
Test whether a layer is a valid layer for Pcbnew.
Definition: layer_ids.h:812
@ F_Cu
Definition: layer_ids.h:64
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint.
Definition: lset.cpp:590
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:544
@ NPTH
like PAD_PTH, but not plated
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ PAD_DRILL_SHAPE_CIRCLE
Definition: pad_shapes.h:70
@ PAD_DRILL_SHAPE_OBLONG
Definition: pad_shapes.h:71
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References _, BOARD::Add(), FOOTPRINT::Add(), SHAPE_POLY_SET::AddHole(), SHAPE_LINE_CHAIN::Append(), SHAPE_POLY_SET::Append(), APPEND, ARC, B_Cu, B_SilkS, FABMASTER::GRAPHIC_ARC::center_x, FABMASTER::GRAPHIC_ARC::center_y, checkpoint(), CIRCLE, comp_graphics, components, CUSTOM, DEGREES_T, 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(), FP_SHAPE::Flip(), FlipLayer(), FlipLayerMask(), Format(), SHAPE_POLY_SET::Fracture(), SHAPE_ARC::GetArcMid(), PCB_SHAPE::GetCenter(), BOARD::GetDesignSettings(), BOARD::GetFileName(), BOARD_ITEM::GetLayer(), getLayer(), BOARD::GetNetInfo(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), 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, 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_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, EDA_SHAPE::SetArcGeometry(), EDA_SHAPE::SetCenter(), EDA_SHAPE::SetEnd(), FOOTPRINT::SetFPID(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetItalic(), BOARD_ITEM::SetLayer(), FP_SHAPE::SetLocalCoord(), FP_TEXT::SetLocalCoord(), FOOTPRINT::SetOrientationDegrees(), FOOTPRINT::SetPosition(), FOOTPRINT::SetReference(), EDA_SHAPE::SetStart(), PCB_SHAPE::SetStroke(), EDA_TEXT::SetText(), EDA_TEXT::SetTextHeight(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetTextWidth(), FOOTPRINT::SetValue(), EDA_TEXT::SetVisible(), EDA_SHAPE::SetWidth(), SMD, PAD::SMDMask(), SOLID, 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 2877 of file import_fabmaster.cpp.

2878{
2879
2880 for( auto& geom : board_graphics )
2881 {
2882 checkpoint();
2883
2884 PCB_LAYER_ID layer;
2885
2886 // The pin numbers are not useful for us outside of the footprints
2887 if( geom.subclass == "PIN_NUMBER" )
2888 continue;
2889
2890 layer = getLayer( geom.subclass );
2891
2892 if( !IsPcbLayer( layer ) )
2893 layer = Cmts_User;
2894
2895 if( !geom.elements->empty() )
2896 {
2898 if( ( *( geom.elements->begin() ) )->width == 0 )
2899 {
2900 SHAPE_POLY_SET poly_outline = loadShapePolySet( *( geom.elements ) );
2901
2902 if( poly_outline.OutlineCount() < 1 || poly_outline.COutline( 0 ).PointCount() < 3 )
2903 continue;
2904
2905 PCB_SHAPE* new_poly = new PCB_SHAPE( aBoard, SHAPE_T::POLY );
2906 new_poly->SetLayer( layer );
2907 new_poly->SetPolyShape( poly_outline );
2908 new_poly->SetStroke( STROKE_PARAMS( 0 ) );
2909
2910 if( layer == F_SilkS || layer == B_SilkS )
2911 new_poly->SetFilled( true );
2912
2913 aBoard->Add( new_poly, ADD_MODE::APPEND );
2914 }
2915 }
2916
2917 for( auto& seg : *geom.elements )
2918 {
2919 switch( seg->shape )
2920 {
2921
2922 case GR_SHAPE_LINE:
2923 {
2924 const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2925
2926 PCB_SHAPE* line = new PCB_SHAPE( aBoard, SHAPE_T::SEGMENT );
2927 line->SetLayer( layer );
2928 line->SetStart( wxPoint( src->start_x, src->start_y ) );
2929 line->SetEnd( wxPoint( src->end_x, src->end_y ) );
2930 line->SetStroke( STROKE_PARAMS( src->width, PLOT_DASH_TYPE::SOLID ) );
2931
2932 aBoard->Add( line, ADD_MODE::APPEND );
2933 break;
2934 }
2935 case GR_SHAPE_CIRCLE:
2936 {
2937 const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2938
2939 PCB_SHAPE* circle = new PCB_SHAPE( aBoard, SHAPE_T::CIRCLE );
2940
2941 circle->SetLayer( layer );
2942 circle->SetCenter( wxPoint( src->center_x, src->center_y ) );
2943 circle->SetEnd( wxPoint( src->end_x, src->end_y ) );
2944 circle->SetWidth( src->width );
2945
2946 aBoard->Add( circle, ADD_MODE::APPEND );
2947 break;
2948 }
2949 case GR_SHAPE_ARC:
2950 {
2951 const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2952
2953 PCB_SHAPE* arc = new PCB_SHAPE( aBoard, SHAPE_T::ARC );
2954 arc->SetLayer( layer );
2955 arc->SetArcGeometry( src->result.GetP0(),
2956 src->result.GetArcMid(),
2957 src->result.GetP1() );
2958 arc->SetStroke( STROKE_PARAMS( src->width, PLOT_DASH_TYPE::SOLID ) );
2959
2960 aBoard->Add( arc, ADD_MODE::APPEND );
2961 break;
2962 }
2963 case GR_SHAPE_RECTANGLE:
2964 {
2965 const GRAPHIC_RECTANGLE *src =
2966 static_cast<const GRAPHIC_RECTANGLE*>( seg.get() );
2967
2968 PCB_SHAPE* rect = new PCB_SHAPE( aBoard, SHAPE_T::RECT );
2969 rect->SetLayer( layer );
2970 rect->SetStart( wxPoint( src->start_x, src->start_y ) );
2971 rect->SetEnd( wxPoint( src->end_x, src->end_y ) );
2972 rect->SetStroke( STROKE_PARAMS( 0 ) );
2973 rect->SetFilled( true );
2974 aBoard->Add( rect, ADD_MODE::APPEND );
2975 break;
2976 }
2977 case GR_SHAPE_TEXT:
2978 {
2979 const GRAPHIC_TEXT *src =
2980 static_cast<const GRAPHIC_TEXT*>( seg.get() );
2981
2982 PCB_TEXT* txt = new PCB_TEXT( aBoard );
2983 txt->SetLayer( layer );
2984 txt->SetTextPos( wxPoint( src->start_x, src->start_y - src->height / 2 ) );
2985 txt->SetText( src->text );
2986 txt->SetItalic( src->ital );
2987 txt->SetTextThickness( src->thickness );
2988 txt->SetTextHeight( src->height );
2989 txt->SetTextWidth( src->width );
2990 txt->SetHorizJustify( src->orient );
2991 aBoard->Add( txt, ADD_MODE::APPEND );
2992 break;
2993 }
2994 default:
2995 return false;
2996 }
2997 }
2998 }
2999
3000 return true;
3001
3002}
void SetFilled(bool aFlag)
Definition: eda_shape.h:95
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: eda_shape.h:251
SHAPE_POLY_SET loadShapePolySet(const graphic_element &aLine)
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
@ Cmts_User
Definition: layer_ids.h:110

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::SetArcGeometry(), EDA_SHAPE::SetCenter(), EDA_SHAPE::SetEnd(), EDA_SHAPE::SetFilled(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetItalic(), BOARD_ITEM::SetLayer(), EDA_SHAPE::SetPolyShape(), EDA_SHAPE::SetStart(), PCB_SHAPE::SetStroke(), EDA_TEXT::SetText(), EDA_TEXT::SetTextHeight(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetTextWidth(), EDA_SHAPE::SetWidth(), SOLID, 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 2440 of file import_fabmaster.cpp.

2441{
2442 LSET layer_set;
2443
2445 layer_set |= LSET::AllTechMask() | LSET::UserMask();
2446
2447 for( auto& layer : layers )
2448 {
2449 checkpoint();
2450
2451 if( layer.second.layerid >= PCBNEW_LAYER_ID_START )
2452 layer_set.set( layer.second.layerid );
2453 }
2454
2455 aBoard->SetEnabledLayers( layer_set );
2456
2457 for( auto& layer : layers )
2458 {
2459 if( layer.second.conductive )
2460 {
2461 aBoard->SetLayerName( static_cast<PCB_LAYER_ID>( layer.second.layerid ),
2462 layer.second.name );
2463 }
2464 }
2465
2466 return true;
2467}
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:521
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition: board.cpp:416
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
static LSET UserMask()
Definition: lset.cpp:855
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:841
@ PCBNEW_LAYER_ID_START
Definition: layer_ids.h:63

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 2517 of file import_fabmaster.cpp.

2518{
2519 for( auto& net : netnames )
2520 {
2521 checkpoint();
2522
2523 NETINFO_ITEM *newnet = new NETINFO_ITEM( aBoard, net );
2524 aBoard->Add( newnet, ADD_MODE::APPEND );
2525 }
2526
2527 return true;
2528}
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 2769 of file import_fabmaster.cpp.

2770{
2771 PCB_LAYER_ID layer;
2772
2773 if( aLine->lclass == "BOARD GEOMETRY" )
2774 layer = Edge_Cuts;
2775 else if( aLine->lclass == "DRAWING FORMAT" )
2776 layer = Dwgs_User;
2777 else
2778 layer = Cmts_User;
2779
2780 STROKE_PARAMS defaultStroke( aBoard->GetDesignSettings().GetLineThickness( layer ) );
2781
2782 for( auto& seg : aLine->segment )
2783 {
2784 switch( seg->shape )
2785 {
2786
2787 case GR_SHAPE_LINE:
2788 {
2789 const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2790
2791 PCB_SHAPE* line = new PCB_SHAPE( aBoard, SHAPE_T::SEGMENT );
2792 line->SetLayer( layer );
2793 line->SetStart( wxPoint( src->start_x, src->start_y ) );
2794 line->SetEnd( wxPoint( src->end_x, src->end_y ) );
2795 line->SetStroke( STROKE_PARAMS( src->width, PLOT_DASH_TYPE::SOLID ) );
2796
2797 if( line->GetWidth() == 0 )
2798 line->SetStroke( defaultStroke );
2799
2800 aBoard->Add( line, ADD_MODE::APPEND );
2801 break;
2802 }
2803 case GR_SHAPE_CIRCLE:
2804 {
2805 const GRAPHIC_ARC* lsrc = static_cast<const GRAPHIC_ARC*>( seg.get() );
2806
2807 PCB_SHAPE* circle = new PCB_SHAPE( aBoard, SHAPE_T::CIRCLE );
2808
2809 circle->SetLayer( layer );
2810 circle->SetCenter( wxPoint( lsrc->center_x, lsrc->center_y ) );
2811 circle->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
2812 circle->SetWidth( lsrc->width );
2813
2814 if( lsrc->width == 0 )
2815 circle->SetWidth( aBoard->GetDesignSettings().GetLineThickness( circle->GetLayer() ) );
2816
2817 aBoard->Add( circle, ADD_MODE::APPEND );
2818 break;
2819 }
2820 case GR_SHAPE_ARC:
2821 {
2822 const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2823
2824 PCB_SHAPE* arc = new PCB_SHAPE( aBoard, SHAPE_T::ARC );
2825 arc->SetLayer( layer );
2826 arc->SetArcGeometry( src->result.GetP0(),
2827 src->result.GetArcMid(),
2828 src->result.GetP1() );
2829 arc->SetStroke( STROKE_PARAMS( src->width, PLOT_DASH_TYPE::SOLID ) );
2830
2831 if( arc->GetWidth() == 0 )
2832 arc->SetStroke( defaultStroke );
2833
2834 aBoard->Add( arc, ADD_MODE::APPEND );
2835 break;
2836 }
2837 case GR_SHAPE_RECTANGLE:
2838 {
2839 const GRAPHIC_RECTANGLE *src =
2840 static_cast<const GRAPHIC_RECTANGLE*>( seg.get() );
2841
2842 PCB_SHAPE* rect = new PCB_SHAPE( aBoard, SHAPE_T::RECT );
2843 rect->SetLayer( layer );
2844 rect->SetStart( wxPoint( src->start_x, src->start_y ) );
2845 rect->SetEnd( wxPoint( src->end_x, src->end_y ) );
2846 rect->SetStroke( defaultStroke );
2847
2848 aBoard->Add( rect, ADD_MODE::APPEND );
2849 break;
2850 }
2851 case GR_SHAPE_TEXT:
2852 {
2853 const GRAPHIC_TEXT *src = static_cast<const GRAPHIC_TEXT*>( seg.get() );
2854
2855 PCB_TEXT* txt = new PCB_TEXT( aBoard );
2856 txt->SetLayer( layer );
2857 txt->SetTextPos( wxPoint( src->start_x, src->start_y - src->height / 2 ) );
2858 txt->SetText( src->text );
2859 txt->SetItalic( src->ital );
2860 txt->SetTextThickness( src->thickness );
2861 txt->SetTextHeight( src->height );
2862 txt->SetTextWidth( src->width );
2863 txt->SetHorizJustify( src->orient );
2864
2865 aBoard->Add( txt, ADD_MODE::APPEND );
2866 break;
2867 }
2868 default:
2869 return false;
2870 }
2871 }
2872
2873 return true;
2874}
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
int GetWidth() const
Definition: eda_shape.h:107
@ Edge_Cuts
Definition: layer_ids.h:113

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_ITEM::GetLayer(), BOARD_DESIGN_SETTINGS::GetLineThickness(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), EDA_SHAPE::GetWidth(), 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, EDA_SHAPE::SetArcGeometry(), EDA_SHAPE::SetCenter(), EDA_SHAPE::SetEnd(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetItalic(), BOARD_ITEM::SetLayer(), EDA_SHAPE::SetStart(), PCB_SHAPE::SetStroke(), EDA_TEXT::SetText(), EDA_TEXT::SetTextHeight(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetTextWidth(), EDA_SHAPE::SetWidth(), SOLID, 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 2622 of file import_fabmaster.cpp.

2623{
2624 if( aLine->segment.size() < 3 )
2625 return false;
2626
2627 PCB_LAYER_ID layer = Cmts_User;
2628
2629 auto new_layer = getLayer( aLine->layer );
2630
2631 if( IsPcbLayer( new_layer ) )
2632 layer = new_layer;
2633
2634 SHAPE_POLY_SET poly_outline = loadShapePolySet( aLine->segment );
2635
2636 if( poly_outline.OutlineCount() < 1 || poly_outline.COutline( 0 ).PointCount() < 3 )
2637 return false;
2638
2639 STROKE_PARAMS defaultStroke( aBoard->GetDesignSettings().GetLineThickness( layer ) );
2640 PCB_SHAPE* new_poly = new PCB_SHAPE( aBoard );
2641
2642 new_poly->SetShape( SHAPE_T::POLY );
2643 new_poly->SetLayer( layer );
2644
2645 // Polygons on the silk layer are filled but other layers are not/fill doesn't make sense
2646 if( layer == F_SilkS || layer == B_SilkS )
2647 {
2648 new_poly->SetFilled( true );
2649 new_poly->SetStroke( STROKE_PARAMS( 0 ) );
2650 }
2651 else
2652 {
2653 new_poly->SetStroke( STROKE_PARAMS( ( *( aLine->segment.begin() ) )->width,
2655
2656 if( new_poly->GetWidth() == 0 )
2657 new_poly->SetStroke( defaultStroke );
2658 }
2659
2660 new_poly->SetPolyShape( poly_outline );
2661 aBoard->Add( new_poly, ADD_MODE::APPEND );
2662
2663 return true;
2664
2665}
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:110

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(), PCB_SHAPE::SetStroke(), and SOLID.

Referenced by loadZones().

◆ loadShapePolySet()

SHAPE_POLY_SET FABMASTER::loadShapePolySet ( const graphic_element aLine)
private

Definition at line 2586 of file import_fabmaster.cpp.

2587{
2588 SHAPE_POLY_SET poly_outline;
2589 int last_subseq = 0;
2590 int hole_idx = -1;
2591
2592 poly_outline.NewOutline();
2593
2594 for( const auto& seg : aElement )
2595 {
2596 if( seg->subseq > 0 || seg->subseq != last_subseq )
2597 hole_idx = poly_outline.AddHole( SHAPE_LINE_CHAIN{} );
2598
2599 if( seg->shape == GR_SHAPE_LINE )
2600 {
2601 const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2602
2603 if( poly_outline.VertexCount( 0, hole_idx ) == 0 )
2604 poly_outline.Append( src->start_x, src->start_y, 0, hole_idx );
2605
2606 poly_outline.Append( src->end_x, src->end_y, 0, hole_idx );
2607 }
2608 else if( seg->shape == GR_SHAPE_ARC )
2609 {
2610 const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2611 SHAPE_LINE_CHAIN& chain = poly_outline.Hole( 0, hole_idx );
2612
2613 chain.Append( src->result );
2614 }
2615 }
2616
2617 poly_outline.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
2618 return poly_outline;
2619}

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 2470 of file import_fabmaster.cpp.

2471{
2472 const NETNAMES_MAP& netinfo = aBoard->GetNetInfo().NetsByName();
2473 const auto& ds = aBoard->GetDesignSettings();
2474
2475 for( auto& via : vias )
2476 {
2477 checkpoint();
2478
2479 auto net_it = netinfo.find( via->net );
2480 auto padstack = pads.find( via->padstack );
2481
2482 PCB_VIA* new_via = new PCB_VIA( aBoard );
2483
2484 new_via->SetPosition( wxPoint( via->x, via->y ) );
2485
2486 if( net_it != netinfo.end() )
2487 new_via->SetNet( net_it->second );
2488
2489 if( padstack == pads.end() )
2490 {
2491 new_via->SetDrillDefault();
2492
2493 if( !ds.m_ViasDimensionsList.empty() )
2494 {
2495 new_via->SetWidth( ds.m_ViasDimensionsList[0].m_Diameter );
2496 new_via->SetDrill( ds.m_ViasDimensionsList[0].m_Drill );
2497 }
2498 else
2499 {
2500 new_via->SetDrillDefault();
2501 new_via->SetWidth( ds.m_ViasMinSize );
2502 }
2503 }
2504 else
2505 {
2506 new_via->SetDrill( padstack->second.drill_size_x );
2507 new_via->SetWidth( padstack->second.width );
2508 }
2509
2510 aBoard->Add( new_via, ADD_MODE::APPEND );
2511 }
2512
2513 return true;
2514}
void SetDrillDefault()
Function SetDrillDefault sets the drill value for vias to the default value UNDEFINED_DRILL_DIAMETER.
Definition: pcb_track.h:485
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: pcb_track.h:464
void SetPosition(const VECTOR2I &aPoint) override
Definition: pcb_track.h:402

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 2668 of file import_fabmaster.cpp.

2669{
2670 if( aLine->segment.size() < 3 )
2671 return false;
2672
2673 int last_subseq = 0;
2674 int hole_idx = -1;
2675 SHAPE_POLY_SET* zone_outline = nullptr;
2676 ZONE* zone = nullptr;
2677
2678 const NETNAMES_MAP& netinfo = aBoard->GetNetInfo().NetsByName();
2679 auto net_it = netinfo.find( aLine->netname );
2680 PCB_LAYER_ID layer = Cmts_User;
2681 auto new_layer = getLayer( aLine->layer );
2682
2683 if( IsPcbLayer( new_layer ) )
2684 layer = new_layer;
2685
2686 zone = new ZONE( aBoard );
2687 zone_outline = new SHAPE_POLY_SET;
2688
2689 if( net_it != netinfo.end() )
2690 zone->SetNet( net_it->second );
2691
2692 if( aLine->layer == "ALL" )
2693 zone->SetLayerSet( aBoard->GetLayerSet() & LSET::AllCuMask() );
2694 else
2695 zone->SetLayer( layer );
2696
2697 zone->SetIsRuleArea( false );
2698 zone->SetDoNotAllowTracks( false );
2699 zone->SetDoNotAllowVias( false );
2700 zone->SetDoNotAllowPads( false );
2701 zone->SetDoNotAllowFootprints( false );
2702 zone->SetDoNotAllowCopperPour( false );
2703
2704 if( aLine->lclass == "ROUTE KEEPOUT")
2705 {
2706 zone->SetIsRuleArea( true );
2707 zone->SetDoNotAllowTracks( true );
2708 }
2709 else if( aLine->lclass == "VIA KEEPOUT")
2710 {
2711 zone->SetIsRuleArea( true );
2712 zone->SetDoNotAllowVias( true );
2713 }
2714 else
2715 {
2716 zone->SetAssignedPriority( 50 );
2717 }
2718
2719 zone->SetLocalClearance( 0 );
2721
2722 zone_outline->NewOutline();
2723
2724
2725 for( const auto& seg : aLine->segment )
2726 {
2727 if( seg->subseq > 0 && seg->subseq != last_subseq )
2728 {
2730 if( aLine->lclass == "BOUNDARY" )
2731 break;
2732
2733 hole_idx = zone_outline->AddHole( SHAPE_LINE_CHAIN{} );
2734 last_subseq = seg->subseq;
2735 last_subseq = seg->subseq;
2736 }
2737
2738 if( seg->shape == GR_SHAPE_LINE )
2739 {
2740 const GRAPHIC_LINE* src = static_cast<const GRAPHIC_LINE*>( seg.get() );
2741
2742 if( zone_outline->VertexCount( 0, hole_idx ) == 0 )
2743 zone_outline->Append( src->start_x, src->start_y, 0, hole_idx );
2744
2745 zone_outline->Append( src->end_x, src->end_y, 0, hole_idx );
2746 }
2747 else if( seg->shape == GR_SHAPE_ARC )
2748 {
2749 const GRAPHIC_ARC* src = static_cast<const GRAPHIC_ARC*>( seg.get() );
2750 zone_outline->Hole( 0, hole_idx ).Append( src->result );
2751 }
2752 }
2753
2754 if( zone_outline->Outline( 0 ).PointCount() >= 3 )
2755 {
2756 zone->SetOutline( zone_outline );
2757 aBoard->Add( zone, ADD_MODE::APPEND );
2758 }
2759 else
2760 {
2761 delete( zone_outline );
2762 delete( zone );
2763 }
2764
2765 return true;
2766}
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:172
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
void SetDoNotAllowPads(bool aEnable)
Definition: zone.h:702
void SetDoNotAllowCopperPour(bool aEnable)
Definition: zone.h:699
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:251
void SetIsRuleArea(bool aEnable)
Definition: zone.h:698
void SetDoNotAllowTracks(bool aEnable)
Definition: zone.h:701
void SetDoNotAllowVias(bool aEnable)
Definition: zone.h:700
void SetLocalClearance(int aClearance)
Definition: zone.h:146
void SetLayerSet(LSET aLayerSet) override
Definition: zone.cpp:257
void SetDoNotAllowFootprints(bool aEnable)
Definition: zone.h:703
void SetAssignedPriority(unsigned aPriority)
Definition: zone.h:101
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition: zone.h:242
void SetOutline(SHAPE_POLY_SET *aOutline)
Definition: zone.h:308
@ FULL
pads are covered by copper

References BOARD::Add(), SHAPE_POLY_SET::AddHole(), LSET::AllCuMask(), SHAPE_LINE_CHAIN::Append(), SHAPE_POLY_SET::Append(), 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::SetAssignedPriority(), 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(), 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:313
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: board.cpp:795
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:269
bool loadZone(BOARD *aBoard, const std::unique_ptr< FABMASTER::TRACE > &aLine)
bool loadPolygon(BOARD *aBoard, const std::unique_ptr< FABMASTER::TRACE > &aLine)
unsigned GetNetCount() const
Definition: netinfo.h:347
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
const std::vector< VECTOR2I > & CPoints() const
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.

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 3005 of file import_fabmaster.cpp.

3006{
3007 std::sort( aBoard->Zones().begin(), aBoard->Zones().end(),
3008 [&]( const ZONE* a, const ZONE* b )
3009 {
3010 if( a->GetLayer() == b->GetLayer() )
3011 return a->GetBoundingBox().GetArea() > b->GetBoundingBox().GetArea();
3012
3013 return a->GetLayer() < b->GetLayer();
3014 } );
3015
3017 unsigned int priority = 0;
3018
3019 for( ZONE* zone : aBoard->Zones() )
3020 {
3022 if( zone->GetIsRuleArea() )
3023 continue;
3024
3025 if( zone->GetLayer() != layer )
3026 {
3027 layer = zone->GetLayer();
3028 priority = 0;
3029 }
3030
3031 zone->SetAssignedPriority( priority );
3032 priority += 10;
3033 }
3034
3035 return true;
3036}

References UNDEFINED_LAYER, and BOARD::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 {
1771 assignLayers();
1772 int retval = processPadStacks( i );
1773
1774 i += std::max( retval, 1 );
1775 break;
1776 }
1777
1779 {
1780 int retval = processLayers( i );
1781
1782 i += std::max( retval, 1 );
1783 break;
1784 }
1785
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 processFootprints(size_t aRow)
A!REFDES!COMP_CLASS!COMP_PART_NUMBER!COMP_HEIGHT!COMP_DEVICE_LABEL!COMP_INSERTION_CODE!...
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 processGeometry(size_t aRow)
A!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2!GRAPHIC_DATA_3!...
size_t processSimpleLayers(size_t aRow)
size_t processLayers(size_t aRow)
A!LAYER_SORT!LAYER_SUBCLASS!LAYER_ARTWORK!LAYER_USE!LAYER_CONDUCTOR!LAYER_DIELECTRIC_CONSTANT!...
size_t processPadStacks(size_t aRow)
A!PADNAME!RECNUMBER!LAYER!FIXFLAG!VIAFLAG!PADSHAPE1!PADWIDTH!PADHGHT! PADXOFF!PADYOFF!...
section_type detectType(size_t aOffset)
size_t processPadStackLayers(size_t aRow)
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 processNets(size_t aRow)
A!NET_NAME!REFDES!PIN_NUMBER!PIN_NAME!PIN_GROUND!PIN_POWER!
size_t processVias(size_t aRow)
A!VIA_X!VIA_Y!PAD_STACK_NAME!NET_NAME!TEST_POINT!
size_t processCustomPads(size_t aRow)
A!SUBCLASS!PAD_SHAPE_NAME!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!...

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 1037 of file import_fabmaster.cpp.

1038{
1039 GRAPHIC_ARC* new_arc = new GRAPHIC_ARC ;
1040
1041 new_arc->shape = GR_SHAPE_ARC;
1042 new_arc->start_x = KiROUND( readDouble( aData.graphic_data1 ) * aScale );
1043 new_arc->start_y = -KiROUND( readDouble( aData.graphic_data2 ) * aScale );
1044 new_arc->end_x = KiROUND( readDouble( aData.graphic_data3 ) * aScale );
1045 new_arc->end_y = -KiROUND( readDouble( aData.graphic_data4 ) * aScale );
1046 new_arc->center_x = KiROUND( readDouble( aData.graphic_data5 ) * aScale );
1047 new_arc->center_y = -KiROUND( readDouble( aData.graphic_data6 ) * aScale );
1048 new_arc->radius = KiROUND( readDouble( aData.graphic_data7 ) * aScale );
1049 new_arc->width = KiROUND( readDouble( aData.graphic_data8 ) * aScale );
1050
1051 new_arc->clockwise = ( aData.graphic_data9 != "COUNTERCLOCKWISE" );
1052
1053 EDA_ANGLE startangle( VECTOR2I( new_arc->start_x, new_arc->start_y )
1054 - VECTOR2I( new_arc->center_x, new_arc->center_y ) );
1055 EDA_ANGLE endangle( VECTOR2I( new_arc->end_x, new_arc->end_y )
1056 - VECTOR2I( new_arc->center_x, new_arc->center_y ) );
1058
1059 startangle.Normalize();
1060 endangle.Normalize();
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 < ANGLE_0 )
1070 angle += ANGLE_360;
1071 if( !new_arc->clockwise && angle > ANGLE_0 )
1072 angle -= ANGLE_360;
1073
1074 if( start == end )
1075 angle = -ANGLE_360;
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.
static constexpr EDA_ANGLE & ANGLE_360
Definition: eda_angle.h:418
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:412
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
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:80

References PNS::angle(), ANGLE_0, ANGLE_360, 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(), EDA_ANGLE::Normalize(), 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 875 of file import_fabmaster.cpp.

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

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}
SYMTYPE parseSymType(const std::string &aSymType)
COMPCLASS parseCompClass(const std::string &aCompClass)

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}

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_TEXT * processText(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_LINE * processLine(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 800 of file import_fabmaster.cpp.

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

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 1023 of file import_fabmaster.cpp.

1024{
1025 GRAPHIC_LINE* new_line = new GRAPHIC_LINE ;
1026
1027 new_line->shape = GR_SHAPE_LINE;
1028 new_line->start_x = KiROUND( readDouble( aData.graphic_data1 ) * aScale );
1029 new_line->start_y = -KiROUND( readDouble( aData.graphic_data2 ) * aScale );
1030 new_line->end_x = KiROUND( readDouble( aData.graphic_data3 ) * aScale );
1031 new_line->end_y = -KiROUND( readDouble( aData.graphic_data4 ) * aScale );
1032 new_line->width = KiROUND( readDouble( aData.graphic_data5 ) * aScale );
1033
1034 return new_line;
1035}

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}

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 330 of file import_fabmaster.cpp.

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

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 408 of file import_fabmaster.cpp.

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

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}

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}

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 258 of file import_fabmaster.cpp.

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

References _, EDA_IU_SCALE::IU_PER_MILS, EDA_IU_SCALE::IU_PER_MM, pcbIUScale, 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 656 of file import_fabmaster.cpp.

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

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_H_ALIGN_RIGHT;
1114 else if( aData.graphic_data5 == "CENTER" )
1115 new_text->orient = GR_TEXT_H_ALIGN_CENTER;
1116 else
1117 new_text->orient = GR_TEXT_H_ALIGN_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}
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:296
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT

References _, GR_SHAPE_TEXT, GR_TEXT_H_ALIGN_CENTER, GR_TEXT_H_ALIGN_LEFT, GR_TEXT_H_ALIGN_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}

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}

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 102 of file import_fabmaster.cpp.

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

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 80 of file import_fabmaster.cpp.

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

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

◆ readInt()

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

Definition at line 91 of file import_fabmaster.cpp.

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

Referenced by processPadStackLayers().

Member Data Documentation

◆ board_graphics

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

Definition at line 399 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 400 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 476 of file import_fabmaster.h.

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

◆ has_comps

bool FABMASTER::has_comps
private

Definition at line 96 of file import_fabmaster.h.

◆ has_graphic

bool FABMASTER::has_graphic
private

Definition at line 97 of file import_fabmaster.h.

◆ has_nets

bool FABMASTER::has_nets
private

Definition at line 98 of file import_fabmaster.h.

◆ has_pads

bool FABMASTER::has_pads
private

Definition at line 95 of file import_fabmaster.h.

◆ has_pins

bool FABMASTER::has_pins
private

Definition at line 99 of file import_fabmaster.h.

◆ layer_map

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

Definition at line 505 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 587 of file import_fabmaster.h.

Referenced by checkpoint(), and LoadBoard().

◆ m_filename

wxFileName FABMASTER::m_filename
private

Definition at line 75 of file import_fabmaster.h.

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

◆ m_lastProgressCount

unsigned FABMASTER::m_lastProgressCount
private

Definition at line 588 of file import_fabmaster.h.

Referenced by checkpoint().

◆ m_progressReporter

PROGRESS_REPORTER* FABMASTER::m_progressReporter
private

optional; may be nullptr

Definition at line 586 of file import_fabmaster.h.

Referenced by checkpoint(), and LoadBoard().

◆ m_totalCount

unsigned FABMASTER::m_totalCount
private

for progress reporting

Definition at line 589 of file import_fabmaster.h.

Referenced by checkpoint(), and LoadBoard().

◆ netnames

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

Definition at line 179 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 331 of file import_fabmaster.h.

Referenced by loadFootprints(), and processCustomPads().

◆ pads

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

Definition at line 137 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 178 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 503 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 441 of file import_fabmaster.h.

◆ refdes

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

Definition at line 443 of file import_fabmaster.h.

Referenced by loadFootprints(), and processTraces().

◆ rows

◆ symbols

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

Definition at line 374 of file import_fabmaster.h.

◆ traces

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

Definition at line 437 of file import_fabmaster.h.

Referenced by LoadBoard(), and processTraces().

◆ vias

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

Definition at line 414 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 439 of file import_fabmaster.h.

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


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